Blame


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