Saturday, January 01, 2022

[PATCH 1/4] script(1): actually bubble child errors

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)
---
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

No comments:

Post a Comment