From bfee4b2325efd7c21c2e5ec02193ec2e97cca0ff Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 21 Oct 2015 13:00:59 -0500 Subject: ps: implement -t, remove leading 0 from ETIME days, implement -o GROUP,GID,PCPU --- toys/pending/ps.c | 92 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 18 deletions(-) diff --git a/toys/pending/ps.c b/toys/pending/ps.c index 37816571..8f52cd39 100644 --- a/toys/pending/ps.c +++ b/toys/pending/ps.c @@ -23,11 +23,10 @@ * leaving 9 chars for cmd, so we're using that as our -l output. * * - * TODO: ps aux + * TODO: ps aux (att & bsd style "ps -ax" vs "ps ax" behavior difference) * TODO: finalize F - * TODO: -tuUgG + * TODO: -uUgG * TODO: -o maj_flt,min_flt,stat(unit || j == 1+(i==16))) s = out; if (s) { - s += sprintf(s, "%02ld", (long)(seconds/unit)); + s += sprintf(s, j ? "%02ld": "%2ld", (long)(seconds/unit)); if ((*s = "-::"[j])) s++; } seconds %= unit; unit /= j ? 60 : 24; } -//17 "GROUP", "%CPU", "PGID", "RGROUP", -//21 "RUSER", -, "VSZ" - // COMMAND CMD // Command line limited to 2k displayable. We could dynamically malloc, but // it'd almost never get used, querying length of a proc file is awkward, @@ -309,6 +310,18 @@ static int do_ps(struct dirtree *new) } if (len<1) sprintf(out, "[%.*s]", nlen, name); + // GROUP GID + } else if (i == 17 || i == 26) { + sprintf(out, "%ld", (long)new->st.st_gid); + if (i == 17) { + struct group *gr = getgrgid(new->st.st_gid); + if (gr) out = gr->gr_name; + } + // %CPU + } else if (i == 18) { + ll = (get_uptime()*sysconf(_SC_CLK_TCK)-slot[19]); + len = ((slot[11]+slot[12])*1000)/ll; + sprintf(out, "%d.%d", len/10, len%10); } // Output the field, appropriately padded @@ -338,11 +351,12 @@ void ps_main(void) *typos[] = { "F", "S", "UID", "PID", "PPID", "C", "PRI", "NI", "ADDR", "SZ", "WCHAN", "STIME", "TTY", "TIME", "CMD", "COMMAND", "ELAPSED", "GROUP", - "%CPU", "PGID", "RGROUP", "RUSER", "USER", "VSZ", "RSS" + "%CPU", "PGID", "RGROUP", "RUSER", "USER", "VSZ", "RSS", "UNAME", + "GID", "STAT" }; int i, fd = -1; - TT.width = 99999; // glibc produces no output for printf("%.*s", INT_MAX, x); + TT.width = 99999; if (!FLAG_w) terminal_size(&TT.width, 0); // find controlling tty, falling back to /dev/tty if none @@ -375,6 +389,44 @@ void ps_main(void) } } + // tty list via -t + if (toys.optflags&FLAG_t) { + struct arg_list *tl; + char *next, *arg, *ss; + int len, pts; + + for (tl = TT.t; tl; tl = tl->next) { + arg = tl->arg; + while ((next = comma_iterate(&arg, &len))) { + if (!(15&TT.ttylen)) + TT.ttys = xrealloc(TT.ttys, sizeof(long)*(TT.ttylen+16)); + + // -t pts = 12,pts/12, tty = /dev/tty2,tty2,S0 + pts = 0; + if (isdigit(*next)) pts++; + else { + if (strstart(&next, strcpy(toybuf, "/dev/"))) len -= 5; + if (strstart(&next, "pts/")) { + len -= 4; + pts++; + } else if (strstart(&next, "tty")) len -= 3; + } + if (len < 256 && (!(ss = strchr(next, '/')) || ss-next>len)) + { + struct stat st; + + ss = toybuf + sprintf(toybuf, "/dev/%s", pts ? "pts/" : "tty"); + memcpy(ss, next, len); + ss[len] = 0; + xstat(toybuf, &st); + TT.ttys[TT.ttylen++] = st.st_rdev; + continue; + } + perror_exit("-t '%s'@%ld", tl->arg, 1+next-tl->arg); + } + } + } + // Manual field selection via -o if (toys.optflags&FLAG_o) { struct arg_list *ol; @@ -421,9 +473,9 @@ void ps_main(void) for (j = 0; j < 2; j++) { if (!j) s = typos[i]; // posix requires alternate names for some fields - else if (-1 == (k = stridx((char []){7, 14, 15, 16, 0}, i))) + else if (-1 == (k = stridx((char []){7, 14, 15, 16, 18, 0}, i))) continue; - else s = ((char *[]){"NICE", "ARGS", "COMM", "ETIME"})[k]; + else s = ((char *[]){"NICE", "ARGS", "COMM", "ETIME", "PCPU"})[k]; if (!strncasecmp(type, s, end-type) && strlen(s)==end-type) break; } @@ -445,7 +497,6 @@ void ps_main(void) // order of fields[] matches posix STDOUT section, so add enabled XSI // defaults according to bitmask - for (i=0; def>>i; i++) { if (!((def>>i)&1)) continue; @@ -462,8 +513,7 @@ void ps_main(void) // time and pcpu count as numbers, tty does not) for (field = TT.fields; field; field = field->next) { - // right justify F, UID, PID, PPID, PRI, NI, ADDR SZ, TIME, ELAPSED, %CPU - // STIME + // right justify F UID PID PPID PRI NI ADDR SZ TIME ELAPSED %CPU STIME if (!((1<which)&0x527dd)) field->len *= -1; printf(" %*s" + (field == TT.fields), field->len, field->title); @@ -474,4 +524,10 @@ void ps_main(void) xputc('\n'); dirtree_read("/proc", do_ps); + + if (CFG_TOYBOX_FREE) { + free(TT.pids); + free(TT.ttys); + llist_traverse(TT.fields, free); + } } -- cgit v1.2.3