13e12c5d1SDavid du Colombier #include "sam.h" 23e12c5d1SDavid du Colombier #include "parse.h" 33e12c5d1SDavid du Colombier 43e12c5d1SDavid du Colombier extern jmp_buf mainloop; 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier char errfile[64]; 73e12c5d1SDavid du Colombier String plan9cmd; /* null terminated */ 83e12c5d1SDavid du Colombier Buffer *plan9buf; 93e12c5d1SDavid du Colombier void checkerrs(void); 103e12c5d1SDavid du Colombier 11*219b2ee8SDavid du Colombier int 123e12c5d1SDavid du Colombier plan9(File *f, int type, String *s, int nest) 133e12c5d1SDavid du Colombier { 143e12c5d1SDavid du Colombier long l; 153e12c5d1SDavid du Colombier int m; 163e12c5d1SDavid du Colombier int pid, fd; 173e12c5d1SDavid du Colombier int retcode; 183e12c5d1SDavid du Colombier int pipe1[2], pipe2[2]; 193e12c5d1SDavid du Colombier 203e12c5d1SDavid du Colombier if(s->s[0]==0 && plan9cmd.s[0]==0) 213e12c5d1SDavid du Colombier error(Enocmd); 223e12c5d1SDavid du Colombier else if(s->s[0]) 233e12c5d1SDavid du Colombier Strduplstr(&plan9cmd, s); 243e12c5d1SDavid du Colombier if(downloaded) 253e12c5d1SDavid du Colombier samerr(errfile); 263e12c5d1SDavid du Colombier else 273e12c5d1SDavid du Colombier strcpy(errfile, "/dev/tty"); 283e12c5d1SDavid du Colombier if(type!='!' && pipe(pipe1)==-1) 293e12c5d1SDavid du Colombier error(Epipe); 303e12c5d1SDavid du Colombier if(type=='|') 313e12c5d1SDavid du Colombier snarf(f, addr.r.p1, addr.r.p2, plan9buf, 1); 323e12c5d1SDavid du Colombier if(downloaded) 333e12c5d1SDavid du Colombier remove(errfile); 343e12c5d1SDavid du Colombier if((pid=fork()) == 0){ 353e12c5d1SDavid du Colombier if(downloaded){ /* also put nasty fd's into errfile */ 363e12c5d1SDavid du Colombier fd = create(errfile, 1, 0666L); 373e12c5d1SDavid du Colombier if(fd < 0) 383e12c5d1SDavid du Colombier fd = create("/dev/null", 1, 0666L); 393e12c5d1SDavid du Colombier dup(fd, 2); 403e12c5d1SDavid du Colombier close(fd); 413e12c5d1SDavid du Colombier /* 2 now points at err file */ 423e12c5d1SDavid du Colombier if(type == '>') 433e12c5d1SDavid du Colombier dup(2, 1); 443e12c5d1SDavid du Colombier else if(type=='!'){ 453e12c5d1SDavid du Colombier dup(2, 1); 463e12c5d1SDavid du Colombier fd = open("/dev/null", 0); 473e12c5d1SDavid du Colombier dup(fd, 0); 483e12c5d1SDavid du Colombier close(fd); 493e12c5d1SDavid du Colombier } 503e12c5d1SDavid du Colombier } 513e12c5d1SDavid du Colombier if(type != '!') { 523e12c5d1SDavid du Colombier if(type=='<' || type=='|') 533e12c5d1SDavid du Colombier dup(pipe1[1], 1); 543e12c5d1SDavid du Colombier else if(type == '>') 553e12c5d1SDavid du Colombier dup(pipe1[0], 0); 563e12c5d1SDavid du Colombier close(pipe1[0]); 573e12c5d1SDavid du Colombier close(pipe1[1]); 583e12c5d1SDavid du Colombier } 593e12c5d1SDavid du Colombier if(type == '|'){ 603e12c5d1SDavid du Colombier if(pipe(pipe2) == -1) 613e12c5d1SDavid du Colombier exits("pipe"); 623e12c5d1SDavid du Colombier if((pid = fork())==0){ 633e12c5d1SDavid du Colombier /* 643e12c5d1SDavid du Colombier * It's ok if we get SIGPIPE here 653e12c5d1SDavid du Colombier */ 663e12c5d1SDavid du Colombier close(pipe2[0]); 673e12c5d1SDavid du Colombier io = pipe2[1]; 683e12c5d1SDavid du Colombier if(retcode=!setjmp(mainloop)){ /* assignment = */ 693e12c5d1SDavid du Colombier char *c; 703e12c5d1SDavid du Colombier for(l = 0; l<plan9buf->nrunes; l+=m){ 713e12c5d1SDavid du Colombier m = plan9buf->nrunes-l; 723e12c5d1SDavid du Colombier if(m>BLOCKSIZE-1) 733e12c5d1SDavid du Colombier m = BLOCKSIZE-1; 743e12c5d1SDavid du Colombier Bread(plan9buf, genbuf, m, l); 753e12c5d1SDavid du Colombier genbuf[m] = 0; 763e12c5d1SDavid du Colombier c = Strtoc(tmprstr(genbuf, m+1)); 773e12c5d1SDavid du Colombier Write(pipe2[1], c, strlen(c)); 783e12c5d1SDavid du Colombier free(c); 793e12c5d1SDavid du Colombier } 803e12c5d1SDavid du Colombier } 813e12c5d1SDavid du Colombier exits(retcode? "error" : 0); 823e12c5d1SDavid du Colombier } 833e12c5d1SDavid du Colombier if(pid==-1){ 843e12c5d1SDavid du Colombier fprint(2, "Can't fork?!\n"); 853e12c5d1SDavid du Colombier exits("fork"); 863e12c5d1SDavid du Colombier } 873e12c5d1SDavid du Colombier dup(pipe2[0], 0); 883e12c5d1SDavid du Colombier close(pipe2[0]); 893e12c5d1SDavid du Colombier close(pipe2[1]); 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier if(type=='<'){ 923e12c5d1SDavid du Colombier close(0); /* so it won't read from terminal */ 933e12c5d1SDavid du Colombier open("/dev/null", 0); 943e12c5d1SDavid du Colombier } 953e12c5d1SDavid du Colombier execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), (char *)0); 963e12c5d1SDavid du Colombier exits("exec"); 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier if(pid == -1) 993e12c5d1SDavid du Colombier error(Efork); 1003e12c5d1SDavid du Colombier if(type=='<' || type=='|'){ 1013e12c5d1SDavid du Colombier int nulls; 102*219b2ee8SDavid du Colombier if(downloaded && addr.r.p1 != addr.r.p2) 1033e12c5d1SDavid du Colombier outTl(Hsnarflen, addr.r.p2-addr.r.p1); 1043e12c5d1SDavid du Colombier snarf(f, addr.r.p1, addr.r.p2, snarfbuf, 0); 1053e12c5d1SDavid du Colombier Fdelete(f, addr.r.p1, addr.r.p2); 1063e12c5d1SDavid du Colombier close(pipe1[1]); 1073e12c5d1SDavid du Colombier io = pipe1[0]; 1083e12c5d1SDavid du Colombier f->tdot.p1 = -1; 1093e12c5d1SDavid du Colombier f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0); 1103e12c5d1SDavid du Colombier f->ndot.r.p1 = addr.r.p2; 1113e12c5d1SDavid du Colombier closeio((Posn)-1); 1123e12c5d1SDavid du Colombier }else if(type=='>'){ 1133e12c5d1SDavid du Colombier close(pipe1[0]); 1143e12c5d1SDavid du Colombier io = pipe1[1]; 1153e12c5d1SDavid du Colombier bpipeok = 1; 1163e12c5d1SDavid du Colombier writeio(f); 1173e12c5d1SDavid du Colombier bpipeok = 0; 1183e12c5d1SDavid du Colombier closeio((Posn)-1); 1193e12c5d1SDavid du Colombier } 1203e12c5d1SDavid du Colombier retcode = waitfor(pid); 1213e12c5d1SDavid du Colombier if(type=='|' || type=='<') 1223e12c5d1SDavid du Colombier if(retcode!=0) 1233e12c5d1SDavid du Colombier warn(Wbadstatus); 1243e12c5d1SDavid du Colombier if(downloaded) 1253e12c5d1SDavid du Colombier checkerrs(); 1263e12c5d1SDavid du Colombier if(!nest) 1273e12c5d1SDavid du Colombier dprint("!\n"); 128*219b2ee8SDavid du Colombier return retcode; 1293e12c5d1SDavid du Colombier } 1303e12c5d1SDavid du Colombier 1313e12c5d1SDavid du Colombier void 1323e12c5d1SDavid du Colombier checkerrs(void) 1333e12c5d1SDavid du Colombier { 1343e12c5d1SDavid du Colombier char buf[256]; 1353e12c5d1SDavid du Colombier int f, n, nl; 1363e12c5d1SDavid du Colombier char *p; 1373e12c5d1SDavid du Colombier long l; 1383e12c5d1SDavid du Colombier 139*219b2ee8SDavid du Colombier if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){ 1403e12c5d1SDavid du Colombier if((f=open((char *)errfile, 0)) != -1){ 1413e12c5d1SDavid du Colombier if((n=read(f, buf, sizeof buf-1)) > 0){ 1423e12c5d1SDavid du Colombier for(nl=0,p=buf; nl<3 && p<&buf[n]; p++) 1433e12c5d1SDavid du Colombier if(*p=='\n') 1443e12c5d1SDavid du Colombier nl++; 1453e12c5d1SDavid du Colombier *p = 0; 1463e12c5d1SDavid du Colombier dprint("%s", buf); 1473e12c5d1SDavid du Colombier if(p-buf < l-1) 1483e12c5d1SDavid du Colombier dprint("(sam: more in %s)\n", errfile); 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier close(f); 1513e12c5d1SDavid du Colombier } 1523e12c5d1SDavid du Colombier }else 1533e12c5d1SDavid du Colombier remove((char *)errfile); 1543e12c5d1SDavid du Colombier } 155