• proc文件系统探索之proc根目录下的文件 一 cmdline 命令行的参数


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

    学习,具体实际操作的记录
     
     
    ========================================
    在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 ");
    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的结尾添 加字符结束符""
    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 ",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
     
    由此我们可以看到并非是每个参数之间没有间隔,而是以字符""作为间隔。所以如果我们在某一个程序中想读取进程的命令行参数,我们只需要知道该进程的pid,然后进入proc文件系统的该pid对应的目录下,编程读写读取cmdline文件就可以了。
  • 相关阅读:
    cocos2dx android java调用C++
    cocos2dx android c++调用java
    cocos2dx android collection
    cocos2dx学习之windows android环境搭建
    windows phone 8.0 与 windows phone7.1区别
    C#文件同步工具教程
    Web2.0时代,RSS你会用了吗?(技术实现总结)
    介绍一篇关于session的好文章,写的很详细(jspservlet 技术)
    利用HttpModuler实现WEB程序同一时间只让一个用户实例登陆
    css
  • 原文地址:https://www.cnblogs.com/jackyangrui/p/9849723.html
Copyright © 2020-2023  润新知