diff --git a/NEWS b/NEWS index 228b7406..65093311 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,9 @@ procps-3.2.6 --> procps-3.2.7 + top: document H option -- thanks Tony Ernst top: terabytes -- thanks Tony Ernst ps: SCHED_BATCH is B +ps: fix s format (signals) output with thread display procps-3.2.5 --> procps-3.2.6 diff --git a/pgrep.c b/pgrep.c index 28974242..af1e90b7 100644 --- a/pgrep.c +++ b/pgrep.c @@ -83,7 +83,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *)) int i = 1, size = 32; union el *list; - list = malloc (size * sizeof (union el)); + list = malloc (size * sizeof *list); if (list == NULL) exit (3); @@ -97,7 +97,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *)) exit (2); if (i == size) { size *= 2; - list = realloc (list, size * sizeof (union el)); + list = realloc (list, size * sizeof *list); if (list == NULL) exit (3); } @@ -112,7 +112,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *)) } else { list[0].num = i - 1; } - return (list); + return list; } /* strict_atol returns a Boolean: TRUE if the input string contains a @@ -138,7 +138,7 @@ strict_atol (const char *restrict str, long *restrict value) res += *str - '0'; } *value = sign * res; - return (1); + return 1; } static int @@ -153,10 +153,10 @@ conv_uid (const char *restrict name, union el *restrict e) if (pwd == NULL) { fprintf (stderr, "%s: invalid user name: %s\n", progname, name); - return (0); + return 0; } e->num = pwd->pw_uid; - return (1); + return 1; } @@ -166,16 +166,16 @@ conv_gid (const char *restrict name, union el *restrict e) struct group *grp; if (strict_atol (name, &e->num)) - return (1); + return 1; grp = getgrnam (name); if (grp == NULL) { fprintf (stderr, "%s: invalid group name: %s\n", progname, name); - return (0); + return 0; } e->num = grp->gr_gid; - return (1); + return 1; } @@ -185,11 +185,11 @@ conv_pgrp (const char *restrict name, union el *restrict e) if (! strict_atol (name, &e->num)) { fprintf (stderr, "%s: invalid process group: %s\n", progname, name); - return (0); + return 0; } if (e->num == 0) e->num = getpgrp (); - return (1); + return 1; } @@ -199,11 +199,11 @@ conv_sid (const char *restrict name, union el *restrict e) if (! strict_atol (name, &e->num)) { fprintf (stderr, "%s: invalid session id: %s\n", progname, name); - return (0); + return 0; } if (e->num == 0) e->num = getsid (0); - return (1); + return 1; } @@ -213,9 +213,9 @@ conv_num (const char *restrict name, union el *restrict e) if (! strict_atol (name, &e->num)) { fprintf (stderr, "%s: not a number: %s\n", progname, name); - return (0); + return 0; } - return (1); + return 1; } @@ -223,7 +223,7 @@ static int conv_str (const char *restrict name, union el *restrict e) { e->str = strdup (name); - return (1); + return 1; } @@ -240,7 +240,7 @@ match_numlist (long value, const union el *restrict list) found = 1; } } - return (found); + return found; } static int @@ -256,7 +256,7 @@ match_strlist (const char *restrict value, const union el *restrict list) found = 1; } } - return (found); + return found; } static void @@ -310,7 +310,7 @@ do_openproc (void) } else { ptp = openproc (flags); } - return (ptp); + return ptp; } static regex_t * @@ -346,7 +346,7 @@ do_regcomp (void) } static union el * -select_procs (void) +select_procs (int *num) { PROCTAB *ptp; proc_t task; @@ -359,7 +359,7 @@ select_procs (void) union el *list; char cmd[4096]; - list = malloc (size * sizeof (union el)); + list = malloc (size * sizeof *list); if (list == NULL) exit (3); @@ -450,14 +450,13 @@ select_procs (void) if (opt_long) { char buff[5096]; // FIXME sprintf (buff, "%d %s", task.XXXID, cmd); - list[++matches].str = strdup (buff); + list[matches++].str = strdup (buff); } else { - list[++matches].num = task.XXXID; + list[matches++].num = task.XXXID; } if (matches == size) { size *= 2; - list = realloc (list, - size * sizeof (union el)); + list = realloc(list, size * sizeof *list); if (list == NULL) exit (3); } @@ -467,8 +466,8 @@ select_procs (void) } closeproc (ptp); - list[0].num = matches; - return (list); + *num = matches; + return list; } @@ -607,13 +606,14 @@ int main (int argc, char **argv) { union el *procs; + int num; parse_opts (argc, argv); - procs = select_procs (); + procs = select_procs (&num); if (i_am_pkill) { int i; - for (i = 1; i <= procs[0].num; i++) { + for (i = 0; i < num; i++) { if (kill (procs[i].num, opt_signal) != -1) continue; if (errno==ESRCH) continue; // gone now, which is OK fprintf (stderr, "pkill: %ld - %s\n", @@ -625,5 +625,5 @@ main (int argc, char **argv) else output_numlist (procs); } - return ((procs[0].num) == 0 ? 1 : 0); + return !num; } diff --git a/proc/readproc.c b/proc/readproc.c index e3245c1b..4fad11db 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -37,6 +37,17 @@ extern void __cyg_profile_func_enter(void*,void*); #define LEAVE(x) #endif +// convert hex string to unsigned long long +static unsigned long long unhex(const char *restrict cp){ + unsigned long long ull = 0; + for(;;){ + char c = *cp++; + if(unlikely(c<0x30)) break; + ull = (ull<<4) | (c - (c>0x57) ? 0x57 : 0x30) ; + } + return ull; +} + static int task_dir_missing; /////////////////////////////////////////////////////////////////////////// @@ -71,7 +82,6 @@ typedef struct status_table_struct { // must be padded out to 64 entries, maybe 128 in the future. static void status2proc(char *S, proc_t *restrict P, int is_proc){ - char ShdPnd[16] = ""; long Threads = 0; long Tgid = 0; long Pid = 0; @@ -147,6 +157,7 @@ ENTER(0x220); P->vm_exe = 0; P->vm_lib = 0; P->nlwp = 0; + P->signal[0] = '\0'; // so we can detect it as missing for very old kernels goto base; @@ -195,9 +206,10 @@ ENTER(0x220); S--; // put back the '\n' or '\0' continue; } +#ifdef SIGNAL_STRING case_ShdPnd: - memcpy(ShdPnd, S, 16); - // we know it to be 16 char, so no '\0' needed + memcpy(P->signal, S, 16); + P->signal[16] = '\0'; continue; case_SigBlk: memcpy(P->blocked, S, 16); @@ -212,9 +224,26 @@ ENTER(0x220); P->sigignore[16] = '\0'; continue; case_SigPnd: - memcpy(P->signal, S, 16); - P->signal[16] = '\0'; + memcpy(P->_sigpnd, S, 16); + P->_sigpnd[16] = '\0'; continue; +#else + case_ShdPnd: + P->signal = unhex(S); + continue; + case_SigBlk: + P->blocked = unhex(S); + continue; + case_SigCgt: + P->sigcatch = unhex(S); + continue; + case_SigIgn: + P->sigignore = unhex(S); + continue; + case_SigPnd: + P->_sigpnd = unhex(S); + continue; +#endif case_State: P->state = *S; continue; @@ -265,11 +294,25 @@ ENTER(0x220); continue; } +#if 0 // recent kernels supply per-tgid pending signals if(is_proc && *ShdPnd){ memcpy(P->signal, ShdPnd, 16); P->signal[16] = '\0'; } +#endif + + // recent kernels supply per-tgid pending signals +#ifdef SIGNAL_STRING + if(!is_proc || !P->signal[0]){ + memcpy(P->signal, P->_sigpnd, 16); + P->signal[16] = '\0'; + } +#else + if(!is_proc || !have_process_pending){ + P->signal = P->_sigpnd; + } +#endif // Linux 2.4.13-pre1 to max 2.4.xx have a useless "Tgid" // that is not initialized for built-in kernel tasks. @@ -764,11 +807,17 @@ proc_t* readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, pro if(!t) t = xcalloc(t, sizeof *t); /* passed buf or alloced mem */ // 1. got to fake a thread for old kernels - // 2. for single-threaded processes, this is faster + // 2. for single-threaded processes, this is faster (but must patch up stuff that differs!) if(task_dir_missing || p->nlwp < 2){ if(PT->did_fake) goto out; PT->did_fake=1; memcpy(t,p,sizeof(proc_t)); + // use the per-task pending, not per-tgid pending +#ifdef SIGNAL_STRING + memcpy(&t->signal, &t->_sigpnd, sizeof t->signal); +#else + t->signal = t->_sigpnd; +#endif return t; } diff --git a/proc/readproc.h b/proc/readproc.h index ae44c0a1..a953b291 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -58,17 +58,19 @@ typedef struct proc_t { #ifdef SIGNAL_STRING char // Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding. - signal[18], // status mask of pending signals + signal[18], // status mask of pending signals, per-task for readtask() but per-proc for readproc() blocked[18], // status mask of blocked signals sigignore[18], // status mask of ignored signals - sigcatch[18]; // status mask of caught signals + sigcatch[18], // status mask of caught signals + _sigpnd[18]; // status mask of PER TASK pending signals #else long long // Linux 2.1.7x and up have 64 signals. - signal, // status mask of pending signals + signal, // status mask of pending signals, per-task for readtask() but per-proc for readproc() blocked, // status mask of blocked signals sigignore, // status mask of ignored signals - sigcatch; // status mask of caught signals + sigcatch, // status mask of caught signals + _sigpnd; // status mask of PER TASK pending signals #endif unsigned KLONG start_code, // stat address of beginning of code segment