Introduction
Introduction Statistics Contact Development Disclaimer Help
shell.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
shell.c (3288B)
---
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
11 void
12 setname(File *f)
13 {
14 char buf[1024];
15 if(f)
16 snprint(buf, sizeof buf, "%.*S", f->name.n, f->name.s);
17 else
18 buf[0] = 0;
19 putenv("samfile", buf);
20 }
21
22 int
23 plan9(File *f, int type, String *s, int nest)
24 {
25 long l;
26 int m;
27 int volatile pid;
28 int fd;
29 int retcode;
30 int pipe1[2], pipe2[2];
31
32 if(s->s[0]==0 && plan9cmd.s[0]==0)
33 error(Enocmd);
34 else if(s->s[0])
35 Strduplstr(&plan9cmd, s);
36 if(downloaded){
37 samerr(errfile);
38 remove(errfile);
39 }
40 if(type!='!' && pipe(pipe1)==-1)
41 error(Epipe);
42 if(type=='|')
43 snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
44 if((pid=fork()) == 0){
45 setname(f);
46 if(downloaded){ /* also put nasty fd's into errfi…
47 fd = create(errfile, 1, 0666L);
48 if(fd < 0)
49 fd = create("/dev/null", 1, 0666L);
50 dup(fd, 2);
51 close(fd);
52 /* 2 now points at err file */
53 if(type == '>')
54 dup(2, 1);
55 else if(type=='!'){
56 dup(2, 1);
57 fd = open("/dev/null", 0);
58 dup(fd, 0);
59 close(fd);
60 }
61 }
62 if(type != '!') {
63 if(type=='<' || type=='|')
64 dup(pipe1[1], 1);
65 else if(type == '>')
66 dup(pipe1[0], 0);
67 close(pipe1[0]);
68 close(pipe1[1]);
69 }
70 if(type == '|'){
71 if(pipe(pipe2) == -1)
72 exits("pipe");
73 if((pid = fork())==0){
74 /*
75 * It's ok if we get SIGPIPE here
76 */
77 close(pipe2[0]);
78 io = pipe2[1];
79 if(retcode=!setjmp(mainloop)){ /*…
80 char *c;
81 for(l = 0; l<plan9buf.nc; l+=m){
82 m = plan9buf.nc-l;
83 if(m>BLOCKSIZE-1)
84 m = BLOCKSIZE-1;
85 bufread(&plan9buf, l, ge…
86 genbuf[m] = 0;
87 c = Strtoc(tmprstr(genbu…
88 Write(pipe2[1], c, strle…
89 free(c);
90 }
91 }
92 exits(retcode? "error" : 0);
93 }
94 if(pid==-1){
95 fprint(2, "Can't fork?!\n");
96 exits("fork");
97 }
98 dup(pipe2[0], 0);
99 close(pipe2[0]);
100 close(pipe2[1]);
101 }
102 if(type=='<'){
103 close(0); /* so it won't read from termin…
104 open("/dev/null", 0);
105 }
106 execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), (char *)0);
107 exits("exec");
108 }
109 if(pid == -1)
110 error(Efork);
111 if(type=='<' || type=='|'){
112 int nulls;
113 if(downloaded && addr.r.p1 != addr.r.p2)
114 outTl(Hsnarflen, addr.r.p2-addr.r.p1);
115 snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);
116 logdelete(f, addr.r.p1, addr.r.p2);
117 close(pipe1[1]);
118 io = pipe1[0];
119 f->tdot.p1 = -1;
120 f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);
121 f->ndot.r.p1 = addr.r.p2;
122 closeio((Posn)-1);
123 }else if(type=='>'){
124 close(pipe1[0]);
125 io = pipe1[1];
126 bpipeok = 1;
127 writeio(f);
128 bpipeok = 0;
129 closeio((Posn)-1);
130 }
131 retcode = waitfor(pid);
132 if(type=='|' || type=='<')
133 if(retcode!=0)
134 warn(Wbadstatus);
135 if(downloaded)
136 checkerrs();
137 if(!nest)
138 dprint("!\n");
139 return retcode;
140 }
141
142 void
143 checkerrs(void)
144 {
145 char buf[BLOCKSIZE-10];
146 int f, n, nl;
147 char *p;
148 long l;
149
150 if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){
151 if((f=open(errfile, 0)) != -1){
152 if((n=read(f, buf, sizeof buf-1)) > 0){
153 for(nl=0,p=buf; nl<25 && p<&buf[n]; p++)
154 if(*p=='\n')
155 nl++;
156 *p = 0;
157 dprint("%s", buf);
158 if(p-buf < l-1)
159 dprint("(sam: more in %s)\n", er…
160 }
161 close(f);
162 }
163 }else
164 remove(errfile);
165 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.