1. 程式人生 > >proc文件系統探索之proc根目錄下的文件 一 cmdline 命令行的參數

proc文件系統探索之proc根目錄下的文件 一 cmdline 命令行的參數

aps return getc 有用 travel latency make i++ 終端

轉載自ChinaUnix博客:http://blog.chinaunix.net/uid-22666248-id-3040364.html

本文是根據 kerneltravel proc文件系統探索系列http://www.kerneltravel.net/?p=281 學習,具體實際操作的記錄 proc文件系統探索之proc根目錄下的文件 一 cmdline ======================================== 在proc根目錄下,以數字命名的目錄表示當前一個運行的進程,目錄名為進程的pid。其內的目錄和文件給出了一些關於進程的信息。
  1. ywx@ywx:/proc/1500$ ls
  2. ls: cannot read symbolic link cwd: Permission denied
  3. ls: cannot read symbolic link root: Permission denied
  4. ls: cannot read symbolic link exe: Permission denied
  5. attr cpuset latency mountstats sched status
  6. auxv cwd limits net schedstat syscall
  7. cgroup environ loginuid oom_adj sessionid task

  8. clear_refs exe maps oom_score smaps wchan
  9. cmdline fd mem pagemap stack
  10. comm fdinfo mountinfo personality stat
  11. coredump_filter io mounts root statm
我們可以看到該目錄下有這麽些文件。其中attr、fd、fdinfo、task為目錄,cwd、root為指向目錄的鏈接,exe為指向文件的鏈接,其余為一般文件。對於一些文件或目錄的權限(查看或者修改的權限)是該進程的創建者才有,例如auxv等文件或目錄只有創建該進程的用戶才有查看或修改的權限,而其他一些文件則對所有用戶可讀權限。關於這些文件或目錄的權限,我們可以在內核中找到(fs/proc/base.c, tid_base_stuff數組)。
在2.6.35源碼fs/proc/base.c中;http://lxr.linux.no/linux+v2.6.35/fs/proc/base.c
  1. static const struct pid_entry tid_base_stuff[] = {
  2. 2907 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
  3. 2908 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
  4. 2909 REG("environ", S_IRUSR, proc_environ_operations),
  5. 2910 INF("auxv", S_IRUSR, proc_pid_auxv),
  6. 2911 ONE("status", S_IRUGO, proc_pid_status),
  7. 2912 ONE("personality", S_IRUSR, proc_pid_personality),
  8. 2913 INF("limits", S_IRUSR, proc_pid_limits),
  9. 2914#ifdef CONFIG_SCHED_DEBUG
  10. 2915 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
  11. 2916#endif
  12. 2917 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
  13. 2918#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
  14. 2919 INF("syscall", S_IRUSR, proc_pid_syscall),
  15. 2920#endif
  16. 2921 INF("cmdline", S_IRUGO, proc_pid_cmdline),
  17. 2922 ONE("stat", S_IRUGO, proc_tid_stat),
  18. 2923 ONE("statm", S_IRUGO, proc_pid_statm),
  19. 2924 REG("maps", S_IRUGO, proc_maps_operations),
  20. 2925#ifdef CONFIG_NUMA
  21. 2926 REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
  22. 2927#endif
  23. 2928 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
  24. 2929 LNK("cwd", proc_cwd_link),
  25. 2930 LNK("root", proc_root_link),
  26. 2931 LNK("exe", proc_exe_link),
  27. 2932 REG("mounts", S_IRUGO, proc_mounts_operations),
  28. 2933 REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
  29. 2934#ifdef CONFIG_PROC_PAGE_MONITOR
  30. 2935 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
  31. 2936 REG("smaps", S_IRUGO, proc_smaps_operations),
  32. 2937 REG("pagemap", S_IRUSR, proc_pagemap_operations),
  33. 2938#endif
  34. 2939#ifdef CONFIG_SECURITY
  35. 2940 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
  36. 2941#endif
  37. 2942#ifdef CONFIG_KALLSYMS
  38. 2943 INF("wchan", S_IRUGO, proc_pid_wchan),
  39. 2944#endif
  40. 2945#ifdef CONFIG_STACKTRACE
  41. 2946 ONE("stack", S_IRUSR, proc_pid_stack),
  42. 2947#endif
  43. 2948#ifdef CONFIG_SCHEDSTATS
  44. 2949 INF("schedstat", S_IRUGO, proc_pid_schedstat),
  45. 2950#endif
  46. 2951#ifdef CONFIG_LATENCYTOP
  47. 2952 REG("latency", S_IRUGO, proc_lstats_operations),
  48. 2953#endif
  49. 2954#ifdef CONFIG_PROC_PID_CPUSET
  50. 2955 REG("cpuset", S_IRUGO, proc_cpuset_operations),
  51. 2956#endif
  52. 2957#ifdef CONFIG_CGROUPS
  53. 2958 REG("cgroup", S_IRUGO, proc_cgroup_operations),
  54. 2959#endif
  55. 2960 INF("oom_score", S_IRUGO, proc_oom_score),
  56. 2961 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
  57. 2962#ifdef CONFIG_AUDITSYSCALL
  58. 2963 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
  59. 2964 REG("sessionid", S_IRUSR, proc_sessionid_operations),
  60. 2965#endif
  61. 2966#ifdef CONFIG_FAULT_INJECTION
  62. 2967 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
  63. 2968#endif
  64. 2969#ifdef CONFIG_TASK_IO_ACCOUNTING
  65. 2970 INF("io", S_IRUGO, proc_tid_io_accounting),
  66. 2971#endif
  67. 2972};
