1 /* Written by Anthony Liguori <aliguori@us.ibm.com> */
2
3 #include <stdio.h>
4 #include <getopt.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <err.h>
8
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <unistd.h>
12
13 #define PACKAGE_NAME "procpipe"
14 #define PACKAGE_VERSION "0.0.1"
15
16 #define GPL_SHORT \
17 "This is free software; see the source for copying conditions. There is NO\n"\
18 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
19
20 #define PACKAGE_BUGS "aliguori@us.ibm.com"
21 #define PACKAGE_AUTHOR "Anthony Liguori"
22 #define PACKAGE_OWNER "IBM, Corp."
23 #define PACKAGE_LICENSE GPL_SHORT
24
usage(const char * name)25 static void usage(const char *name)
26 {
27 printf("Usage: %s [OPTIONS]\n"
28 "\n"
29 " -h, --help display this help and exit\n"
30 " -V, --version output version information and exit\n"
31 "\n"
32 "Report bugs to <%s>.\n"
33 , name, PACKAGE_BUGS);
34 }
35
version(const char * name)36 static void version(const char *name)
37 {
38 printf("%s (%s) %s\n"
39 "Written by %s.\n"
40 "\n"
41 "Copyright (C) 2005 %s.\n"
42 "%s\n"
43 , name, PACKAGE_NAME, PACKAGE_VERSION,
44 PACKAGE_AUTHOR, PACKAGE_OWNER, PACKAGE_LICENSE);
45 }
46
exec(int stdout,int stdin,const char * cmd)47 static pid_t exec(int stdout, int stdin, const char *cmd)
48 {
49 pid_t pid;
50
51 pid = fork();
52 if (pid == 0) {
53 close(STDOUT_FILENO);
54 dup2(stdout, STDOUT_FILENO);
55 close(STDIN_FILENO);
56 dup2(stdin, STDIN_FILENO);
57
58 execlp("/bin/sh", "sh", "-c", cmd, NULL);
59 }
60
61 return pid;
62 }
63
main(int argc,char ** argv)64 int main(int argc, char **argv)
65 {
66 int ch, opt_ind = 0;
67 const char *sopt = "hV";
68 struct option lopt[] = {
69 { "help", 0, 0, 'h' },
70 { "version", 0, 0, 'V' },
71 { 0 }
72 };
73 int host_stdout[2];
74 int host_stdin[2];
75 int res;
76 pid_t pid1, pid2;
77 int status;
78
79 while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
80 switch (ch) {
81 case 'h':
82 usage(argv[0]);
83 exit(0);
84 case 'V':
85 version(argv[0]);
86 exit(0);
87 case '?':
88 errx(EINVAL, "Try `%s --help' for more information.",
89 argv[0]);
90 }
91 }
92
93 if ((argc - optind) != 2) {
94 errx(EINVAL, "Two commands are required.\n"
95 "Try `%s --help' for more information.", argv[0]);
96 }
97
98 res = pipe(host_stdout);
99 if (res == -1) {
100 err(errno, "pipe() failed");
101 }
102
103 res = pipe(host_stdin);
104 if (res == -1) {
105 err(errno, "pipe() failed");
106 }
107
108 pid1 = exec(host_stdout[1], host_stdin[0], argv[optind]);
109 if (pid1 == -1) {
110 err(errno, "exec(%s)", argv[optind]);
111 }
112
113 pid2 = exec(host_stdin[1], host_stdout[0], argv[optind + 1]);
114 if (pid2 == -1) {
115 err(errno, "exec(%s)", argv[optind + 1]);
116 }
117
118 waitpid(pid1, &status, 0);
119 if (WIFEXITED(status)) status = WEXITSTATUS(status);
120
121 if (status != 0) {
122 printf("Child exited with status %d\n", status);
123 }
124
125 waitpid(pid2, &status, 0);
126 if (WIFEXITED(status)) status = WEXITSTATUS(status);
127
128 if (status != 0) {
129 printf("Child2 exited with status %d\n", status);
130 }
131
132 return 0;
133 }
134