4 extern jmp_buf mainloop;
7 String plan9cmd; /* null terminated */
12 plan9(File *f, int type, String *s, int nest)
19 int pipe1[2], pipe2[2];
21 if(s->s[0]==0 && plan9cmd.s[0]==0)
24 Strduplstr(&plan9cmd, s);
29 if(type!='!' && pipe(pipe1)==-1)
32 snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
33 if((pid=fork()) == 0){
34 if(downloaded){ /* also put nasty fd's into errfile */
35 fd = create(errfile, 1, 0666L);
37 fd = create("/dev/null", 1, 0666L);
40 /* 2 now points at err file */
45 fd = open("/dev/null", 0);
51 if(type=='<' || type=='|')
61 if((pid = fork())==0){
63 * It's ok if we get SIGPIPE here
67 if(retcode=!setjmp(mainloop)){ /* assignment = */
69 for(l = 0; l<plan9buf.nc; l+=m){
73 bufread(&plan9buf, l, genbuf, m);
75 c = Strtoc(tmprstr(genbuf, m+1));
76 Write(pipe2[1], c, strlen(c));
80 exits(retcode? "error" : 0);
83 fprint(2, "Can't fork?!\n");
91 close(0); /* so it won't read from terminal */
94 execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), nil);
99 if(type=='<' || type=='|'){
101 if(downloaded && addr.r.p1 != addr.r.p2)
102 outTl(Hsnarflen, addr.r.p2-addr.r.p1);
103 snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);
104 logdelete(f, addr.r.p1, addr.r.p2);
108 f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);
109 f->ndot.r.p1 = addr.r.p2;
119 retmsg = waitfor(pid);
120 if(type=='|' || type=='<')
122 warn_s(Wbadstatus, retmsg);
127 return retmsg[0] ? -1 : 0;
138 if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){
139 if((f=open((char *)errfile, 0)) != -1){
140 if((n=read(f, buf, sizeof buf-1)) > 0){
141 for(nl=0,p=buf; nl<3 && p<&buf[n]; p++)
147 dprint("(sam: more in %s)\n", errfile);
152 remove((char *)errfile);