Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.8-rc7 59 lines 1.4 kB view raw
1#include <linux/proc_fs.h> 2#include <linux/sched.h> 3#include <linux/namei.h> 4 5/* 6 * /proc/self: 7 */ 8static 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 20static 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 37static 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 45static 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 51void __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}