4 extern jmp_buf mainloop;
7 String plan9cmd; /* null terminated */
14 plan9(File *f, int type, String *s, int nest)
21 int pipe1[2], pipe2[2];
23 if(s->s[0]==0 && plan9cmd.s[0]==0)
26 Strduplstr(&plan9cmd, s);
31 if(type!='!' && pipe(pipe1)==-1)
33 if(type=='|' || type=='_')
34 snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
35 if((pid=fork()) == 0){
36 if(downloaded){ /* also put nasty fd's into errfile */
37 fd = create(errfile, 1, 0666L);
39 fd = create("/dev/null", 1, 0666L);
42 /* 2 now points at err file */
47 fd = open("/dev/null", 0);
60 if(type == '|' || type == '_'){
63 if((pid = fork())==0){
65 * It's ok if we get SIGPIPE here
69 if(retcode=!setjmp(mainloop)){ /* assignment = */
71 for(l = 0; l<plan9buf.nc; l+=m){
75 bufread(&plan9buf, l, genbuf, m);
77 c = Strtoc(tmprstr(genbuf, m+1));
78 Write(pipe2[1], c, strlen(c));
82 exits(retcode? "error" : 0);
85 fprint(2, "Can't fork?!\n");
92 if(type=='<' || type=='^'){
93 close(0); /* so it won't read from terminal */
96 putenv("%", f == nil ? "" : Strtoc(&f->name));
97 execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), nil);
102 if(type=='<' || type=='|'){
104 if(downloaded && addr.r.p1 != addr.r.p2)
105 outTl(Hsnarflen, addr.r.p2-addr.r.p1);
106 snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);
107 logdelete(f, addr.r.p1, addr.r.p2);
111 f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);
112 f->ndot.r.p1 = addr.r.p2;
121 }else if(type == '^' || type == '_'){
124 bufload(&cmdbuf, cmdbufpos, pipe1[0], &nulls);
127 retmsg = waitfor(pid);
128 if(type=='|' || type=='<' || type=='_' || type=='^')
130 warn_s(Wbadstatus, retmsg);
135 return retmsg[0] ? -1 : 0;
146 if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){
147 if((f=open((char *)errfile, 0)) != -1){
148 if((n=read(f, buf, sizeof buf-1)) > 0){
149 for(nl=0,p=buf; nl<3 && p<&buf[n]; p++)
155 dprint("(sam: more in %s)\n", errfile);
160 remove((char *)errfile);