代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
int pid;
int ppid;
struct node *child;
struct node *next;
char str[0];
} NODE;
static NODE *head = NULL;
static NODE *tail = NULL;
static int cmpWord(char *str, char *word){
while(word[0]){
if(str[0] != word[0]){
return str[0] - word[0];
}
str++;
word++;
}
if((str[0] <= ' ') || (str[0] > '~')){
return 0;
}
return str[0];
}
static int getIndexByWord(char *str, char *word){
int index = 0;
int flag = 0; //0=单词外,1=单词内。
while(str[0]){
if((str[0] > ' ') && (str[0] <= '~')){
if(flag == 0){
flag = 1;
if(cmpWord(str, word) == 0){
return index;
}
}
}else{
if(flag == 1){
flag = 0;
index++;
}
}
str++;
}
return -1;
}
static char *getWordByIndex(char *str, int index){
int num = 0;
int flag = 0; //0=单词外,1=单词内。
while(str[0]){
if((str[0] > ' ') && (str[0] <= '~')){
if(flag == 0){
flag = 1;
if(num == index){
return str;
}
}
}else{
if(flag == 1){
flag = 0;
num++;
}
}
str++;
}
return NULL;
}
static void putNode(NODE *node){
node->next = NULL;
if(head == NULL){
head = node;
}else{
tail->next = node;
}
tail = node;
}
static NODE *getNodeByPPID(int ppid){
if(head == NULL){
return NULL;
}
NODE *ret = head;
if(head->ppid == ppid){
head = head->next;
return ret;
}
NODE *last = ret;
ret = ret->next;
while(ret){
if(ret->ppid == ppid){
last->next = ret->next;
return ret;
}else{
last = ret;
ret = ret->next;
}
}
return NULL;
}
static NODE *makeTree(int pid){
NODE *headNode = NULL;
NODE *last;
NODE *node;
while((node = getNodeByPPID(pid))){
node->child = makeTree(node->pid);
node->next = NULL;
if(headNode){
last->next = node;
}else{
headNode = node;
}
last = node;
}
return headNode;
}
static void dumpTree(NODE *node, char *headStr){
char *buffer = alloca(strlen(headStr)+8);
NODE *freeNode;
while(node){
if(node->next){
printf("%s|-<%d> %s", headStr, node->pid, node->str);
}else{
printf("%s+-<%d> %s", headStr, node->pid, node->str);
}
if(node->child){
if(node->next){
sprintf(buffer, "%s| ", headStr);
}else{
sprintf(buffer, "%s ", headStr);
}
dumpTree(node->child, buffer);
}else{
if(node->next == NULL){
printf("%s\n", headStr);
}
}
freeNode = node;
node = node->next;
free(freeNode);
}
}
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]){
if(argc < 2){
printf("Usage: ps -ef | %s -v\n", argv[0]);
return -1;
}else{
if(strcmp(argv[1], "-v")){
printf("Usage: ps -ef | %s -v\n", argv[0]);
return -1;
}
}
char lineBuffer[4096];
if(fgets(lineBuffer, 4096, stdin) == NULL){
return -2;
}
int indexOfPID = getIndexByWord(lineBuffer, "PID");
int indexOfPPID = getIndexByWord(lineBuffer, "PPID");
int indexOfCMD = getIndexByWord(lineBuffer, "CMD");
if((indexOfPID < 0) || (indexOfPPID < 0) || (indexOfCMD < 0)){
return -3;
}
int length;
char *str;
NODE *node;
while(fgets(lineBuffer, 4096, stdin)){
str = getWordByIndex(lineBuffer, indexOfCMD);
length = strlen(str);
node = malloc(sizeof(NODE) + length + 8);
if(node){
node->pid = atoi(getWordByIndex(lineBuffer, indexOfPID));
node->ppid = atoi(getWordByIndex(lineBuffer, indexOfPPID));
node->child = NULL;
node->next = NULL;
memcpy(node->str, str, length+1);
putNode(node);
}
}
node = makeTree(0);
printf(" <0>\n");
dumpTree(node, " ");
return 0;
}
用法:
ps -ef | ./pstree -v
运行效果:
<0>
|-<1> /sbin/init splash
| |-<282> /lib/systemd/systemd-journald
| |-<297> /lib/systemd/systemd-udevd
| |-<684> /usr/sbin/haveged --Foreground --verbose=1 -w 1024
| |-<685> /lib/systemd/systemd-timesyncd
| |-<686> /usr/sbin/rsyslogd -n -iNONE
| |-<687> /usr/sbin/smartd -n
| |-<689> /usr/sbin/alsactl -E HOME=/run/alsa -s -n 19 -c rdaemon
| |-<690> /usr/sbin/cron -f
| |-<691> /usr/sbin/deepin-elf-verify
| |-<692> /usr/bin/deepin-user-experience-daemon
| |-<694> /opt/todesk/bin/todeskd -f /opt/todesk/config/todeskd.conf
| |-<696> /usr/sbin/uos-resource-manager
| |-<698> /usr/lib/udisks2/udisksd
| |-<700> /usr/lib/accountsservice/accounts-daemon
| |-<701> /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
| |-<702> /sbin/wpa_supplicant -u -s -O /run/wpa_supplicant
| |-<703> /usr/sbin/NetworkManager --no-daemon
| |-<704> /usr/sbin/ModemManager --filter-policy=strict
| |-<707> /lib/systemd/systemd-logind
| |-<762> /usr/lib/policykit-1/polkitd --no-debug
| |-<787> /usr/bin/deepin-devicemanager-server
| |-<1104> /usr/sbin/lightdm
| | |-<10979> /usr/lib/xorg/Xorg -background none :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt1 -novtswitch
| | +-<11073> lightdm --session-child 12 19 20
| | +-<11257> /usr/bin/startdde
| | |-<11466> /bin/sh /usr/bin/kwin_no_scale
| | | +-<11476> kwin_x11 -platform dde-kwin-xcb:appFilePath=/usr/bin/kwin_no_scale
| | |
| | |-<11467> /usr/lib/deepin-daemon/dde-session-daemon
| | |-<11473> /usr/bin/dde-desktop
| | |-<11525> /usr/bin/dde-dock -r
| | |-<11728> /usr/lib/polkit-1-dde/dde-polkit-agent
| | |-<11879> /usr/bin/dde-clipboard
| | |-<11883> /usr/lib/deepin-daemon/dde-calendar-service
| | |-<11884> /usr/bin/DeepinVoiceWakeuper
| | |-<11889> /usr/lib/deepin-deepinid-daemon/deepin-deepinid-daemon
| | |-<11893> /usr/lib/geoclue-2.0/demos/agent
| | |-<11904> /usr/bin/deepin-defender-daemonservice
| | |-<11905> dde-printer-helper
| | |-<11908> /usr/lib/at-spi2-core/at-spi-bus-launcher --launch-immediately
| | | +-<11929> /usr/bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 3
| | |
| | |-<11911> DeepinAIAssistant
| | +-<12197> deepin-terminal
| | +-<12205> /bin/bash
| |
| |-<1326> /usr/lib/deepin-daemon/dde-system-daemon
| | +-<1398> rfkill event
| |
| |-<1342> /usr/lib/deepin-deepinid-daemon/deepin-sync-helper
| |-<1362> /usr/lib/deepin-daemon/backlight_helper
| |-<1412> /bin/sh /usr/bin/deepin-anything-tool-ionice --dbus
| | +-<1413> deepin-anything-tool --dbus
| |
| |-<1414> /usr/bin/dbus-udcp
| |-<1432> /usr/bin/deepin-anything-monitor
| |-<1433> /usr/lib/upower/upowerd
| |-<1593> /usr/lib/deepin-authenticate/deepin-authentication
| |-<1612> /usr/sbin/nmbd --foreground --no-process-group
| |-<1614> /usr/lib/deepin-daemon/uos-license-agent
| |-<1615> /usr/bin/udcpg
| |-<1784> /lib/systemd/systemd --user
| | |-<1785> (sd-pam)
| | |-<1840> /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
| | |-<1943> /usr/lib/gvfs/gvfsd
| | |-<1948> /usr/lib/gvfs/gvfsd-fuse /run/user/1000/gvfs -f -o big_writes
| | |-<2059> /usr/lib/dconf/dconf-service
| | |-<2196> /usr/lib/gvfs/gvfs-udisks2-volume-monitor
| | |-<2200> /usr/lib/gvfs/gvfs-mtp-volume-monitor
| | |-<2276> /usr/lib/gvfs/gvfs-gphoto2-volume-monitor
| | |-<2312> /usr/lib/gvfs/gvfs-goa-volume-monitor
| | |-<2337> /usr/lib/gvfs/gvfs-afc-volume-monitor
| | |-<11391> /usr/lib/deepin-daemon/dde-osd
| | |-<11508> /usr/bin/deepin-wm-dbus
| | |-<11545> /usr/bin/kglobalaccel5
| | |-<11677> /usr/lib/x86_64-linux-gnu/bamf/bamfdaemon
| | |-<11768> /usr/bin/pulseaudio --daemonize=no
| | |-<11769> /usr/lib/deepin-turbo/booster-dtkwidget --systemd
| | | +-<11774> booster [dtkwidget]
| | |
| | |-<11954> /usr/bin/deepin-defender-datainterface
| | |-<12173> /usr/lib/bluetooth/obexd
| | +-<12232> /usr/bin/uos-activator
| |
| |-<2352> /usr/sbin/smbd --foreground --no-process-group
| | |-<2463> /usr/sbin/smbd --foreground --no-process-group
| | |-<2464> /usr/sbin/smbd --foreground --no-process-group
| | +-<2476> /usr/sbin/smbd --foreground --no-process-group
| |
| |-<2370> /usr/libexec/lastore-daemon/lastore-daemon
| |-<2393> /usr/sbin/ipwatchd -c /etc/ipwatchd.conf
| |-<2597> /bin/sh /usr/lib/bluetooth/bluetoothd.sh
| | +-<2598> /usr/lib/bluetooth/bluetoothd
| |
| |-<2609> /usr/bin/dde-file-manager-daemon
| |-<2721> /usr/bin/deepin-MonitorNetFlow
| |-<2805> /usr/bin/sh -c cd /usr/bin;/usr/bin/deepin-defender-antiav
| | +-<2813> /usr/bin/deepin-defender-antiav
| |
| |-<3903> /usr/sbin/cupsd -l
| |-<4760> /usr/sbin/sshd -D
| | +-<9826> sshd: test [priv]
| | +-<9829> sshd: test@pts/1
| | +-<9830> -bash
| | |-<13489> ps -ef
| | +-<13490> ./a.out -v
| |
| |-<10498> /usr/lib/deepin-daemon/greeter-display-daemon
| |-<11254> /usr/bin/gnome-keyring-daemon --daemonize --login
| |-<11368> /usr/bin/fcitx-implugin-service
| |-<11370> /usr/bin/fcitx -d
| | +-<11600> sh -c /opt/apps/org.deepin.chineseime/files/bin/chinime-qim
| | +-<11601> /opt/apps/org.deepin.chineseime/files/bin/chinime-qim
| |
| |-<11382> /usr/bin/dbus-daemon --syslog --fork --print-pid 5 --print-address 7 --config-file /usr/share/fcitx/dbus/daemon.conf
| |-<11386> /usr/bin/fcitx-dbus-watcher unix:abstract=/tmp/dbus-0XBHAVE18o,guid=250d6f9b792522fe2640cda161c97cdd 11382
| |-<11931> /usr/lib/at-spi2-core/at-spi2-registryd --use-gnome-session
| +-<11979> /usr/bin/dde-clipboardloader
|
+-<2> [kthreadd]
|-<3> [rcu_gp]
|-<4> [rcu_par_gp]
|-<6> [kworker/0:0H-kblockd]
|-<8> [mm_percpu_wq]
|-<9> [ksoftirqd/0]
|-<10> [rcu_sched]
|-<11> [rcu_bh]
|-<12> [migration/0]
|-<14> [cpuhp/0]
|-<15> [cpuhp/1]
|-<16> [migration/1]
|-<17> [ksoftirqd/1]
|-<19> [kworker/1:0H-events_highpri]
|-<20> [kdevtmpfs]
|-<21> [netns]
|-<22> [kauditd]
|-<23> [khungtaskd]
|-<24> [oom_reaper]
|-<25> [writeback]
|-<26> [kcompactd0]
|-<27> [ksmd]
|-<28> [khugepaged]
|-<29> [crypto]
|-<30> [kintegrityd]
|-<31> [kblockd]
|-<32> [ata_sff]
|-<33> [edac-poller]
|-<34> [devfreq_wq]
|-<35> [watchdogd]
|-<37> [kswapd0]
|-<55> [kthrotld]
|-<56> [nvme-wq]
|-<57> [nvme-reset-wq]
|-<58> [nvme-delete-wq]
|-<59> [scsi_eh_0]
|-<60> [scsi_tmf_0]
|-<61> [scsi_eh_1]
|-<62> [scsi_tmf_1]
|-<63> [scsi_eh_2]
|-<64> [scsi_tmf_2]
|-<65> [scsi_eh_3]
|-<66> [scsi_tmf_3]
|-<71> [ipv6_addrconf]
|-<81> [kstrp]
|-<83> [kworker/0:1H-events_highpri]
|-<153> [kworker/u5:0-i915_flip]
|-<185> [kworker/1:1H-events_highpri]
|-<239> [jbd2/sda5-8]
|-<240> [ext4-rsv-conver]
|-<293> [lightcherry]
|-<294> [lightorange]
|-<344> [irq/126-mei_me]
|-<408> [kworker/0:3-cgroup_pidlist_destroy]
|-<611> [jbd2/sda1-8]
|-<612> [ext4-rsv-conver]
|-<621> [jbd2/sda3-8]
|-<622> [ext4-rsv-conver]
|-<624> [jbd2/sda7-8]
|-<625> [ext4-rsv-conver]
|-<1330> [cfg80211]
|-<2621> [kworker/u5:1]
|-<10295> [kworker/u4:0-events_unbound]
|-<12066> [kworker/1:2-mm_percpu_wq]
|-<13318> [kworker/1:0-cgroup_destroy]
|-<13390> [kworker/u4:1-events_unbound]
+-<13431> [kworker/0:1-cgroup_destroy]