歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

busybox中ps命令源代碼分析

busybox/procps/ps.c
 busybox/libbb/procps.c

我們在串口終端通過ps命令查看系統當前正在運行的進程:

~ # ps
  PID USER      VSZ STAT COMMAND
    1 root      1080 S    init
    2 root        0 SW  [kthreadd]
    3 root        0 SW  [ksoftirqd/0]
    4 root        0 SW  [kworker/0:0]
    5 root        0 SW<  [kworker/0:0H]
    6 root        0 SW  [kworker/u2:0]
    7 root        0 SW  [rcu_preempt]
    8 root        0 SW  [rcu_bh]
    9 root        0 SW  [rcu_sched]
  10 root        0 SW<  [khelper]
  11 root        0 SW<  [writeback]
  12 root        0 SW<  [bioset]
  13 root        0 SW<  [kblockd]
  14 root        0 SW  [khubd]
  15 root        0 SW  [kworker/0:1]
  16 root        0 SW<  [cfg80211]
  17 root        0 SW<  [rpciod]
  18 root        0 SW  [kswapd0]
  19 root        0 SW<  [nfsiod]
  20 root        0 SW<  [cifsiod]
  21 root        0 SW<  [crypto]
  34 root        0 SW<  [dwc_otg]
  35 root        0 SW  [kworker/u2:1]
  54 root        0 SW<  [deferwq]
  55 root        0 SW  [kworker/0:2]
  56 root        0 SW<  [kworker/0:1H]
  233 root        0 SWN  [jffs2_gcd_mtd3]
  238 root      1080 S    syslogd
  240 root      1072 S    klogd
  241 root      1084 S    -/bin/sh
  242 root      1080 R    ps

720                puts("  PID USER      VSZ STAT COMMAND");

在busybox/procps/ps.c文件中ps_main函數,是與ps命令的第一行輸出對應的。

procps_status_t *p;

728        while ((p = procps_scan(p, psscan_flags)) != NULL) {
...
781                                const char *user = get_cached_username(p->uid);
782                                len = printf("%5u %-8.8s %s %s  ",
783                                        p->pid, user, buf6, p->state);
...
787                {
788                        int sz = terminal_width - len;
789                        char buf[sz + 1];
790                        read_cmdline(buf, sz, p->pid, p->comm);
791                        puts(buf);
792                }
}

先看p = procps_scan(p, psscan_flags),這個函數在busybox/libbb/procps.c中實現,每一個進程都會在/proc目錄下新建一個進程號對應的文件夾,這個函數通過讀取/proc目錄下所有進程號對應的文件夾,讀取文件夾下的stat, cmdline等文件,並將讀取的這些文件的信息保存在procps_status_t* sp這個結構體裡面並返回這個結構體。

再看get_cached_username函數,他根據procps_scan函數返回的procps_status_t* p指針中的p->uid來返回進程的用戶名,然後下一行的printf打印出了PID USER VSZ STAT這些字段的信息都是從指針p中獲取。

最後再看read_cmdline這個函數,他會讀取執行程序的命令並復制到buf中,讓下一行的puts打印出來。如果進程占用的VSZ為0,那麼他會在程序對應的命令的兩邊加上’[ ]’,比如dwc_otg,khubd這些進程由於VSZ都是0,所以在他們的兩邊都有’[ ]’。

最後要說一句,不管是內核創建的進程還是用戶空間創建的進程都會在/proc目錄下新建一個進程號對應的文件夾,所以都會通過ps顯示出來。

Copyright © Linux教程網 All Rights Reserved