self.c 1.4 KB

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