]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/rc/havefork.c
ip/ipconfig: use ewrite() to enable routing command for sendra
[plan9front.git] / sys / src / cmd / rc / havefork.c
1 #include "rc.h"
2 #include "getflags.h"
3 #include "exec.h"
4 #include "io.h"
5 #include "fns.h"
6
7 void
8 Xasync(void)
9 {
10         int null = open("/dev/null", 0);
11         int pid;
12         char npid[10];
13
14         if(null<0){
15                 Xerror("Can't open /dev/null\n");
16                 return;
17         }
18         Updenv();
19         switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){
20         case -1:
21                 close(null);
22                 Xerror("try again");
23                 break;
24         case 0:
25                 clearwaitpids();
26                 pushredir(ROPEN, null, 0);
27                 start(runq->code, runq->pc+1, runq->local);
28                 runq->ret = 0;
29                 break;
30         default:
31                 addwaitpid(pid);
32                 close(null);
33                 runq->pc = runq->code[runq->pc].i;
34                 inttoascii(npid, pid);
35                 setvar("apid", newword(npid, (word *)0));
36                 break;
37         }
38 }
39
40 void
41 Xpipe(void)
42 {
43         struct thread *p = runq;
44         int pc = p->pc, forkid;
45         int lfd = p->code[pc++].i;
46         int rfd = p->code[pc++].i;
47         int pfd[2];
48
49         if(pipe(pfd)<0){
50                 Xerror("can't get pipe");
51                 return;
52         }
53         Updenv();
54         switch(forkid = fork()){
55         case -1:
56                 Xerror("try again");
57                 break;
58         case 0:
59                 clearwaitpids();
60                 start(p->code, pc+2, runq->local);
61                 runq->ret = 0;
62                 close(pfd[PRD]);
63                 pushredir(ROPEN, pfd[PWR], lfd);
64                 break;
65         default:
66                 addwaitpid(forkid);
67                 start(p->code, p->code[pc].i, runq->local);
68                 close(pfd[PWR]);
69                 pushredir(ROPEN, pfd[PRD], rfd);
70                 p->pc = p->code[pc+1].i;
71                 p->pid = forkid;
72                 break;
73         }
74 }
75
76 /*
77  * Who should wait for the exit from the fork?
78  */
79 enum { Stralloc = 100, };
80
81 void
82 Xbackq(void)
83 {
84         int c, l, pid;
85         int pfd[2];
86         char *s, *wd, *ewd, *stop;
87         struct io *f;
88         word *v, *nextv;
89
90         stop = "";
91         if(runq->argv && runq->argv->words)
92                 stop = runq->argv->words->word;
93         if(pipe(pfd)<0){
94                 Xerror("can't make pipe");
95                 return;
96         }
97         Updenv();
98         switch(pid = fork()){
99         case -1:
100                 Xerror("try again");
101                 close(pfd[PRD]);
102                 close(pfd[PWR]);
103                 return;
104         case 0:
105                 clearwaitpids();
106                 close(pfd[PRD]);
107                 start(runq->code, runq->pc+1, runq->local);
108                 pushredir(ROPEN, pfd[PWR], 1);
109                 return;
110         default:
111                 addwaitpid(pid);
112                 close(pfd[PWR]);
113                 f = openfd(pfd[PRD]);
114                 s = wd = ewd = 0;
115                 v = 0;
116                 while((c = rchr(f))!=EOF){
117                         if(s==ewd){
118                                 l = s-wd;
119                                 wd = erealloc(wd, l+Stralloc);
120                                 ewd = wd+l+Stralloc-1;
121                                 s = wd+l;
122                         }
123                         if(strchr(stop, c)){
124                                 if(s!=wd){
125                                         *s='\0';
126                                         v = newword(wd, v);
127                                         s = wd;
128                                 }
129                         }
130                         else *s++=c;
131                 }
132                 if(s!=wd){
133                         *s='\0';
134                         v = newword(wd, v);
135                 }
136                 free(wd);
137                 closeio(f);
138                 Waitfor(pid, 0);
139                 poplist();      /* ditch split in "stop" */
140                 /* v points to reversed arglist -- reverse it onto argv */
141                 while(v){
142                         nextv = v->next;
143                         v->next = runq->argv->words;
144                         runq->argv->words = v;
145                         v = nextv;
146                 }
147                 runq->pc = runq->code[runq->pc].i;
148                 return;
149         }
150 }
151
152 void
153 Xpipefd(void)
154 {
155         struct thread *p = runq;
156         int pc = p->pc, pid;
157         char name[40];
158         int pfd[2];
159         int sidefd, mainfd;
160
161         if(pipe(pfd)<0){
162                 Xerror("can't get pipe");
163                 return;
164         }
165         if(p->code[pc].i==READ){
166                 sidefd = pfd[PWR];
167                 mainfd = pfd[PRD];
168         }
169         else{
170                 sidefd = pfd[PRD];
171                 mainfd = pfd[PWR];
172         }
173         Updenv();
174         switch(pid = fork()){
175         case -1:
176                 Xerror("try again");
177                 break;
178         case 0:
179                 clearwaitpids();
180                 start(p->code, pc+2, runq->local);
181                 close(mainfd);
182                 pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
183                 runq->ret = 0;
184                 break;
185         default:
186                 addwaitpid(pid);
187                 close(sidefd);
188                 pushredir(ROPEN, mainfd, mainfd);
189                 shuffleredir(); /* shuffle redir to bottom of stack for turfredir() */
190                 strcpy(name, Fdprefix);
191                 inttoascii(name+strlen(name), mainfd);
192                 pushword(name);
193                 p->pc = p->code[pc+1].i;
194                 break;
195         }
196 }
197
198 void
199 Xsubshell(void)
200 {
201         int pid;
202
203         Updenv();
204         switch(pid = fork()){
205         case -1:
206                 Xerror("try again");
207                 break;
208         case 0:
209                 clearwaitpids();
210                 start(runq->code, runq->pc+1, runq->local);
211                 runq->ret = 0;
212                 break;
213         default:
214                 addwaitpid(pid);
215                 Waitfor(pid, 1);
216                 runq->pc = runq->code[runq->pc].i;
217                 break;
218         }
219 }
220
221 int
222 execforkexec(void)
223 {
224         int pid;
225         int n;
226         char buf[ERRMAX];
227
228         switch(pid = fork()){
229         case -1:
230                 return -1;
231         case 0:
232                 clearwaitpids();
233                 pushword("exec");
234                 execexec();
235                 strcpy(buf, "can't exec: ");
236                 n = strlen(buf);
237                 errstr(buf+n, ERRMAX-n);
238                 Exit(buf);
239         }
240         addwaitpid(pid);
241         return pid;
242 }