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 */
87dd7cddfSDavid du Colombier Buffer plan9buf;
93e12c5d1SDavid du Colombier void checkerrs(void);
103e12c5d1SDavid du Colombier
11219b2ee8SDavid du Colombier int
plan9(File * f,int type,String * s,int nest)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;
18c35931e2SDavid du Colombier char *retmsg;
193e12c5d1SDavid du Colombier int pipe1[2], pipe2[2];
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier if(s->s[0]==0 && plan9cmd.s[0]==0)
223e12c5d1SDavid du Colombier error(Enocmd);
233e12c5d1SDavid du Colombier else if(s->s[0])
243e12c5d1SDavid du Colombier Strduplstr(&plan9cmd, s);
257dd7cddfSDavid du Colombier if(downloaded){
263e12c5d1SDavid du Colombier samerr(errfile);
277dd7cddfSDavid du Colombier remove(errfile);
287dd7cddfSDavid du Colombier }
293e12c5d1SDavid du Colombier if(type!='!' && pipe(pipe1)==-1)
303e12c5d1SDavid du Colombier error(Epipe);
313e12c5d1SDavid du Colombier if(type=='|')
327dd7cddfSDavid du Colombier snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
333e12c5d1SDavid du Colombier if((pid=fork()) == 0){
343e12c5d1SDavid du Colombier if(downloaded){ /* also put nasty fd's into errfile */
353e12c5d1SDavid du Colombier fd = create(errfile, 1, 0666L);
363e12c5d1SDavid du Colombier if(fd < 0)
373e12c5d1SDavid du Colombier fd = create("/dev/null", 1, 0666L);
383e12c5d1SDavid du Colombier dup(fd, 2);
393e12c5d1SDavid du Colombier close(fd);
403e12c5d1SDavid du Colombier /* 2 now points at err file */
413e12c5d1SDavid du Colombier if(type == '>')
423e12c5d1SDavid du Colombier dup(2, 1);
433e12c5d1SDavid du Colombier else if(type=='!'){
443e12c5d1SDavid du Colombier dup(2, 1);
453e12c5d1SDavid du Colombier fd = open("/dev/null", 0);
463e12c5d1SDavid du Colombier dup(fd, 0);
473e12c5d1SDavid du Colombier close(fd);
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier }
503e12c5d1SDavid du Colombier if(type != '!') {
513e12c5d1SDavid du Colombier if(type=='<' || type=='|')
523e12c5d1SDavid du Colombier dup(pipe1[1], 1);
533e12c5d1SDavid du Colombier else if(type == '>')
543e12c5d1SDavid du Colombier dup(pipe1[0], 0);
553e12c5d1SDavid du Colombier close(pipe1[0]);
563e12c5d1SDavid du Colombier close(pipe1[1]);
573e12c5d1SDavid du Colombier }
583e12c5d1SDavid du Colombier if(type == '|'){
593e12c5d1SDavid du Colombier if(pipe(pipe2) == -1)
603e12c5d1SDavid du Colombier exits("pipe");
613e12c5d1SDavid du Colombier if((pid = fork())==0){
623e12c5d1SDavid du Colombier /*
633e12c5d1SDavid du Colombier * It's ok if we get SIGPIPE here
643e12c5d1SDavid du Colombier */
653e12c5d1SDavid du Colombier close(pipe2[0]);
663e12c5d1SDavid du Colombier io = pipe2[1];
673e12c5d1SDavid du Colombier if(retcode=!setjmp(mainloop)){ /* assignment = */
683e12c5d1SDavid du Colombier char *c;
697dd7cddfSDavid du Colombier for(l = 0; l<plan9buf.nc; l+=m){
707dd7cddfSDavid du Colombier m = plan9buf.nc-l;
713e12c5d1SDavid du Colombier if(m>BLOCKSIZE-1)
723e12c5d1SDavid du Colombier m = BLOCKSIZE-1;
737dd7cddfSDavid du Colombier bufread(&plan9buf, l, genbuf, m);
743e12c5d1SDavid du Colombier genbuf[m] = 0;
753e12c5d1SDavid du Colombier c = Strtoc(tmprstr(genbuf, m+1));
763e12c5d1SDavid du Colombier Write(pipe2[1], c, strlen(c));
773e12c5d1SDavid du Colombier free(c);
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier }
803e12c5d1SDavid du Colombier exits(retcode? "error" : 0);
813e12c5d1SDavid du Colombier }
823e12c5d1SDavid du Colombier if(pid==-1){
833e12c5d1SDavid du Colombier fprint(2, "Can't fork?!\n");
843e12c5d1SDavid du Colombier exits("fork");
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier dup(pipe2[0], 0);
873e12c5d1SDavid du Colombier close(pipe2[0]);
883e12c5d1SDavid du Colombier close(pipe2[1]);
893e12c5d1SDavid du Colombier }
903e12c5d1SDavid du Colombier if(type=='<'){
913e12c5d1SDavid du Colombier close(0); /* so it won't read from terminal */
923e12c5d1SDavid du Colombier open("/dev/null", 0);
933e12c5d1SDavid du Colombier }
94*f19e7b74SDavid du Colombier execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), nil);
953e12c5d1SDavid du Colombier exits("exec");
963e12c5d1SDavid du Colombier }
973e12c5d1SDavid du Colombier if(pid == -1)
983e12c5d1SDavid du Colombier error(Efork);
993e12c5d1SDavid du Colombier if(type=='<' || type=='|'){
1003e12c5d1SDavid du Colombier int nulls;
101219b2ee8SDavid du Colombier if(downloaded && addr.r.p1 != addr.r.p2)
1023e12c5d1SDavid du Colombier outTl(Hsnarflen, addr.r.p2-addr.r.p1);
1037dd7cddfSDavid du Colombier snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);
1047dd7cddfSDavid du Colombier logdelete(f, addr.r.p1, addr.r.p2);
1053e12c5d1SDavid du Colombier close(pipe1[1]);
1063e12c5d1SDavid du Colombier io = pipe1[0];
1073e12c5d1SDavid du Colombier f->tdot.p1 = -1;
1087dd7cddfSDavid du Colombier f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);
1093e12c5d1SDavid du Colombier f->ndot.r.p1 = addr.r.p2;
1103e12c5d1SDavid du Colombier closeio((Posn)-1);
1113e12c5d1SDavid du Colombier }else if(type=='>'){
1123e12c5d1SDavid du Colombier close(pipe1[0]);
1133e12c5d1SDavid du Colombier io = pipe1[1];
1143e12c5d1SDavid du Colombier bpipeok = 1;
1153e12c5d1SDavid du Colombier writeio(f);
1163e12c5d1SDavid du Colombier bpipeok = 0;
1173e12c5d1SDavid du Colombier closeio((Posn)-1);
1183e12c5d1SDavid du Colombier }
119c35931e2SDavid du Colombier retmsg = waitfor(pid);
1203e12c5d1SDavid du Colombier if(type=='|' || type=='<')
121c35931e2SDavid du Colombier if(retmsg[0]!=0)
122c35931e2SDavid du Colombier warn_s(Wbadstatus, retmsg);
1233e12c5d1SDavid du Colombier if(downloaded)
1243e12c5d1SDavid du Colombier checkerrs();
1253e12c5d1SDavid du Colombier if(!nest)
1263e12c5d1SDavid du Colombier dprint("!\n");
127c35931e2SDavid du Colombier return retmsg[0] ? -1 : 0;
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier
1303e12c5d1SDavid du Colombier void
checkerrs(void)1313e12c5d1SDavid du Colombier checkerrs(void)
1323e12c5d1SDavid du Colombier {
1333e12c5d1SDavid du Colombier char buf[256];
1343e12c5d1SDavid du Colombier int f, n, nl;
1353e12c5d1SDavid du Colombier char *p;
1363e12c5d1SDavid du Colombier long l;
1373e12c5d1SDavid du Colombier
138219b2ee8SDavid du Colombier if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){
1393e12c5d1SDavid du Colombier if((f=open((char *)errfile, 0)) != -1){
1403e12c5d1SDavid du Colombier if((n=read(f, buf, sizeof buf-1)) > 0){
1413e12c5d1SDavid du Colombier for(nl=0,p=buf; nl<3 && p<&buf[n]; p++)
1423e12c5d1SDavid du Colombier if(*p=='\n')
1433e12c5d1SDavid du Colombier nl++;
1443e12c5d1SDavid du Colombier *p = 0;
1453e12c5d1SDavid du Colombier dprint("%s", buf);
1463e12c5d1SDavid du Colombier if(p-buf < l-1)
1473e12c5d1SDavid du Colombier dprint("(sam: more in %s)\n", errfile);
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier close(f);
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier }else
1523e12c5d1SDavid du Colombier remove((char *)errfile);
1533e12c5d1SDavid du Colombier }
154