Created
June 1, 2014 20:01
-
-
Save clausecker/fcf6f96a2e7667387243 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <signal.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <sys/wait.h> | |
| #include <unistd.h> | |
| #define SHELL "/bin/sh" | |
| extern int main(int, char*[]); | |
| static int readingend(int, int, const char*); | |
| static int writingend(int, int, const char*); | |
| static int usr1handler(); | |
| extern int | |
| main(int argc, char *argv[]) | |
| { | |
| int pipefd[2], status; | |
| pid_t rpid, wpid; | |
| if (argc != 3) { | |
| fprintf(stderr, "Invalid argument count\n"); | |
| return (EXIT_FAILURE); | |
| } | |
| if (pipe(pipefd)) { | |
| perror("Cannot make a pipe"); | |
| return (EXIT_FAILURE); | |
| } | |
| signal(SIGUSR1, (void(*)(int))usr1handler); | |
| if ((rpid = fork()) < 0) { | |
| perror("Cannot fork"); | |
| return (EXIT_FAILURE); | |
| } | |
| if (rpid == 0) | |
| return (readingend(pipefd[0], pipefd[1], argv[2])); | |
| if ((wpid = fork()) < 0) { | |
| perror("Cannot fork"); | |
| kill(rpid, SIGKILL); | |
| return (EXIT_FAILURE); | |
| } | |
| if (wpid == 0) | |
| return (writingend(pipefd[0], pipefd[1], argv[1])); | |
| close(pipefd[0]); | |
| close(pipefd[1]); | |
| waitpid(rpid, &status, 0); | |
| return (status); | |
| } | |
| static int | |
| readingend(int rfd, int wfd, const char *cmd) | |
| { | |
| close(wfd); | |
| dup2(rfd, STDIN_FILENO); | |
| /* execl() only returns on error */ | |
| execl(SHELL, SHELL, "-c", cmd, NULL); | |
| fprintf(stderr, "Cannot execute %s: ", cmd); | |
| perror(NULL); | |
| /* clean up */ | |
| kill(getppid(), SIGUSR1); | |
| return (EXIT_FAILURE); | |
| } | |
| static int | |
| writingend(int rfd, int wfd, const char *cmd) | |
| { | |
| close(rfd); | |
| dup2(wfd, STDOUT_FILENO); | |
| execl(SHELL, SHELL, "-c", cmd, NULL); | |
| fprintf(stderr, "Cannot execute %s: ", cmd); | |
| perror(NULL); | |
| /* clean up */ | |
| kill(getppid(), SIGUSR1); | |
| return (EXIT_FAILURE); | |
| } | |
| static int | |
| usr1handler() | |
| { | |
| /* child already printed diagnostic */ | |
| exit(EXIT_FAILURE); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment