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 }