From 916b9174a60d5c07d73b4d42a3bf0b505a429c69 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Mon, 10 Jul 2017 17:22:06 +0200 Subject: xe: -L: print job ids, not PIDs PID can be reused during long runs --- xe.1 | 4 ++-- xe.c | 38 +++++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/xe.1 b/xe.1 index 0e2fde6..13cdf7c 100644 --- a/xe.1 +++ b/xe.1 @@ -89,7 +89,7 @@ Run the commands with line-buffered output; lines from two jobs will not interleave. When used with .Fl vv , -also prefix each line with the PID +also prefix each line with the job id in such a manner that the output can be piped to .Sq Li sort -snk1 to group it by job. @@ -102,7 +102,7 @@ never executes a command when no arguments are passed. Dry run: don't run the commands, just print them. .It Fl v Verbose: print commands to standard error before running them. -When used twice, also print PID and exit status for each command. +When used twice, also print job id and exit status for each command. .It Fl I Ar arg Replace occurrences of .Ar arg diff --git a/xe.c b/xe.c index 0989f3a..777f1fd 100644 --- a/xe.c +++ b/xe.c @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -45,7 +46,11 @@ static size_t argslen; static size_t argscap; static size_t argsresv; -static pid_t *children; +struct child { + pid_t pid; // 0 if empty slot + long iter; +}; +static struct child *children; static char **inargs; @@ -90,10 +95,8 @@ mywait() int i; for (i = 0; i < maxjobs; i++) - if (children[i] == pid) { - children[i] = 0; + if (children[i].pid == pid) goto my_child; - } return 1; @@ -101,28 +104,31 @@ my_child: if (WIFEXITED(status)) { if (WEXITSTATUS(status) >= 1 && WEXITSTATUS(status) <= 125) { if (Fflag) { - fprintf(stderr, "xe: pid %d exited with status %d\n", pid, WEXITSTATUS(status)); + fprintf(stderr, "xe: job %ld [pid %ld] exited with status %d\n", children[i].iter, (long)pid, WEXITSTATUS(status)); exit(123); } failed = 1; } else if (WEXITSTATUS(status) == 255) { - fprintf(stderr, "xe: pid %d exited with status 255\n", pid); + fprintf(stderr, "xe: job %ld [pid %ld] exited with status 255\n", children[i].iter, (long)pid); exit(124); } else if (WEXITSTATUS(status) > 125) { exit(WEXITSTATUS(status)); } } else if (WIFSIGNALED(status)) { - fprintf(stderr, "xe: pid %d terminated by signal %d\n", - pid, WTERMSIG(status)); + fprintf(stderr, "xe: job %ld [pid %ld] terminated by signal %d\n", + children[i].iter, (long)pid, WTERMSIG(status)); exit(125); } if (vflag > 1) { - fprintf(traceout, "%ld< %d\n", (long)pid, WEXITSTATUS(status)); + fprintf(traceout, "%04ld< status %d\n", + children[i].iter, WEXITSTATUS(status)); fflush(traceout); } - + + children[i].pid = 0; runjobs--; + return 1; } @@ -254,6 +260,7 @@ run() exit(126); if (Lflag) { + long iter = iterations; lpid = fork(); if (lpid == 0) { // in line-logging child char *line = 0; @@ -273,7 +280,7 @@ run() exit(0); if (vflag > 1) - printf("%ld= ", (long)pid); + printf("%04ld= ", iter); fwrite(line, 1, rd, stdout); }; } @@ -286,14 +293,15 @@ run() if (vflag) { if (vflag > 1) - fprintf(traceout, "%ld> ", (long)pid); + fprintf(traceout, "%04ld> ", iterations); trace(); } int i; for (i = 0; i < maxjobs; i++) - if (!children[i]) { - children[i] = pid; + if (!children[i].pid) { + children[i].pid = pid; + children[i].iter = iterations; break; } @@ -399,7 +407,7 @@ main(int argc, char *argv[], char *envp[]) exit(1); } - children = calloc(sizeof (pid_t), maxjobs); + children = calloc(sizeof (struct child), maxjobs); if (!children) exit(1); -- cgit 1.4.1