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