下面來詳細每一個文件和目錄的作用。 1.cmdline文件 該文件包含的是該進程的命令行參數,包括進程的啟動路徑(argv[0])。也就是說例如你在命令行上運行一個hello程序:
  1. 打開一個終端:
  2. ywx@ywx:~/desktop$ cat hello.c
  3. #include <stdio.h>
  4. #include <wait.h>
  5. int main()
  6. {
  7. int i=0;
  8. for(i=0;i<100;i++)
  9. {
  10. printf("hello world\n");
  11. sleep(2);
  12. }
  13. return 0;
  14. }
  15. ywx@ywx:~/desktop$ gcc hello.c -o hello
  16. ywx@ywx:~/desktop$ ./hello one two
  17. hello world
  18. hello world
打開另一個終端,查看當前進程的進程號:得知進程號為 ywx@ywx:~/Desktop$ ps -A | grep hello 2752 pts/0 00:00:00 hello 然後進入/proc/2752進程下面: ywx@ywx:~/Desktop$ cd /proc/2752 ywx@ywx:/proc/2752$ cat cmdline ./helloonetwoywx@ywx:/proc/2752$ 可以看到cmdline裏的內容為 “./helloonetwo”,正是命令行的參數。可能你會疑問為什麽參數沒有分開??那是因為cat欺騙了你。我們可以將cmdline復制到desktop下,然後用vim查看發現是這樣的:
  1. ./hello^@one^@two^@
也就是說,實際上每個參數之間是有東西隔開的,只不過cat將其忽略而已,而vim可以給你標識出東西,但vim本身不顯示罷了。我們可以通過編程讀取該文件。下面給出程序。 我們一個字符一個字符的讀取文件內容直到文件結束,在讀取每一個字符的時候,打印其字符和對應的數值。
  1. ywx@ywx:~/desktop$ cat readcmd.c
  2. #include <stdio.h>// std io fopen() snprintf() feof() perrof()
  3. int main(int argc,char *argv[])
  4. {
  5. FILE *fp;
  6. char path[80];
  7. unsigned char ch;
  8. snprintf(path,80,"/home/ywx/desktop/cmdline");//將cmdline中內容寫入path數組中,並在path的結尾添 加字符結束符"\0"
  9. if((fp=fopen(path,"r")) == NULL)
  10. {
  11. perror("fopen");
  12. return 0;
  13. }
  14. while(!feof(fp)) //判斷當前操作位置是否為文件的末尾,如果是,返回一個非零值
  15. {
  16. ch=fgetc(fp);//從stream流中讀取一個字符,操作位置向下移動一個
  17. printf("%c %d\n",ch,ch);
  18. }
  19. fclose(fp);
  20. return 0;
  21. }
ywx@ywx:~/Desktop$ gcc readcmd.c -o readcmd ywx@ywx:~/Desktop$ ./readcmd . 46 / 47 h 104 e 101 l 108 l 108 o 111 0 o 111 n 110 e 101 0 t 116 w 119 o 111 0 ? 255 由此我們可以看到並非是每個參數之間沒有間隔,而是以字符"\0"作為間隔。所以如果我們在某一個程序中想讀取進程的命令行參數,我們只需要知道該進程的pid,然後進入proc文件系統的該pid對應的目錄下,編程讀寫讀取cmdline文件就可以了。

proc文件系統探索之proc根目錄下的文件 一 cmdline 命令行的參數