diff options
author | Rob Landley <rob@landley.net> | 2016-01-28 22:10:06 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2016-01-28 22:10:06 -0600 |
commit | 4a13ca98e18cea4acc8d605653d0ee8425e34f59 (patch) | |
tree | 42acd4e80890a5eab8df308c988f7bcf8dc87494 | |
parent | 852740618edc876ac7416e18c2f92f78707cd708 (diff) | |
download | toybox-4a13ca98e18cea4acc8d605653d0ee8425e34f59.tar.gz |
Add SIGWINCH support to top, and implement -o and -n in pgrep/pkill.
-rw-r--r-- | lib/interestingtimes.c | 15 | ||||
-rw-r--r-- | lib/net.c | 1 | ||||
-rw-r--r-- | toys/posix/ps.c | 94 |
3 files changed, 68 insertions, 42 deletions
diff --git a/lib/interestingtimes.c b/lib/interestingtimes.c index 93e2ec52..c4ea2c27 100644 --- a/lib/interestingtimes.c +++ b/lib/interestingtimes.c @@ -67,10 +67,14 @@ int scan_key_getsize(char *scratch, int miliwait, unsigned *xx, unsigned *yy) { int key; - while (512&(key = scan_key(scratch, miliwait))) { - if (key<0) break; - if (xx) *xx = (key>>10)&1023; - if (yy) *yy = (key>>20)&1023; + if (512&(key = scan_key(scratch, miliwait))) { + if (key>0) { + if (xx) *xx = (key>>10)&1023; + if (yy) *yy = (key>>20)&1023; + toys.signal = SIGWINCH; + + return -3; + } } return key; @@ -195,7 +199,8 @@ int scan_key(char *scratch, int miliwait) // Read 1 byte so we don't overshoot sequence match. (We can deviate // and fail to match, but match consumes entire buffer.) - if (1 != read(0, scratch+1+*scratch, 1)) return -1; + if (toys.signal || 1 != read(0, scratch+1+*scratch, 1)) + return toys.signal ? -3 : -1; ++*scratch; } @@ -49,6 +49,7 @@ int xpoll(struct pollfd *fds, int nfds, int timeout) for (;;) { if (0>(i = poll(fds, nfds, timeout))) { + if (toys.signal) return i; if (errno != EINTR && errno != ENOMEM) perror_exit("xpoll"); else if (timeout>0) timeout--; } else return i; diff --git a/toys/posix/ps.c b/toys/posix/ps.c index c95f73f5..f99a2168 100644 --- a/toys/posix/ps.c +++ b/toys/posix/ps.c @@ -41,13 +41,14 @@ * TODO: iotop: Window size change: respond immediately. Why not padding * at right edge? (Not adjusting to screen size at all? Header wraps?) * TODO: top: thread support and SMP + * TODO: pgrep -f only searches the amount of cmdline that fits in toybuf. USE_PS(NEWTOY(ps, "k(sort)*P(ppid)*aAdeflMno*O*p(pid)*s*t*u*U*g*G*wZ[!ol][+Ae]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE)) // stayroot because iotop needs root to read other process' proc/$$/io USE_TOP(NEWTOY(top, ">0m" "k*o*p*u*s#<1=9d#=3<1n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE)) USE_IOTOP(NEWTOY(iotop, ">0AaKO" "k*o*p*u*s#<1=7d#=3<1n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE)) -USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:", TOYFLAG_USR|TOYFLAG_BIN)) -USE_PKILL(NEWTOY(pkill, "Vu*U*t*s*P*g*G*fnovxl:", TOYFLAG_USR|TOYFLAG_BIN)) +USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN)) +USE_PKILL(NEWTOY(pkill, "Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN)) config PS bool "ps" @@ -232,8 +233,6 @@ GLOBALS( struct arg_list *p; struct arg_list *o; struct arg_list *k; - - long long milistart; } top; struct{ char *L; @@ -246,9 +245,9 @@ GLOBALS( struct arg_list *u; char *d; - void *regexes; + void *regexes, *snapshot; int signal; - pid_t self; + pid_t self, match; } pgrep; }; @@ -257,7 +256,7 @@ GLOBALS( unsigned width, height; dev_t tty; void *fields, *kfields; - long long ticks, bits; + long long ticks, bits, time; int kcount, forcek, sortpos; int (*match_process)(long long *slot); void (*show_process)(void *tb); @@ -542,6 +541,7 @@ static void show_ps(struct carveup *tb) else width -= printf("%*.*s", pad, len, out); if (!width) break; } + xputc(TT.time ? '\r' : '\n'); } // dirtree callback: read data about process to display, store, or discard it. @@ -756,7 +756,6 @@ static int get_ps(struct dirtree *new) TT.kcount++; if (TT.show_process) { TT.show_process(tb); - xputc('\n'); return 0; } @@ -1057,7 +1056,7 @@ void ps_main(void) // Calculate seen fields bit array, and if we aren't deferring printing // print headers now (for low memory/nommu systems). TT.bits = get_headers(TT.fields, toybuf, sizeof(toybuf)); - if (!(toys.optflags&FLAG_M)) printf("%s\n", toybuf); + if (!(toys.optflags&FLAG_M)) printf("%.*s\n", TT.width, toybuf); if (!(toys.optflags&(FLAG_k|FLAG_M))) TT.show_process = (void *)show_ps; TT.match_process = ps_match_process; dt = dirtree_read("/proc", get_ps); @@ -1078,7 +1077,7 @@ void ps_main(void) // Now that we've recalculated field widths, re-pad headers again get_headers(TT.fields, toybuf, sizeof(toybuf)); - printf("%s\n", toybuf); + printf("%.*s\n", TT.width, toybuf); } if (toys.optflags&FLAG_k) @@ -1086,7 +1085,6 @@ void ps_main(void) for (i = 0; i<TT.kcount; i++) { show_ps(tbsort[i]); free(tbsort[i]); - xputc('\n'); } if (CFG_TOYBOX_FREE) free(tbsort); } @@ -1177,6 +1175,7 @@ static void top_common( unsigned tock = 0; int i, lines, topoff = 0, done = 0; + toys.signal = SIGWINCH; TT.bits = get_headers(TT.fields, toybuf, sizeof(toybuf)); *scratch = 0; memset(plist, 0, sizeof(plist)); @@ -1244,8 +1243,14 @@ static void top_common( if (recalc) { qsort(mix.tb, mix.count, sizeof(struct carveup *), (void *)ksort); + if (!(toys.optflags&FLAG_b)) { + printf("\033[H\033[J"); + if (toys.signal) { + toys.signal = 0; + terminal_probesize(&TT.width, &TT.height); + } + } lines = TT.height; - if (!(toys.optflags&FLAG_b)) printf("\033[H\033[J"); } if (recalc && !(toys.optflags&FLAG_q)) { if (*toys.which->name == 't') { @@ -1332,15 +1337,12 @@ static void top_common( } *pos = 0; lines = header_line(lines, 1); - - if (!(toys.optflags&FLAG_b)) - terminal_probesize(&TT.width, &TT.height); } if (!recalc) printf("\033[%dH\033[J", 1+TT.height-lines); recalc = 1; for (i = 0; i<lines && i+topoff<mix.count; i++) { - if (i) xprintf("\r\n"); + if (i) xputc('\n'); show_ps(mix.tb[i+topoff]); } @@ -1399,11 +1401,14 @@ static void top_setup(char *defo, char *defk) { int len; + TT.time = militime(); TT.top.d *= 1000; if (toys.optflags&FLAG_b) TT.width = TT.height = 99999; else { xset_terminal(0, 1, 0); sigatexit(tty_sigreset); + xsignal(SIGWINCH, generic_signal); + printf("\033[?25l\033[0m"); } shared_main(); @@ -1440,7 +1445,7 @@ void top_main(void) static int iotop_filter(long long *oslot, long long *nslot, int milis) { if (!(toys.optflags&FLAG_a)) merge_deltas(oslot, nslot, milis); - else oslot[SLOT_upticks] = ((militime()-TT.top.milistart)*TT.ticks)/1000; + else oslot[SLOT_upticks] = ((militime()-TT.time)*TT.ticks)/1000; return !(toys.optflags&FLAG_o)||oslot[SLOT_iobytes+!(toys.optflags&FLAG_A)]; } @@ -1451,7 +1456,6 @@ void iotop_main(void) if (toys.optflags&FLAG_K) TT.forcek++; - TT.top.milistart = militime(); top_setup(s1 = xmprintf("PID,PR,USER,%sREAD,%sWRITE,SWAP,%sIO,COMM",d,d,d), s2 = xmprintf("-%sIO,-ETIME,-PID",d)); free(s1); @@ -1472,17 +1476,34 @@ struct regex_list { regex_t reg; }; -static void show_pgrep(struct carveup *tb) +static void do_pgk(struct carveup *tb) +{ + if (TT.pgrep.signal) { + if (kill(*tb->slot, TT.pgrep.signal)) { + char *s = num_to_sig(TT.pgrep.signal); + + if (!s) sprintf(s = toybuf, "%d", TT.pgrep.signal); + perror_msg("%s->%lld", s, *tb->slot); + } + } + if (!(toys.optflags&FLAG_c) && (!TT.pgrep.signal || TT.tty)) { + printf("%lld", *tb->slot); + if (toys.optflags&FLAG_l) + printf(" %s", tb->str+tb->offset[4]*!!(toys.optflags&FLAG_f)); + + printf("%s", TT.pgrep.d ? TT.pgrep.d : "\n"); + } +} + +static void match_pgrep(struct carveup *tb) { regmatch_t match; struct regex_list *reg; - char *name = tb->str; + char *name = tb->str+tb->offset[4]*!!(toys.optflags&FLAG_f);; // Never match ourselves. if (TT.pgrep.self == *tb->slot) return; - if (toys.optflags&FLAG_f) name += tb->offset[4]; - if (TT.pgrep.regexes) { for (reg = TT.pgrep.regexes; reg; reg = reg->next) { if (regexec(®->reg, name, 1, &match, 0)) continue; @@ -1495,20 +1516,15 @@ static void show_pgrep(struct carveup *tb) // Repurpose a field for -c count TT.sortpos++; - if (TT.pgrep.signal) { - if (kill(*tb->slot, TT.pgrep.signal)) { - char *s = num_to_sig(TT.pgrep.signal); - - if (!s) sprintf(s = toybuf, "%d", TT.pgrep.signal); - perror_msg("%s->%lld", s, *tb->slot); - } - } - if (!(toys.optflags&FLAG_c) && (!TT.pgrep.signal || TT.tty)) { - printf("%lld", *tb->slot); - if (toys.optflags&FLAG_l) printf(" %s", name); - - printf("%s", TT.pgrep.d ? TT.pgrep.d : "\n"); - } + if (toys.optflags&(FLAG_n|FLAG_o)) { + long long ll = tb->slot[SLOT_starttime]; + + if (toys.optflags&FLAG_o) ll *= -1; + if (TT.time && TT.time>ll) return; + TT.time = ll; + free(TT.pgrep.snapshot); + TT.pgrep.snapshot = xmemdup(toybuf, (name+strlen(name)+1)-toybuf); + } else do_pgk(tb); } static int pgrep_match_process(long long *slot) @@ -1549,10 +1565,14 @@ void pgrep_main(void) TT.pgrep.regexes = reg; } TT.match_process = pgrep_match_process; - TT.show_process = (void *)show_pgrep; + TT.show_process = (void *)match_pgrep; dirtree_read("/proc", get_ps); if (toys.optflags&FLAG_c) printf("%d\n", TT.sortpos); + if (TT.pgrep.snapshot) { + do_pgk(TT.pgrep.snapshot); + if (CFG_TOYBOX_FREE) free(TT.pgrep.snapshot); + } if (TT.pgrep.d) xputc('\n'); } |