1 4b241872 2007-03-26 devnull #include <u.h>
2 4b241872 2007-03-26 devnull #include <signal.h>
3 4b241872 2007-03-26 devnull #if defined(PLAN9PORT) && defined(__sun__)
4 4b241872 2007-03-26 devnull # define BSD_COMP /* sigh. for TIOCNOTTY */
6 4b241872 2007-03-26 devnull #include <sys/ioctl.h>
7 f08fdedc 2003-11-23 devnull #include "rc.h"
8 f08fdedc 2003-11-23 devnull #include "getflags.h"
9 f08fdedc 2003-11-23 devnull #include "exec.h"
10 f08fdedc 2003-11-23 devnull #include "io.h"
11 f08fdedc 2003-11-23 devnull #include "fns.h"
13 f08fdedc 2003-11-23 devnull int havefork = 1;
16 f08fdedc 2003-11-23 devnull Xasync(void)
18 f08fdedc 2003-11-23 devnull int null = open("/dev/null", 0);
21 f08fdedc 2003-11-23 devnull char npid[10];
22 f08fdedc 2003-11-23 devnull if(null<0){
23 f08fdedc 2003-11-23 devnull Xerror("Can't open /dev/null\n");
26 f08fdedc 2003-11-23 devnull switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){
28 f08fdedc 2003-11-23 devnull close(null);
29 f08fdedc 2003-11-23 devnull Xerror("try again");
32 4b241872 2007-03-26 devnull clearwaitpids();
34 4b241872 2007-03-26 devnull * I don't know what the right thing to do here is,
35 4b241872 2007-03-26 devnull * so this is all experimentally determined.
36 4b241872 2007-03-26 devnull * If we just dup /dev/null onto 0, then running
37 4b241872 2007-03-26 devnull * ssh foo & will reopen /dev/tty, try to read a password,
38 4b241872 2007-03-26 devnull * get a signal, and repeat, in a tight loop, forever.
39 4b241872 2007-03-26 devnull * Arguably this is a bug in ssh (it behaves the same
40 4b241872 2007-03-26 devnull * way under bash as under rc) but I'm fixing it here
41 4b241872 2007-03-26 devnull * anyway. If we dissociate the process from the tty,
42 4b241872 2007-03-26 devnull * then it won't be able to open /dev/tty ever again.
43 4b241872 2007-03-26 devnull * The SIG_IGN on SIGTTOU makes writing the tty
44 4b241872 2007-03-26 devnull * (via fd 1 or 2, for example) succeed even though
45 4b241872 2007-03-26 devnull * our pgrp is not the terminal's controlling pgrp.
47 4b241872 2007-03-26 devnull if((tty = open("/dev/tty", OREAD)) >= 0){
49 4b241872 2007-03-26 devnull * Should make reads of tty fail, writes succeed.
51 4b241872 2007-03-26 devnull signal(SIGTTIN, SIG_IGN);
52 4b241872 2007-03-26 devnull signal(SIGTTOU, SIG_IGN);
53 4b241872 2007-03-26 devnull ioctl(tty, TIOCNOTTY);
54 4b241872 2007-03-26 devnull close(tty);
56 4b241872 2007-03-26 devnull if(isatty(0))
57 4b241872 2007-03-26 devnull pushredir(ROPEN, null, 0);
59 4b241872 2007-03-26 devnull close(null);
60 f08fdedc 2003-11-23 devnull start(runq->code, runq->pc+1, runq->local);
61 f08fdedc 2003-11-23 devnull runq->ret = 0;
64 4b241872 2007-03-26 devnull addwaitpid(pid);
65 f08fdedc 2003-11-23 devnull close(null);
66 f08fdedc 2003-11-23 devnull runq->pc = runq->code[runq->pc].i;
67 f08fdedc 2003-11-23 devnull inttoascii(npid, pid);
68 f08fdedc 2003-11-23 devnull setvar("apid", newword(npid, (word *)0));
74 f08fdedc 2003-11-23 devnull Xpipe(void)
76 f08fdedc 2003-11-23 devnull struct thread *p = runq;
77 f08fdedc 2003-11-23 devnull int pc = p->pc, forkid;
78 f08fdedc 2003-11-23 devnull int lfd = p->code[pc++].i;
79 f08fdedc 2003-11-23 devnull int rfd = p->code[pc++].i;
80 f08fdedc 2003-11-23 devnull int pfd[2];
81 f08fdedc 2003-11-23 devnull if(pipe(pfd)<0){
82 f08fdedc 2003-11-23 devnull Xerror("can't get pipe");
85 f08fdedc 2003-11-23 devnull switch(forkid = fork()){
87 f08fdedc 2003-11-23 devnull Xerror("try again");
90 4b241872 2007-03-26 devnull clearwaitpids();
91 f08fdedc 2003-11-23 devnull start(p->code, pc+2, runq->local);
92 f08fdedc 2003-11-23 devnull runq->ret = 0;
93 f08fdedc 2003-11-23 devnull close(pfd[PRD]);
94 f08fdedc 2003-11-23 devnull pushredir(ROPEN, pfd[PWR], lfd);
97 4b241872 2007-03-26 devnull addwaitpid(forkid);
98 f08fdedc 2003-11-23 devnull start(p->code, p->code[pc].i, runq->local);
99 f08fdedc 2003-11-23 devnull close(pfd[PWR]);
100 f08fdedc 2003-11-23 devnull pushredir(ROPEN, pfd[PRD], rfd);
101 f08fdedc 2003-11-23 devnull p->pc = p->code[pc+1].i;
102 f08fdedc 2003-11-23 devnull p->pid = forkid;
108 f08fdedc 2003-11-23 devnull * Who should wait for the exit from the fork?
111 f08fdedc 2003-11-23 devnull Xbackq(void)
113 f08fdedc 2003-11-23 devnull char wd[8193];
115 f08fdedc 2003-11-23 devnull char *s, *ewd=&wd[8192], *stop;
116 f08fdedc 2003-11-23 devnull struct io *f;
117 f08fdedc 2003-11-23 devnull var *ifs = vlook("ifs");
118 f08fdedc 2003-11-23 devnull word *v, *nextv;
119 f08fdedc 2003-11-23 devnull int pfd[2];
120 f08fdedc 2003-11-23 devnull int pid;
121 f08fdedc 2003-11-23 devnull stop = ifs->val?ifs->val->word:"";
122 f08fdedc 2003-11-23 devnull if(pipe(pfd)<0){
123 f08fdedc 2003-11-23 devnull Xerror("can't make pipe");
126 f08fdedc 2003-11-23 devnull switch(pid = fork()){
127 f08fdedc 2003-11-23 devnull case -1:
128 f08fdedc 2003-11-23 devnull Xerror("try again");
129 f08fdedc 2003-11-23 devnull close(pfd[PRD]);
130 f08fdedc 2003-11-23 devnull close(pfd[PWR]);
133 4b241872 2007-03-26 devnull clearwaitpids();
134 f08fdedc 2003-11-23 devnull close(pfd[PRD]);
135 f08fdedc 2003-11-23 devnull start(runq->code, runq->pc+1, runq->local);
136 f08fdedc 2003-11-23 devnull pushredir(ROPEN, pfd[PWR], 1);
138 f08fdedc 2003-11-23 devnull default:
139 4b241872 2007-03-26 devnull addwaitpid(pid);
140 f08fdedc 2003-11-23 devnull close(pfd[PWR]);
141 f08fdedc 2003-11-23 devnull f = openfd(pfd[PRD]);
144 f08fdedc 2003-11-23 devnull while((c = rchr(f))!=EOF){
145 f08fdedc 2003-11-23 devnull if(strchr(stop, c) || s==ewd){
146 f08fdedc 2003-11-23 devnull if(s!=wd){
147 f08fdedc 2003-11-23 devnull *s='\0';
148 f08fdedc 2003-11-23 devnull v = newword(wd, v);
152 f08fdedc 2003-11-23 devnull else *s++=c;
154 f08fdedc 2003-11-23 devnull if(s!=wd){
155 f08fdedc 2003-11-23 devnull *s='\0';
156 f08fdedc 2003-11-23 devnull v = newword(wd, v);
158 f08fdedc 2003-11-23 devnull closeio(f);
159 f08fdedc 2003-11-23 devnull Waitfor(pid, 0);
160 f08fdedc 2003-11-23 devnull /* v points to reversed arglist -- reverse it onto argv */
161 f08fdedc 2003-11-23 devnull while(v){
162 f08fdedc 2003-11-23 devnull nextv = v->next;
163 f08fdedc 2003-11-23 devnull v->next = runq->argv->words;
164 f08fdedc 2003-11-23 devnull runq->argv->words = v;
165 f08fdedc 2003-11-23 devnull v = nextv;
167 f08fdedc 2003-11-23 devnull runq->pc = runq->code[runq->pc].i;
173 f08fdedc 2003-11-23 devnull Xpipefd(void)
175 f08fdedc 2003-11-23 devnull struct thread *p = runq;
176 4b241872 2007-03-26 devnull int pc = p->pc, pid;
177 f08fdedc 2003-11-23 devnull char name[40];
178 f08fdedc 2003-11-23 devnull int pfd[2];
179 f08fdedc 2003-11-23 devnull int sidefd, mainfd;
180 f08fdedc 2003-11-23 devnull if(pipe(pfd)<0){
181 f08fdedc 2003-11-23 devnull Xerror("can't get pipe");
184 f08fdedc 2003-11-23 devnull if(p->code[pc].i==READ){
185 f08fdedc 2003-11-23 devnull sidefd = pfd[PWR];
186 f08fdedc 2003-11-23 devnull mainfd = pfd[PRD];
189 f08fdedc 2003-11-23 devnull sidefd = pfd[PRD];
190 f08fdedc 2003-11-23 devnull mainfd = pfd[PWR];
192 4b241872 2007-03-26 devnull switch(pid = fork()){
193 f08fdedc 2003-11-23 devnull case -1:
194 f08fdedc 2003-11-23 devnull Xerror("try again");
197 4b241872 2007-03-26 devnull clearwaitpids();
198 f08fdedc 2003-11-23 devnull start(p->code, pc+2, runq->local);
199 f08fdedc 2003-11-23 devnull close(mainfd);
200 f08fdedc 2003-11-23 devnull pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
201 f08fdedc 2003-11-23 devnull runq->ret = 0;
203 f08fdedc 2003-11-23 devnull default:
204 4b241872 2007-03-26 devnull addwaitpid(pid);
205 f08fdedc 2003-11-23 devnull close(sidefd);
206 f08fdedc 2003-11-23 devnull pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */
207 f08fdedc 2003-11-23 devnull strcpy(name, Fdprefix);
208 f08fdedc 2003-11-23 devnull inttoascii(name+strlen(name), mainfd);
209 f08fdedc 2003-11-23 devnull pushword(name);
210 f08fdedc 2003-11-23 devnull p->pc = p->code[pc+1].i;
216 f08fdedc 2003-11-23 devnull Xsubshell(void)
218 f08fdedc 2003-11-23 devnull int pid;
219 f08fdedc 2003-11-23 devnull switch(pid = fork()){
220 f08fdedc 2003-11-23 devnull case -1:
221 f08fdedc 2003-11-23 devnull Xerror("try again");
224 4b241872 2007-03-26 devnull clearwaitpids();
225 f08fdedc 2003-11-23 devnull start(runq->code, runq->pc+1, runq->local);
226 f08fdedc 2003-11-23 devnull runq->ret = 0;
228 f08fdedc 2003-11-23 devnull default:
229 4b241872 2007-03-26 devnull addwaitpid(pid);
230 f08fdedc 2003-11-23 devnull Waitfor(pid, 1);
231 f08fdedc 2003-11-23 devnull runq->pc = runq->code[runq->pc].i;
237 f08fdedc 2003-11-23 devnull execforkexec(void)
239 f08fdedc 2003-11-23 devnull int pid;
241 f08fdedc 2003-11-23 devnull char buf[ERRMAX];
243 f08fdedc 2003-11-23 devnull switch(pid = fork()){
244 f08fdedc 2003-11-23 devnull case -1:
245 f08fdedc 2003-11-23 devnull return -1;
247 4b241872 2007-03-26 devnull clearwaitpids();
248 f08fdedc 2003-11-23 devnull pushword("exec");
249 f08fdedc 2003-11-23 devnull execexec();
250 f08fdedc 2003-11-23 devnull strcpy(buf, "can't exec: ");
251 f08fdedc 2003-11-23 devnull n = strlen(buf);
252 f08fdedc 2003-11-23 devnull errstr(buf+n, ERRMAX-n);
253 f08fdedc 2003-11-23 devnull Exit(buf);
255 4b241872 2007-03-26 devnull addwaitpid(pid);
256 f08fdedc 2003-11-23 devnull return pid;