1 #include <linux/proc_fs.h> 2 #include <linux/sched.h> 3 #include <linux/namei.h> 4 5 /* 6 * /proc/self: 7 */ 8 static int proc_self_readlink(struct dentry *dentry, char __user *buffer, 9 int buflen) 10 { 11 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 12 pid_t tgid = task_tgid_nr_ns(current, ns); 13 char tmp[PROC_NUMBUF]; 14 if (!tgid) 15 return -ENOENT; 16 sprintf(tmp, "%d", tgid); 17 return vfs_readlink(dentry,buffer,buflen,tmp); 18 } 19 20 static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) 21 { 22 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 23 pid_t tgid = task_tgid_nr_ns(current, ns); 24 char *name = ERR_PTR(-ENOENT); 25 if (tgid) { 26 /* 11 for max length of signed int in decimal + NULL term */ 27 name = kmalloc(12, GFP_KERNEL); 28 if (!name) 29 name = ERR_PTR(-ENOMEM); 30 else 31 sprintf(name, "%d", tgid); 32 } 33 nd_set_link(nd, name); 34 return NULL; 35 } 36 37 static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, 38 void *cookie) 39 { 40 char *s = nd_get_link(nd); 41 if (!IS_ERR(s)) 42 kfree(s); 43 } 44 45 static const struct inode_operations proc_self_inode_operations = { 46 .readlink = proc_self_readlink, 47 .follow_link = proc_self_follow_link, 48 .put_link = proc_self_put_link, 49 }; 50 51 void __init proc_self_init(void) 52 { 53 struct proc_dir_entry *proc_self_symlink; 54 mode_t mode; 55 56 mode = S_IFLNK | S_IRWXUGO; 57 proc_self_symlink = proc_create("self", mode, NULL, NULL ); 58 proc_self_symlink->proc_iops = &proc_self_inode_operations; 59 } 60