diff options
author | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2023-10-08 19:26:29 +0200 |
---|---|---|
committer | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2023-10-08 19:26:29 +0200 |
commit | 763d49da434c25b62763ebba67ea340a9c143cfe (patch) | |
tree | 9aabd702421792d02012fe34c19cf86c5199ffb8 | |
parent | 7f7acbf4ca9f8c25e8d10402d8302bc38d3c854e (diff) |
better error handling
-rw-r--r-- | rpt.c | 53 |
1 files changed, 35 insertions, 18 deletions
@@ -1,5 +1,6 @@ #define _GNU_SOURCE /* getopt_long */ +#include <errno.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> @@ -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); } } |