diff options
-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); } } |