tagging vde-2 version 2.3.2
[vde.git] / 2.3.2 / src / dpipe.c
blobef47d887346801593014aece07f7583f19e03cc4
1 /* Copyright 2003 Renzo Davoli
2 * Licensed under the GPL
3 */
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <signal.h>
11 #include <fcntl.h>
13 #include <config.h>
14 #include <vde.h>
15 #include <vdecommon.h>
17 #if 0
18 #define execvp(X,Y) \
19 ({ char **y; \
20 fprintf(stderr,"execvp \"%s\" -",(X)); \
21 for (y=(Y); *y != NULL; y++) \
22 fprintf(stderr,"\"%s\"",*y); \
23 fprintf(stderr,"\n"); \
24 sleep (10); \
26 #endif
28 static char *progname;
30 int splitindex(int argc, char *argv[], int *dirchar)
32 register int i;
34 for (i=0; i<argc; i++) {
35 if (*dirchar == argv[i][0] && argv[i][1] == '=' ) {
36 (argv[i])++;*dirchar=0;
38 if (argv[i][0] == '=') {
39 if (argv[i][1] == '}' || argv[i][1] == '{')
40 *dirchar=argv[i][1];
41 break;
44 return i;
47 void usage()
49 fprintf(stderr,"Usage:\n\t%s cmd1 [arg1...] = cmd2 [arg2...]\n\n",progname);
50 kill(getpgrp(),SIGTERM);
51 exit (-1);
54 static int alternate_stdin;
55 static int alternate_stdout;
56 static void alternate_fd()
58 char numstr[10];
59 alternate_stdin=open("/dev/null",O_RDONLY);
60 alternate_stdout=open("/dev/null",O_RDONLY);
61 close(alternate_stdin);
62 close(alternate_stdout);
63 snprintf(numstr,10,"%d",alternate_stdin);
64 setenv("ALTERNATE_STDIN",numstr,1);
65 snprintf(numstr,10,"%d",alternate_stdout);
66 setenv("ALTERNATE_STDOUT",numstr,1);
69 int recmain(int argc, char *argv[],int olddirchar)
71 int split;
72 int newdirchar=olddirchar;
74 split=splitindex(argc,argv,&newdirchar);
75 if (split >= argc) {
76 if (newdirchar != 0)
77 usage();
78 execvp(argv[0],argv);
80 else {
81 char **argv1,**argv2;
82 int p1[2],p2[2];
84 if (argc < 3 || split == 0 || split == argc-1)
85 usage();
87 pipe(p1);
88 if (olddirchar == 0) pipe(p2);
89 argv[split]=NULL;
90 argv1=argv;
91 argv2=argv+(split+1);
93 if (fork()) {
94 switch (olddirchar) {
95 case 0:
96 close(p1[1]); close(p2[0]);
97 if (p1[0] != alternate_stdin){
98 dup2(p1[0],alternate_stdin);
99 close(p1[0]);
101 if (p1[0] != alternate_stdout){
102 dup2(p2[1],alternate_stdout);
103 close(p2[1]);
105 break;
106 case '}':
107 close(p1[0]);
108 dup2(p1[1],STDOUT_FILENO);
109 close(p1[1]);
110 break;
111 case '{':
112 close(p1[1]);
113 dup2(p1[0],STDIN_FILENO);
114 close(p1[0]);
115 break;
116 default:
117 fprintf(stderr,"Error\n");
119 execvp(argv1[0],argv1);
120 } else {
121 switch (olddirchar) {
122 case 0:
123 close(p2[1]); close(p1[0]);
124 dup2(p2[0],STDIN_FILENO);
125 dup2(p1[1],STDOUT_FILENO);
126 close(p2[0]); close(p1[1]);
127 break;
128 case '}':
129 close(p1[1]);
130 dup2(p1[0],STDIN_FILENO);
131 close(p1[0]);
132 break;
133 case '{':
134 close(p1[0]);
135 dup2(p1[1],STDOUT_FILENO);
136 close(p1[1]);
137 break;
138 default:
139 fprintf(stderr,"Error\n");
141 recmain(argc-split-1,argv2,newdirchar);
144 return 0;
147 int main(int argc, char *argv[])
150 int split;
151 char **argv1,**argv2;
152 int p1[2],p2[2];
153 int dirchar=0;
154 int daemonize=0;
155 char *pidfile=NULL;
156 int pgrp;
157 int argflag;
158 int err=0;
160 progname=argv[0];
161 argv++;
162 argc--;
164 do {
165 argflag=0;
166 if (argv[0] && *argv[0] == '-') {
167 argflag++;
168 argv[0]++;
169 if (*argv[0] == '-') {
170 argv[0]++;
171 if (strcmp(argv[0],"daemon") == 0)
172 daemonize = 1;
173 else if (strcmp(argv[0],"pidfile") == 0) {
174 pidfile = argv[argflag];
175 argflag++;
176 } else {
177 fprintf(stderr,"unknown option --%s\n",argv[0]);
178 err++;
180 } else {
181 while (*argv[0] != 0) {
182 switch (*argv[0]) {
183 case 0: break;
184 case 'd': daemonize = 1; break;
185 case 'p': pidfile = argv[argflag];
186 argflag++;
187 break;
188 default: fprintf(stderr,"unknown option -%c\n",*argv[0]);
189 err++;
191 if (*argv[0] != 0) argv[0]++;
194 argv += argflag;
195 argc -= argflag;
197 } while (argflag);
199 if (err)
200 exit(1);
202 if (daemonize != 0)
203 daemon(0,0);
204 else if (setpgrp() != 0) {
205 fprintf(stderr,"Err: cannot create pgrp\n");
206 exit(1);
209 pgrp = getpgrp();
211 if (pidfile != NULL) {
212 FILE *f=fopen(pidfile, "w");
213 if (f != NULL) {
214 fprintf(f,"-%d\n",pgrp);
215 fclose(f);
219 alternate_fd();
220 split=splitindex(argc,argv,&dirchar);
222 if (argc < 3 || split == 0 || split >= argc-1)
223 usage();
225 pipe(p1);
226 pipe(p2);
227 argv[split]=NULL;
228 argv1=argv;
229 argv2=argv+(split+1);
231 if (fork()) {
232 close(p1[1]); close(p2[0]);
233 dup2(p1[0],STDIN_FILENO);
234 dup2(p2[1],STDOUT_FILENO);
235 close(p1[0]); close(p2[1]);
236 execvp(argv1[0],argv1);
237 } else {
238 close(p2[1]); close(p1[0]);
239 dup2(p2[0],STDIN_FILENO);
240 dup2(p1[1],STDOUT_FILENO);
241 close(p1[1]); close(p2[0]);
242 recmain(argc-split-1,argv2,dirchar);
244 return (0);