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 this after 2 weeks with minor tweaks and rebased (now that v1 4/4 was applied). I'm interested to see at least 1/3 land, and 2/3 is a very simple clean-up. If there's anything missing here, please let me know. 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