commit: c93bd81010be5bde922ad54271f53d04549b6ec1
parent 378169e980db0bf73bd4e258c686622150be6383
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 18 Jun 2025 16:07:01 +0200
exits when child process returns non-zero
Diffstat:
M | timer.c | 63 | ++++++++++++++++++++++++++++++++++++++++++++++----------------- |
1 file changed, 46 insertions(+), 17 deletions(-)
diff --git a/timer.c b/timer.c
@@ -5,14 +5,15 @@
#include "strtodur.h"
#include <errno.h>
-#include <limits.h> // UINT_MAX
-#include <signal.h> // sigaction
-#include <spawn.h> // posix_spawnp
-#include <stdio.h> // fprintf, fputs
-#include <stdlib.h> // exit
-#include <string.h> // strerror
-#include <time.h> // timer_create
-#include <unistd.h> // sleep
+#include <limits.h> // UINT_MAX
+#include <signal.h> // sigaction
+#include <spawn.h> // posix_spawnp
+#include <stdio.h> // fprintf, fputs
+#include <stdlib.h> // exit
+#include <string.h> // strerror
+#include <sys/wait.h> // waitpid
+#include <time.h> // timer_create
+#include <unistd.h> // sleep
extern char **environ;
static char **args;
@@ -33,6 +34,17 @@ sig_timer(int sig)
}
static void
+sig_chld(int sig)
+{
+ int chld_stat = 0;
+ waitpid((pid_t)-1, &chld_stat, WNOHANG);
+
+ if(!WIFEXITED(chld_stat)) return;
+
+ if(WEXITSTATUS(chld_stat) != 0) exit(WEXITSTATUS(chld_stat));
+}
+
+static void
bad_usage()
{
fputs("Usage: timer <interval> <command> [arguments...]\n", stderr);
@@ -67,21 +79,25 @@ main(int argc, char *argv[])
argc--;
argv++;
- struct sigaction sa;
- sa.sa_handler = &sig_timer;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
+ struct sigaction sa_alrm;
+ sa_alrm.sa_handler = &sig_timer;
+ sigemptyset(&sa_alrm.sa_mask);
+ sa_alrm.sa_flags = SA_RESTART;
- if(sigaction(SIGALRM, &sa, NULL) != 0)
+ if(sigaction(SIGALRM, &sa_alrm, NULL) != 0)
{
fprintf(stderr, "timer: error: Failed registering signal handler: %s\n", strerror(errno));
return 1;
}
- errno = 0;
- if(signal(SIGCHLD, SIG_IGN) == SIG_ERR)
+ struct sigaction sa_chld;
+ sa_chld.sa_handler = &sig_chld;
+ sigemptyset(&sa_chld.sa_mask);
+ sa_chld.sa_flags = SA_RESTART;
+
+ if(sigaction(SIGCHLD, &sa_chld, NULL) != 0)
{
- fprintf(stderr, "timer: error: Failed setting to ignore SIGCHLD: %s\n", strerror(errno));
+ fprintf(stderr, "timer: error: Failed registering signal handler: %s\n", strerror(errno));
return 1;
}
@@ -109,7 +125,20 @@ main(int argc, char *argv[])
args = argv;
- while(sigsuspend(&sa.sa_mask))
+ sigset_t sigmask;
+ sigfillset(&sigmask);
+ if(sigdelset(&sigmask, SIGALRM) != 0)
+ {
+ fprintf(stderr, "timer: error: Failed adding SIGALARM to new sigmask: %s\n", strerror(errno));
+ return 1;
+ }
+ if(sigdelset(&sigmask, SIGCHLD) != 0)
+ {
+ fprintf(stderr, "timer: error: Failed adding SIGCHLD to new sigmask: %s\n", strerror(errno));
+ return 1;
+ }
+
+ while(sigsuspend(&sigmask))
;
return 0;