#include #include #include /* * /proc/self: */ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, int buflen) { struct pid_namespace *ns = dentry->d_sb->s_fs_info; pid_t tgid = task_tgid_nr_ns(current, ns); char tmp[PROC_NUMBUF]; if (!tgid) return -ENOENT; sprintf(tmp, "%d", tgid); return vfs_readlink(dentry,buffer,buflen,tmp); } static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) { struct pid_namespace *ns = dentry->d_sb->s_fs_info; pid_t tgid = task_tgid_nr_ns(current, ns); char *name = ERR_PTR(-ENOENT); if (tgid) { /* 11 for max length of signed int in decimal + NULL term */ name = kmalloc(12, GFP_KERNEL); if (!name) name = ERR_PTR(-ENOMEM); else sprintf(name, "%d", tgid); } nd_set_link(nd, name); return NULL; } static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) { char *s = nd_get_link(nd); if (!IS_ERR(s)) kfree(s); } static const struct inode_operations proc_self_inode_operations = { .readlink = proc_self_readlink, .follow_link = proc_self_follow_link, .put_link = proc_self_put_link, }; void __init proc_self_init(void) { struct proc_dir_entry *proc_self_symlink; mode_t mode; mode = S_IFLNK | S_IRWXUGO; proc_self_symlink = proc_create("self", mode, NULL, NULL ); proc_self_symlink->proc_iops = &proc_self_inode_operations; }