aboutsummaryrefslogtreecommitdiff
path: root/rpt.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpt.c')
-rw-r--r--rpt.c53
1 files 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 <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);
}
}