Mercurial > hg > toybox
comparison toys/pending/ps.c @ 1710:2e59317546ed draft
Cleanup pass on ps.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 27 Feb 2015 12:17:30 -0600 |
parents | 0d33dd5f537e |
children | 783dc27590de |
comparison
equal
deleted
inserted
replaced
1709:8d6203ecfb88 | 1710:2e59317546ed |
---|---|
13 help | 13 help |
14 usage: ps [-o COL1,COL2=HEADER] [-T] | 14 usage: ps [-o COL1,COL2=HEADER] [-T] |
15 | 15 |
16 Show list of processes | 16 Show list of processes |
17 | 17 |
18 -o COL1,COL2=HEADER Select columns for display | 18 -a Show all processes with a tty |
19 -T Show threads | 19 -A Show all processes |
20 -o Select columns for display | |
21 -T Show threads | |
20 */ | 22 */ |
21 | 23 |
22 #define FOR_ps | 24 #define FOR_ps |
23 #include "toys.h" | 25 #include "toys.h" |
24 | 26 |
25 GLOBALS( | 27 GLOBALS( |
26 struct arg_list *llist_o; | 28 struct arg_list *llist_o; |
27 unsigned screen_width; | 29 unsigned screen_width; |
30 | |
31 void *o; | |
28 ) | 32 ) |
29 | 33 |
30 #define BUFF_SIZE 1024 | 34 #define BUFF_SIZE 1024 |
31 struct header_list { | 35 struct header_list { |
32 char *name; | |
33 char *header; | |
34 char *format; | |
35 int width; | |
36 int position; | |
37 struct header_list *next; | 36 struct header_list *next; |
37 char *name, *header, *format; | |
38 int width, position; | |
38 }; | 39 }; |
39 | |
40 struct header_list *o_list = NULL; //List of Header attributes. | |
41 | 40 |
42 /* | 41 /* |
43 * create list of header attributes taking care of -o (-o ooid=MOM..) | 42 * create list of header attributes taking care of -o (-o ooid=MOM..) |
44 * and width of attributes. | 43 * and width of attributes. |
45 */ | 44 */ |
46 static void list_add(struct header_list **list, struct header_list *data, char *c_data) | 45 static void list_add(struct header_list *data, char *c_data) |
47 { | 46 { |
48 struct header_list *temp = *list, *new = xzalloc(sizeof(struct header_list)); | 47 struct header_list *temp = TT.o, *new = xzalloc(sizeof(struct header_list)); |
49 | 48 |
50 new->name = data->name; | 49 new->name = data->name; |
51 if (c_data) new->header = c_data; | 50 if (c_data) new->header = c_data; |
52 else new->header = xstrdup(data->header); | 51 else new->header = xstrdup(data->header); |
53 if (c_data && (strlen(c_data) > data->width)) new->width = strlen(c_data); | 52 if (c_data && (strlen(c_data) > data->width)) new->width = strlen(c_data); |
56 new->position = data->position; | 55 new->position = data->position; |
57 | 56 |
58 if (temp) { | 57 if (temp) { |
59 while (temp->next) temp = temp->next; | 58 while (temp->next) temp = temp->next; |
60 temp->next = new; | 59 temp->next = new; |
61 } else *list = new; | 60 } else TT.o = new; |
62 } | 61 } |
63 | 62 |
64 //print the default header OR header with -o args | 63 //print the default header OR header with -o args |
65 static void print_header(struct header_list *hdr, int hdr_len) | 64 static void print_header(struct header_list *hdr, int hdr_len) |
66 { | 65 { |
68 char *ptr = NULL, *str, *temp; | 67 char *ptr = NULL, *str, *temp; |
69 struct arg_list *node = TT.llist_o; | 68 struct arg_list *node = TT.llist_o; |
70 | 69 |
71 // Default pid, user, time, comm | 70 // Default pid, user, time, comm |
72 if (!node) { | 71 if (!node) { |
73 list_add(&o_list, hdr+4, 0); | 72 list_add(hdr+4, 0); |
74 list_add(&o_list, hdr, 0); | 73 list_add(hdr, 0); |
75 list_add(&o_list, hdr+11, 0); | 74 list_add(hdr+11, 0); |
76 list_add(&o_list, hdr+3, 0); | 75 list_add(hdr+3, 0); |
77 } | 76 } |
78 | 77 |
79 while (node) { | 78 while (node) { |
80 char *s = str = xstrdup(node->arg); | 79 char *s = str = xstrdup(node->arg); |
81 | 80 |
89 // search from default header | 88 // search from default header |
90 if (!(strcmp(hdr[i].name, ptr))) { | 89 if (!(strcmp(hdr[i].name, ptr))) { |
91 //handle condition like ppid = M,OM | 90 //handle condition like ppid = M,OM |
92 if (str) ptr = xmprintf("%s,%s", temp, str); | 91 if (str) ptr = xmprintf("%s,%s", temp, str); |
93 else ptr = xmprintf("%s", temp); | 92 else ptr = xmprintf("%s", temp); |
94 list_add(&o_list, &hdr[i], ptr); | 93 list_add(hdr+i, ptr); |
95 break; | 94 break; |
96 } | 95 } |
97 i++; | 96 i++; |
98 } | 97 } |
99 if (!hdr[i].name) perror_exit("Invalid arg for -o option"); | 98 if (!hdr[i].name) perror_exit("Invalid arg for -o option"); |
100 break; | 99 break; |
101 } else { | 100 } else { |
102 while (hdr[i].name) { | 101 while (hdr[i].name) { |
103 if (!(strcmp(hdr[i].name, ptr))) { | 102 if (!(strcmp(hdr[i].name, ptr))) { |
104 list_add(&o_list, &hdr[i], 0); | 103 list_add(hdr+i, 0); |
105 break; | 104 break; |
106 } | 105 } |
107 i++; | 106 i++; |
108 } | 107 } |
109 if (!hdr[i].name) error_exit("bad -o"); | 108 if (!hdr[i].name) error_exit("bad -o"); |
113 } | 112 } |
114 free(s); | 113 free(s); |
115 node = node->next; | 114 node = node->next; |
116 } | 115 } |
117 | 116 |
118 for (hdr = o_list; hdr; hdr = hdr->next) | 117 for (hdr = TT.o; hdr; hdr = hdr->next) |
119 printf(hdr->format , hdr->width, hdr->header); | 118 printf(hdr->format , hdr->width, hdr->header); |
120 xputc('\n'); | 119 xputc('\n'); |
121 } | 120 } |
122 | 121 |
123 //get uid/gid for processes. | 122 //get uid/gid for processes. |
200 struct group *gr; | 199 struct group *gr; |
201 char *name, *user, *group, *ruser, *rgroup, *ptr; | 200 char *name, *user, *group, *ruser, *rgroup, *ptr; |
202 long rss; | 201 long rss; |
203 unsigned long stime, utime, start_time, vsz; | 202 unsigned long stime, utime, start_time, vsz; |
204 unsigned ppid, ruid, rgid, pgid; | 203 unsigned ppid, ruid, rgid, pgid; |
205 struct header_list *p = o_list; | 204 struct header_list *p = TT.o; |
206 | 205 |
207 sprintf(stat_buff, "/proc/%d", pid); | 206 sprintf(stat_buff, "/proc/%d", pid); |
208 if(stat(stat_buff, &stats)) return; | 207 if(stat(stat_buff, &stats)) return; |
209 | 208 |
210 if (tid) { | 209 if (tid) { |
379 { | 378 { |
380 DIR *dp; | 379 DIR *dp; |
381 struct dirent *entry; | 380 struct dirent *entry; |
382 int pid; | 381 int pid; |
383 struct header_list def_header[] = { | 382 struct header_list def_header[] = { |
384 {"user", "USER", "%-*s ", 8, 0, NULL}, | 383 {0, "user", "USER", "%-*s ", 8, 0}, |
385 {"group", "GROUP", "%-*s ", 8, 1, NULL}, | 384 {0, "group", "GROUP", "%-*s ", 8, 1}, |
386 {"comm", "COMMAND", "%-*s ",16, 2, NULL}, | 385 {0, "comm", "COMMAND", "%-*s ",16, 2}, |
387 {"args", "COMMAND", "%-*s ",30, 3, NULL}, | 386 {0, "args", "COMMAND", "%-*s ",30, 3}, |
388 {"pid", "PID", "%*s ", 5, 4, NULL}, | 387 {0, "pid", "PID", "%*s ", 5, 4}, |
389 {"ppid","PPID", "%*s ", 5, 5, NULL}, | 388 {0, "ppid","PPID", "%*s ", 5, 5}, |
390 {"pgid", "PGID", "%*s ", 5, 6, NULL}, | 389 {0, "pgid", "PGID", "%*s ", 5, 6}, |
391 {"etime","ELAPSED", "%*s ", 7, 7, NULL}, | 390 {0, "etime","ELAPSED", "%*s ", 7, 7}, |
392 {"nice", "NI", "%*s ", 5, 8, NULL}, | 391 {0, "nice", "NI", "%*s ", 5, 8}, |
393 {"rgroup","RGROUP", "%-*s ", 8, 9, NULL}, | 392 {0, "rgroup","RGROUP", "%-*s ", 8, 9}, |
394 {"ruser","RUSER", "%-*s ", 8, 10, NULL}, | 393 {0, "ruser","RUSER", "%-*s ", 8, 10}, |
395 {"time", "TIME", "%*s ", 6, 11, NULL}, | 394 {0, "time", "TIME", "%*s ", 6, 11}, |
396 {"tty", "TT", "%-*s ", 6, 12, NULL}, | 395 {0, "tty", "TT", "%-*s ", 6, 12}, |
397 {"vsz","VSZ", "%*s ", 7, 13, NULL}, | 396 {0, "vsz","VSZ", "%*s ", 7, 13}, |
398 {"stat", "STAT", "%-*s ", 4, 14, NULL}, | 397 {0, "stat", "STAT", "%-*s ", 4, 14}, |
399 {"rss", "RSS", "%*s ", 4, 15, NULL}, | 398 {0, "rss", "RSS", "%*s ", 4, 15}, |
400 {0,0,0,0,0,0} | 399 {0,0,0,0,0,0} |
401 }; | 400 }; |
402 | 401 |
403 TT.screen_width = 80; //default width | 402 TT.screen_width = 80; //default width |
404 terminal_size(&TT.screen_width, NULL); | 403 terminal_size(&TT.screen_width, NULL); |
407 if (!(dp = opendir("/proc"))) perror_exit("opendir"); | 406 if (!(dp = opendir("/proc"))) perror_exit("opendir"); |
408 while ((entry = readdir(dp))) { | 407 while ((entry = readdir(dp))) { |
409 if (isdigit(*entry->d_name)) { | 408 if (isdigit(*entry->d_name)) { |
410 pid = atoi(entry->d_name); | 409 pid = atoi(entry->d_name); |
411 do_ps_line(pid, 0); | 410 do_ps_line(pid, 0); |
412 if (toys.optflags & FLAG_T) | 411 if (toys.optflags & FLAG_T) do_ps_threads(pid); |
413 do_ps_threads(pid); | |
414 } | 412 } |
415 } | 413 } |
416 closedir(dp); | 414 closedir(dp); |
417 if (CFG_TOYBOX_FREE) { | 415 |
418 struct header_list *temp = o_list; | 416 while (CFG_TOYBOX_FREE) { |
419 while(temp) { | 417 struct header_list *temp = llist_pop(&TT.o); |
420 o_list = o_list->next; | 418 |
421 free(temp->header); | 419 if (!temp) break; |
422 free(temp); | 420 free(temp->header); |
423 temp = o_list; | 421 free(temp); |
424 } | 422 } |
425 } | 423 } |
426 } |