123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- #include <linux/proc_fs.h>
- #include <linux/sched.h>
- #include <linux/namei.h>
- /*
- * /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;
- }
|