3 #if defined(PLAN9PORT) && defined(__sun__)
4 # define BSD_COMP /* sigh. for TIOCNOTTY */
18 int null = open("/dev/null", 0);
23 Xerror("Can't open /dev/null\n");
26 switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){
34 * I don't know what the right thing to do here is,
35 * so this is all experimentally determined.
36 * If we just dup /dev/null onto 0, then running
37 * ssh foo & will reopen /dev/tty, try to read a password,
38 * get a signal, and repeat, in a tight loop, forever.
39 * Arguably this is a bug in ssh (it behaves the same
40 * way under bash as under rc) but I'm fixing it here
41 * anyway. If we dissociate the process from the tty,
42 * then it won't be able to open /dev/tty ever again.
43 * The SIG_IGN on SIGTTOU makes writing the tty
44 * (via fd 1 or 2, for example) succeed even though
45 * our pgrp is not the terminal's controlling pgrp.
47 if((tty = open("/dev/tty", OREAD)) >= 0){
49 * Should make reads of tty fail, writes succeed.
51 signal(SIGTTIN, SIG_IGN);
52 signal(SIGTTOU, SIG_IGN);
53 ioctl(tty, TIOCNOTTY);
57 pushredir(ROPEN, null, 0);
60 start(runq->code, runq->pc+1, runq->local);
66 runq->pc = runq->code[runq->pc].i;
67 inttoascii(npid, pid);
68 setvar("apid", newword(npid, (word *)0));
76 struct thread *p = runq;
77 int pc = p->pc, forkid;
78 int lfd = p->code[pc++].i;
79 int rfd = p->code[pc++].i;
82 Xerror("can't get pipe");
85 switch(forkid = fork()){
91 start(p->code, pc+2, runq->local);
94 pushredir(ROPEN, pfd[PWR], lfd);
98 start(p->code, p->code[pc].i, runq->local);
100 pushredir(ROPEN, pfd[PRD], rfd);
101 p->pc = p->code[pc+1].i;
108 * Who should wait for the exit from the fork?
113 struct thread *p = runq;
116 char *s, *ewd=&wd[8192], *stop, *q;
118 var *ifs = vlook("ifs");
123 stop = ifs->val?ifs->val->word:"";
125 Xerror("can't make pipe");
128 switch(pid = fork()){
137 start(runq->code, runq->pc+1, runq->local);
138 pushredir(ROPEN, pfd[PWR], 1);
143 f = openfd(pfd[PRD]);
146 while((c = rchr(f))!=EOF){
149 for(q=stop; *q; q+=n) {
150 n = chartorune(&r, q);
151 if(s-wd >= n && memcmp(s-n, q, n) == 0) {
171 /* v points to reversed arglist -- reverse it onto argv */
174 v->next = runq->argv->words;
175 runq->argv->words = v;
178 p->pc = p->code[p->pc].i;
186 struct thread *p = runq;
190 struct { int sidefd, mainfd; } fd[2], *r, *w;
194 switch(p->code[pc].i){
204 Xerror("can't get pipe");
207 r->sidefd = pfd[PWR];
208 r->mainfd = pfd[PRD];
212 Xerror("can't get pipe");
215 w->sidefd = pfd[PRD];
216 w->mainfd = pfd[PWR];
218 switch(pid = fork()){
224 start(p->code, pc+2, runq->local);
227 pushredir(ROPEN, r->sidefd, 1);
231 pushredir(ROPEN, w->sidefd, 0);
239 pushredir(ROPEN, w->mainfd, w->mainfd); /* so that Xpopredir can close it later */
240 strcpy(name, Fdprefix);
241 inttoascii(name+strlen(name), w->mainfd);
246 pushredir(ROPEN, r->mainfd, r->mainfd);
247 strcpy(name, Fdprefix);
248 inttoascii(name+strlen(name), r->mainfd);
251 p->pc = p->code[pc+1].i;
260 switch(pid = fork()){
266 start(runq->code, runq->pc+1, runq->local);
272 runq->pc = runq->code[runq->pc].i;
284 switch(pid = fork()){
291 strcpy(buf, "can't exec: ");
293 errstr(buf+n, ERRMAX-n);