int child_count = 0;
-int run(const char *p, char *const argv[])
+int run(const char *cmd, char *const argv[])
{
int child, error;
child = fork();
return child;
}
- execvp(p, argv);
+ execvp(cmd, argv);
error = errno;
- printf("Failed to execv: %s\n", strerror(error));
+ printf("Failed to execv command %s: %s\n", cmd, strerror(error));
exit(1);
return 0;
}
-int harvest_zombies()
+int harvest_zombies(int pid)
{
int status;
- pid_t pid;
if (child_count == 0)
return 0;
- pid = wait(&status);
+ pid = waitpid(pid, &status, 0);
if (status == 0)
printf("pid %d: terminated with exit code %d\n", pid, status);
return 1;
}
+/*
+ * Runs a command cmd with params argv, connects stdin and stdout to
+ * readfd and writefd
+ *
+ * Returns the pid of the executed process
+ */
+int run_piped(const char *cmd, char *const argv[], int *readfd, int *writefd)
+{
+ int rfd[2], wfd[2], error, pid;
+
+ if (pipe(rfd)) {
+ error = errno;
+ fprintf(stderr, "pipe() failed: %s\n", strerror(error));
+ return -1;
+ }
+
+ if (pipe(wfd)) {
+ error = errno;
+ fprintf(stderr, "pipe() failed: %s\n", strerror(error));
+ return -1;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ printf("parent\n");
+ error = errno;
+ fprintf(stderr, "fork() failed: %s\n", strerror(error));
+ return -1;
+ }
+
+ if (pid) {
+ close(rfd[1]);
+ close(wfd[0]);
+ *readfd = rfd[0];
+ *writefd = wfd[1];
+ return pid;
+ }
+
+ close(rfd[0]);
+ close(wfd[1]);
+ dup2(wfd[0], STDIN_FILENO);
+ dup2(rfd[1], STDOUT_FILENO);
+
+ /* Now we have redirected both stdin and stdout to parent process */
+ execvp(cmd, argv);
+ error = errno;
+ printf("Failed to execv command %s: %s\n", cmd, strerror(error));
+ exit(1);
+ return 0;
+}
+
+/*
+ * Runs a command cmd with params argv, connects stdin and stdout to
+ * readfd and writefd
+ *
+ * Returns the pid of the executed process
+ */
+int run_piped_stream(const char *cmd, char *const argv[],
+ FILE **readf, FILE **writef)
+{
+ int rfd, wfd, pid, error;
+
+ pid = run_piped(cmd, argv, &rfd, &wfd);
+
+ if (readf) {
+ *readf = fdopen(rfd, "r");
+ if (*readf == NULL) {
+ error = errno;
+ fprintf(stderr,
+ "Error opening file stream for fd %d: %s\n",
+ rfd, strerror(error));
+ return -1;
+ }
+ }
+
+ if (writef) {
+ *writef = fdopen(wfd, "w");
+ if (*writef == NULL) {
+ error = errno;
+ fprintf(stderr,
+ "Error opening file stream for fd %d: %s\n",
+ wfd, strerror(error));
+ return -1;
+ }
+ }
+
+ return pid;
+}
#include <errno.h>
int run(const char *p, char *const argv[]);
-int harvest_zombies();
+int harvest_zombies(int pid);
+int run_piped(const char *cmd, char *const argv[], int *readfd, int *writefd);
+int run_piped_stream(const char *cmd, char *const argv[],
+ FILE **readf, FILE **writef);
extern int child_count;