]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/sam/shell.c
audiohda: fix syntax error
[plan9front.git] / sys / src / cmd / sam / shell.c
1 #include "sam.h"
2 #include "parse.h"
3
4 extern  jmp_buf mainloop;
5
6 char    errfile[64];
7 String  plan9cmd;       /* null terminated */
8 Buffer  plan9buf;
9 void    checkerrs(void);
10 Buffer  cmdbuf;
11 int     cmdbufpos;
12
13 static void
14 updateenv(File *f)
15 {
16         static int fd = -1;
17         int n;
18         char buf[64], *p, *e;
19         
20         if(f == nil){
21                 putenv("%", "");
22                 putenv("%dot", "");
23                 return;
24         }
25
26         p = Strtoc(&f->name);
27         putenv("%", p);
28         free(p);
29         
30         p = buf;
31         e = buf+sizeof(buf);
32         p = seprint(p, e, "%lud", 1+nlcount(f, 0, f->dot.r.p1));
33         p = seprint(p+1, e, "%lud", f->dot.r.p1);
34         p = seprint(p+1, e, "%lud", f->dot.r.p2);
35         n = p - buf;
36         if(fd == -1)
37         if((fd = create("/env/%dot", OWRITE, 0666)) < 0)
38                 fprint(2, "updateenv create: %r\n");
39         if(write(fd, buf, n) != n)
40                 fprint(2, "updateenv write: %r\n");
41 }
42
43 int
44 plan9(File *f, int type, String *s, int nest)
45 {
46         long l;
47         int m;
48         int pid, fd;
49         int retcode;
50         char *retmsg;
51         int pipe1[2], pipe2[2];
52
53         if(s->s[0]==0 && plan9cmd.s[0]==0)
54                 error(Enocmd);
55         else if(s->s[0])
56                 Strduplstr(&plan9cmd, s);
57         if(downloaded){
58                 samerr(errfile);
59                 remove(errfile);
60         }
61         if(type!='!' && pipe(pipe1)==-1)
62                 error(Epipe);
63         if(type=='|' || type=='_')
64                 snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
65         if((pid=fork()) == 0){
66                 if(downloaded){ /* also put nasty fd's into errfile */
67                         fd = create(errfile, 1, 0666L);
68                         if(fd < 0)
69                                 fd = create("/dev/null", 1, 0666L);
70                         dup(fd, 2);
71                         close(fd);
72                         /* 2 now points at err file */
73                         if(type == '>')
74                                 dup(2, 1);
75                         else if(type=='!'){
76                                 dup(2, 1);
77                                 fd = open("/dev/null", 0);
78                                 dup(fd, 0);
79                                 close(fd);
80                         }
81                 }
82                 if(type != '!') {
83                         if(type == '>')
84                                 dup(pipe1[0], 0);
85                         else
86                                 dup(pipe1[1], 1);
87                         close(pipe1[0]);
88                         close(pipe1[1]);
89                 }
90                 if(type == '|' || type == '_'){
91                         if(pipe(pipe2) == -1)
92                                 exits("pipe");
93                         if((pid = fork())==0){
94                                 /*
95                                  * It's ok if we get SIGPIPE here
96                                  */
97                                 close(pipe2[0]);
98                                 io = pipe2[1];
99                                 if(retcode=!setjmp(mainloop)){  /* assignment = */
100                                         char *c;
101                                         for(l = 0; l<plan9buf.nc; l+=m){
102                                                 m = plan9buf.nc-l;
103                                                 if(m>BLOCKSIZE-1)
104                                                         m = BLOCKSIZE-1;
105                                                 bufread(&plan9buf, l, genbuf, m);
106                                                 genbuf[m] = 0;
107                                                 c = Strtoc(tmprstr(genbuf, m+1));
108                                                 Write(pipe2[1], c, strlen(c));
109                                                 free(c);
110                                         }
111                                 }
112                                 exits(retcode? "error" : 0);
113                         }
114                         if(pid==-1){
115                                 fprint(2, "Can't fork?!\n");
116                                 exits("fork");
117                         }
118                         dup(pipe2[0], 0);
119                         close(pipe2[0]);
120                         close(pipe2[1]);
121                 }
122                 if(type=='<' || type=='^'){
123                         close(0);       /* so it won't read from terminal */
124                         open("/dev/null", 0);
125                 }
126                 updateenv(f);
127                 execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), nil);
128                 exits("exec");
129         }
130         if(pid == -1)
131                 error(Efork);
132         if(type=='<' || type=='|'){
133                 int nulls;
134                 if(downloaded && addr.r.p1 != addr.r.p2)
135                         outTl(Hsnarflen, addr.r.p2-addr.r.p1);
136                 snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);
137                 logdelete(f, addr.r.p1, addr.r.p2);
138                 close(pipe1[1]);
139                 io = pipe1[0];
140                 f->tdot.p1 = -1;
141                 f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);
142                 f->ndot.r.p1 = addr.r.p2;
143                 closeio((Posn)-1);
144         }else if(type=='>'){
145                 close(pipe1[0]);
146                 io = pipe1[1];
147                 bpipeok = 1;
148                 writeio(f);
149                 bpipeok = 0;
150                 closeio((Posn)-1);
151         }else if(type == '^' || type == '_'){
152                 int nulls;
153                 close(pipe1[1]);
154                 bufload(&cmdbuf, cmdbufpos, pipe1[0], &nulls);
155                 close(pipe1[0]);
156         }
157         retmsg = waitfor(pid);
158         if(type=='|' || type=='<' || type=='_' || type=='^')
159                 if(retmsg[0]!=0)
160                         warn_s(Wbadstatus, retmsg);
161         if(downloaded)
162                 checkerrs();
163         if(!nest)
164                 dprint("!\n");
165         return retmsg[0] ? -1 : 0;
166 }
167
168 void
169 checkerrs(void)
170 {
171         char buf[256];
172         int f, n, nl;
173         char *p;
174         long l;
175
176         if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){
177                 if((f=open((char *)errfile, 0)) != -1){
178                         if((n=read(f, buf, sizeof buf-1)) > 0){
179                                 for(nl=0,p=buf; nl<3 && p<&buf[n]; p++)
180                                         if(*p=='\n')
181                                                 nl++;
182                                 *p = 0;
183                                 dprint("%s", buf);
184                                 if(p-buf < l-1)
185                                         dprint("(sam: more in %s)\n", errfile);
186                         }
187                         close(f);
188                 }
189         }else
190                 remove((char *)errfile);
191 }