天天看點

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中擷取。