From 763d49da434c25b62763ebba67ea340a9c143cfe Mon Sep 17 00:00:00 2001 From: Tristan Riehs Date: Sun, 8 Oct 2023 19:26:29 +0200 Subject: better error handling --- rpt.c | 53 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/rpt.c b/rpt.c index 1a9a256..d07d227 100644 --- a/rpt.c +++ b/rpt.c @@ -1,5 +1,6 @@ #define _GNU_SOURCE /* getopt_long */ +#include #include #include #include @@ -49,37 +50,53 @@ continue_on_error(int status) (void) status; } +void +exec_child(char **argv) +{ + int status; + + status = execvp(argv[0], argv); + + if (status < 0) + { + perror("rpt[child process]"); + exit(4); + } + + exit(4); +} + +void +wait_child(pid_t pid, void (*handle_error_f)(int status)) +{ + int exit_status = 0; + + waitpid(pid, &exit_status, 0); + + handle_error_f(exit_status); +} + /* Invoke the executable *ARGV COUNT times, passing it the rest of ARG as arguments. Call HANDLE_ERROR_F between each process. */ void -repeat_cmd(char **argv, long count, void (*handle_error_f)(int)) +repeat_cmd(char **argv, long count, void (*handle_error_f)(int status)) { pid_t pid; - int status; for(long i = 0; i < count; ++i) { pid = fork(); - if (pid == 0) + if (pid < 0) { - /* child */ - status = execvp(argv[0], argv); - - if (status < 0) - exit(1); - - exit(2); + perror("rpt"); + exit(4); } - else - { - /* parent */ - int exit_status = 0; - - waitpid(pid, &exit_status, 0); - handle_error_f(exit_status); - } + if (pid == 0) + exec_child(argv); + else + wait_child(pid, handle_error_f); } } -- cgit v1.2.3