script.1 says > script will exit with the status of 0 unless any of its child > processes fail, in which case, script will return 1. This is a patent lie: it only exits with 1 if the host or writer processes fail, not the actual child
Instead, wait for the child in the writer process and bubble its status up verbatim (for signals ‒ as shell-style 128+sig) --- Resending after a month. I previously posted this to user@, per official instructions, but this may be a better place. 1/3 is def. what I'm most interested in pushing through, since having functional pass-through fixes a bunch of dirty work-arounds in my CI jobs, and 2/3 is simple clean-up and fixes mismatched warnings; 3/3 would be nice to have, but ultimately not that impactful. Please keep me in CC, as I'm not subscribed. usr.bin/script/script.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c index da22623ff..763975d6a 100644 --- a/usr.bin/script/script.c +++ b/usr.bin/script/script.c @@ -251,16 +251,12 @@ dooutput(void) sigemptyset(&blkalrm); sigaddset(&blkalrm, SIGALRM); + sigaddset(&blkalrm, SIGCHLD); bzero(&sa, sizeof sa); sigemptyset(&sa.sa_mask); sa.sa_handler = scriptflush; (void)sigaction(SIGALRM, &sa, NULL); - bzero(&sa, sizeof sa); - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_IGN; - (void)sigaction(SIGCHLD, &sa, NULL); - if (pledge("stdio proc", NULL) == -1) err(1, "pledge"); @@ -295,7 +291,17 @@ dooutput(void) outcc += cc; sigprocmask(SIG_UNBLOCK, &blkalrm, NULL); } - done(0); + + int e = 0, err; + while ((err = wait(&e)) == -1 && errno == EINTR) + ; + if (err != -1) { + if (WIFEXITED(e)) + e = WEXITSTATUS(e); + else + e = 128 + WTERMSIG(e); + } + done(e); } void -- 2.30.2
signature.asc
Description: PGP signature