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
int i = 1, size = 32;
union el *list;
- list = malloc (size * sizeof (union el));
+ list = malloc (size * sizeof *list);
if (list == NULL)
exit (3);
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);
}
} else {
list[0].num = i - 1;
}
- return (list);
+ return list;
}
/* strict_atol returns a Boolean: TRUE if the input string contains a
res += *str - '0';
}
*value = sign * res;
- return (1);
+ return 1;
}
static int
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;
}
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;
}
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;
}
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;
}
if (! strict_atol (name, &e->num)) {
fprintf (stderr, "%s: not a number: %s\n",
progname, name);
- return (0);
+ return 0;
}
- return (1);
+ return 1;
}
conv_str (const char *restrict name, union el *restrict e)
{
e->str = strdup (name);
- return (1);
+ return 1;
}
found = 1;
}
}
- return (found);
+ return found;
}
static int
found = 1;
}
}
- return (found);
+ return found;
}
static void
} else {
ptp = openproc (flags);
}
- return (ptp);
+ return ptp;
}
static regex_t *
}
static union el *
-select_procs (void)
+select_procs (int *num)
{
PROCTAB *ptp;
proc_t task;
union el *list;
char cmd[4096];
- list = malloc (size * sizeof (union el));
+ list = malloc (size * sizeof *list);
if (list == NULL)
exit (3);
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);
}
}
closeproc (ptp);
- list[0].num = matches;
- return (list);
+ *num = matches;
+ return list;
}
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",
else
output_numlist (procs);
}
- return ((procs[0].num) == 0 ? 1 : 0);
+ return !num;
}
#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;
///////////////////////////////////////////////////////////////////////////
// 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;
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;
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);
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;
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.
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;
}
#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