commit: 05ba3f9bc9017f2542c002cd2f3d95554a02a102
parent 142e21a38b1a52929cbf63650778bf3ed74bd3e3
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 9 Nov 2025 20:13:51 +0100
cmd/time: propagate all signals to child
Diffstat:
| M | cmd/time.1 | 7 | ++----- |
| M | cmd/time.c | 68 | ++++++++++++++++++++++++++++++++++++++++---------------------------- |
2 files changed, 42 insertions(+), 33 deletions(-)
diff --git a/cmd/time.1 b/cmd/time.1
@@ -43,11 +43,8 @@ could not be found
.El
.Sh SIGNALS
.Nm
-propagates
-.Dv SIGTERM
-and
-.Dv SIGINT
-to it's child process, allowing constructs like
+propagates all signals to it's child process,
+allowing constructs like
.Ql timeout 1s time yes
to work as expected.
.Sh SEE ALSO
diff --git a/cmd/time.c b/cmd/time.c
@@ -29,23 +29,6 @@ enum cmd_time_mode
};
static void
-kill_child(int sig)
-{
- if(child > 0)
- {
- if(kill(child, sig) != 0)
- {
- // candicate for sig2str
- fprintf(stderr,
- "time: warning: Failed propagating signal number %d to child process (%d): %s\n",
- sig,
- child,
- strerror(errno));
- }
- }
-}
-
-static void
usage(void)
{
fprintf(stderr, "Usage: time [-p|-v] command [argument ...]\n");
@@ -103,6 +86,15 @@ main(int argc, char *argv[])
return 1;
}
+ sigset_t sigset;
+ if(sigfillset(&sigset) != 0) return 1;
+
+ if(sigprocmask(SIG_BLOCK, &sigset, NULL) != 0)
+ {
+ fprintf(stderr, "time: error: Failed setting process' signal mask: %s\n", strerror(errno));
+ return 1;
+ }
+
if(posix_spawnp(&child, argv[0], NULL, NULL, argv, environ) != 0)
{
ret = 126 + (errno == ENOENT);
@@ -110,20 +102,40 @@ main(int argc, char *argv[])
return ret;
}
- struct sigaction sa = {
- .sa_handler = &kill_child,
- .sa_flags = 0,
- };
+ int status = 0;
- if(sigaction(SIGTERM, &sa, NULL) != 0)
- fprintf(stderr, "time: warning: Failed adding handler for SIGTERM: %s\n", strerror(errno));
+ // Loop so signals are repeateadly propagated until child terminates
+ while(true)
+ {
+ int sig = -1;
+ if(sigwait(&sigset, &sig) != 0)
+ {
+ fprintf(stderr, "time: error: Failed waiting for signals: %s\n", strerror(errno));
+ return 1;
+ }
- if(sigaction(SIGINT, &sa, NULL) != 0)
- fprintf(stderr, "time: warning: Failed adding handler for SIGINT: %s\n", strerror(errno));
+ int ret = waitpid(child, &status, WNOHANG);
+ if(ret == child)
+ {
+ child = -1;
+ break;
+ }
+ else if(ret == -1)
+ {
+ fprintf(stderr, "time: error: Failed waiting for child process: %s\n", strerror(errno));
+ return 1;
+ }
- int status = 0;
- waitpid(child, &status, 0);
- child = -1; // reaped
+ if(kill(child, sig) != 0)
+ {
+ // candicate for sig2str
+ fprintf(stderr,
+ "time: warning: Failed propagating signal number %d to child process (%d): %s\n",
+ sig,
+ child,
+ strerror(errno));
+ }
+ }
clock_t t1 = times(&tms);
if(t1 == -1)