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)
---
Resend after a year; clean rebase. Keep me in CC.

 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

Attachment: signature.asc
Description: PGP signature

Reply via email to