Blob
1 #include "sam.h"2 #include "parse.h"4 extern jmp_buf mainloop;6 char errfile[64];7 String plan9cmd; /* null terminated */8 Buffer plan9buf;9 void checkerrs(void);11 int12 plan9(File *f, int type, String *s, int nest)13 {14 long l;15 int m;16 int pid, fd;17 int retcode;18 int pipe1[2], pipe2[2];20 if(s->s[0]==0 && plan9cmd.s[0]==0)21 error(Enocmd);22 else if(s->s[0])23 Strduplstr(&plan9cmd, s);24 if(downloaded){25 samerr(errfile);26 remove(errfile);27 }28 if(type!='!' && pipe(pipe1)==-1)29 error(Epipe);30 if(type=='|')31 snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);32 if((pid=fork()) == 0){33 if(downloaded){ /* also put nasty fd's into errfile */34 fd = create(errfile, 1, 0666L);35 if(fd < 0)36 fd = create("/dev/null", 1, 0666L);37 dup(fd, 2);38 close(fd);39 /* 2 now points at err file */40 if(type == '>')41 dup(2, 1);42 else if(type=='!'){43 dup(2, 1);44 fd = open("/dev/null", 0);45 dup(fd, 0);46 close(fd);47 }48 }49 if(type != '!') {50 if(type=='<' || type=='|')51 dup(pipe1[1], 1);52 else if(type == '>')53 dup(pipe1[0], 0);54 close(pipe1[0]);55 close(pipe1[1]);56 }57 if(type == '|'){58 if(pipe(pipe2) == -1)59 exits("pipe");60 if((pid = fork())==0){61 /*62 * It's ok if we get SIGPIPE here63 */64 close(pipe2[0]);65 io = pipe2[1];66 if(retcode=!setjmp(mainloop)){ /* assignment = */67 char *c;68 for(l = 0; l<plan9buf.nc; l+=m){69 m = plan9buf.nc-l;70 if(m>BLOCKSIZE-1)71 m = BLOCKSIZE-1;72 bufread(&plan9buf, l, genbuf, m);73 genbuf[m] = 0;74 c = Strtoc(tmprstr(genbuf, m+1));75 Write(pipe2[1], c, strlen(c));76 free(c);77 }78 }79 exits(retcode? "error" : 0);80 }81 if(pid==-1){82 fprint(2, "Can't fork?!\n");83 exits("fork");84 }85 dup(pipe2[0], 0);86 close(pipe2[0]);87 close(pipe2[1]);88 }89 if(type=='<'){90 close(0); /* so it won't read from terminal */91 open("/dev/null", 0);92 }93 execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), (char *)0);94 exits("exec");95 }96 if(pid == -1)97 error(Efork);98 if(type=='<' || type=='|'){99 int nulls;100 if(downloaded && addr.r.p1 != addr.r.p2)101 outTl(Hsnarflen, addr.r.p2-addr.r.p1);102 snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);103 logdelete(f, addr.r.p1, addr.r.p2);104 close(pipe1[1]);105 io = pipe1[0];106 f->tdot.p1 = -1;107 f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);108 f->ndot.r.p1 = addr.r.p2;109 closeio((Posn)-1);110 }else if(type=='>'){111 close(pipe1[0]);112 io = pipe1[1];113 bpipeok = 1;114 writeio(f);115 bpipeok = 0;116 closeio((Posn)-1);117 }118 retcode = waitfor(pid);119 if(type=='|' || type=='<')120 if(retcode!=0)121 warn(Wbadstatus);122 if(downloaded)123 checkerrs();124 if(!nest)125 dprint("!\n");126 return retcode;127 }129 void130 checkerrs(void)131 {132 char buf[256];133 int f, n, nl;134 char *p;135 long l;137 if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){138 if((f=open((char *)errfile, 0)) != -1){139 if((n=read(f, buf, sizeof buf-1)) > 0){140 for(nl=0,p=buf; nl<3 && p<&buf[n]; p++)141 if(*p=='\n')142 nl++;143 *p = 0;144 dprint("%s", buf);145 if(p-buf < l-1)146 dprint("(sam: more in %s)\n", errfile);147 }148 close(f);149 }150 }else151 remove((char *)errfile);152 }