Introduction
Introduction Statistics Contact Development Disclaimer Help
unix.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
unix.c (5290B)
---
1 #define NOPLAN9DEFINES
2 #include "mk.h"
3 #include <sys/wait.h>
4 #include <signal.h>
5 #include <sys/stat.h>
6 #include <sys/time.h>
7
8 char *shell = "/bin/sh";
9 char *shellname = "sh";
10
11 extern char **environ;
12
13 static void
14 mkperror(char *s)
15 {
16 fprint(2, "%s: %r\n", s);
17 }
18
19 void
20 readenv(void)
21 {
22 char **p, *s;
23 Word *w;
24
25 for(p = environ; *p; p++){
26 /* rsc 5/5/2004 -- This misparses fn#cd={whatever}
27 s = shname(*p);
28 if(*s == '=') {
29 *s = 0;
30 w = newword(s+1);
31 } else
32 w = newword("");
33 */
34 s = strchr(*p, '=');
35 if(s){
36 *s = 0;
37 w = newword(s+1);
38 } else
39 w = newword("");
40 if (symlook(*p, S_INTERNAL, 0))
41 continue;
42 s = strdup(*p);
43 setvar(s, (void *)w);
44 symlook(s, S_EXPORTED, (void*)"")->u.ptr = "";
45 }
46 }
47
48 /*
49 * done on child side of fork, so parent's env is not affected
50 * and we don't care about freeing memory because we're going
51 * to exec immediately after this.
52 */
53 void
54 exportenv(Envy *e, Shell *sh)
55 {
56 int i;
57 char **p;
58 static char buf[16384];
59
60 p = 0;
61 for(i = 0; e->name; e++, i++) {
62 p = (char**) Realloc(p, (i+2)*sizeof(char*));
63 if(e->values)
64 snprint(buf, sizeof buf, "%s=%s", e->name, wtos…
65 else
66 snprint(buf, sizeof buf, "%s=", e->name);
67 p[i] = strdup(buf);
68 }
69 p[i] = 0;
70 environ = p;
71 }
72
73 int
74 waitfor(char *msg)
75 {
76 int status;
77 int pid;
78
79 *msg = 0;
80 pid = wait(&status);
81 if(pid > 0) {
82 if(status&0x7f) {
83 if(status&0x80)
84 snprint(msg, ERRMAX, "signal %d, core du…
85 else
86 snprint(msg, ERRMAX, "signal %d", status…
87 } else if(status&0xff00)
88 snprint(msg, ERRMAX, "exit(%d)", (status>>8)&0xf…
89 }
90 return pid;
91 }
92
93 void
94 expunge(int pid, char *msg)
95 {
96 if(strcmp(msg, "interrupt"))
97 kill(pid, SIGINT);
98 else
99 kill(pid, SIGHUP);
100 }
101
102 int mypid;
103
104 int
105 shargv(Word *cmd, int extra, char ***pargv)
106 {
107 char **argv;
108 int i, n;
109 Word *w;
110
111 n = 0;
112 for(w=cmd; w; w=w->next)
113 n++;
114
115 argv = Malloc((n+extra+1)*sizeof(argv[0]));
116 i = 0;
117 for(w=cmd; w; w=w->next)
118 argv[i++] = w->s;
119 argv[n] = 0;
120 *pargv = argv;
121 return n;
122 }
123
124 int
125 execsh(char *args, char *cmd, Bufblock *buf, Envy *e, Shell *sh, Word *s…
126 {
127 char *p, **argv;
128 int tot, n, pid, in[2], out[2];
129
130 if(buf && pipe(out) < 0){
131 mkperror("pipe");
132 Exit();
133 }
134 pid = fork();
135 mypid = getpid();
136 if(pid < 0){
137 mkperror("mk fork");
138 Exit();
139 }
140 if(pid == 0){
141 if(buf)
142 close(out[0]);
143 if(pipe(in) < 0){
144 mkperror("pipe");
145 Exit();
146 }
147 pid = fork();
148 if(pid < 0){
149 mkperror("mk fork");
150 Exit();
151 }
152 if(pid != 0){
153 dup2(in[0], 0);
154 if(buf){
155 dup2(out[1], 1);
156 close(out[1]);
157 }
158 close(in[0]);
159 close(in[1]);
160 if (e)
161 exportenv(e, sh);
162 n = shargv(shellcmd, 1, &argv);
163 argv[n++] = args;
164 argv[n] = 0;
165 execvp(argv[0], argv);
166 mkperror(shell);
167 _exit(1);
168 }
169 close(out[1]);
170 close(in[0]);
171 if(DEBUG(D_EXEC))
172 fprint(1, "starting: %s\n", cmd);
173 p = cmd+strlen(cmd);
174 while(cmd < p){
175 n = write(in[1], cmd, p-cmd);
176 if(n < 0)
177 break;
178 cmd += n;
179 }
180 close(in[1]);
181 _exit(0);
182 }
183 if(buf){
184 close(out[1]);
185 tot = 0;
186 for(;;){
187 if (buf->current >= buf->end)
188 growbuf(buf);
189 n = read(out[0], buf->current, buf->end-buf->cur…
190 if(n <= 0)
191 break;
192 buf->current += n;
193 tot += n;
194 }
195 if (tot && buf->current[-1] == '\n')
196 buf->current--;
197 close(out[0]);
198 }
199 return pid;
200 }
201
202 int
203 pipecmd(char *cmd, Envy *e, int *fd, Shell *sh, Word *shellcmd)
204 {
205 int pid, pfd[2];
206 int n;
207 char **argv;
208
209 if(DEBUG(D_EXEC))
210 fprint(1, "pipecmd='%s'\n", cmd);/**/
211
212 if(fd && pipe(pfd) < 0){
213 mkperror("pipe");
214 Exit();
215 }
216 pid = fork();
217 if(pid < 0){
218 mkperror("mk fork");
219 Exit();
220 }
221 if(pid == 0){
222 if(fd){
223 close(pfd[0]);
224 dup2(pfd[1], 1);
225 close(pfd[1]);
226 }
227 if(e)
228 exportenv(e, sh);
229 n = shargv(shellcmd, 2, &argv);
230 argv[n++] = "-c";
231 argv[n++] = cmd;
232 argv[n] = 0;
233 execvp(argv[0], argv);
234 mkperror(shell);
235 _exit(1);
236 }
237 if(fd){
238 close(pfd[1]);
239 *fd = pfd[0];
240 }
241 return pid;
242 }
243
244 void
245 Exit(void)
246 {
247 while(wait(0) >= 0)
248 ;
249 exits("error");
250 }
251
252 static struct
253 {
254 int sig;
255 char *msg;
256 } sigmsgs[] =
257 {
258 SIGALRM, "alarm",
259 SIGFPE, "sys: fp: fptrap",
260 SIGPIPE, "sys: write on closed pipe",
261 SIGILL, "sys: trap: illegal instruction",
262 /* SIGSEGV, "sys: segmentation violation", */
263 0, 0
264 };
265
266 static void
267 notifyf(int sig)
268 {
269 int i;
270
271 for(i = 0; sigmsgs[i].msg; i++)
272 if(sigmsgs[i].sig == sig)
273 killchildren(sigmsgs[i].msg);
274
275 /* should never happen */
276 signal(sig, SIG_DFL);
277 kill(getpid(), sig);
278 }
279
280 void
281 catchnotes(void)
282 {
283 int i;
284
285 for(i = 0; sigmsgs[i].msg; i++)
286 signal(sigmsgs[i].sig, notifyf);
287 }
288
289 char*
290 maketmp(int *pfd)
291 {
292 static char temp[] = "/tmp/mkargXXXXXX";
293 static char buf[100];
294 int fd;
295
296 strcpy(buf, temp);
297 fd = mkstemp(buf);
298 if(fd < 0)
299 return 0;
300 *pfd = fd;
301 return buf;
302 }
303
304 int
305 chgtime(char *name)
306 {
307 if(access(name, 0) >= 0)
308 return utimes(name, 0);
309 return close(creat(name, 0666));
310 }
311
312 void
313 rcopy(char **to, Resub *match, int n)
314 {
315 int c;
316 char *p;
317
318 *to = match->s.sp; /* stem0 matches complete targ…
319 for(to++, match++; --n > 0; to++, match++){
320 if(match->s.sp && match->e.ep){
321 p = match->e.ep;
322 c = *p;
323 *p = 0;
324 *to = strdup(match->s.sp);
325 *p = c;
326 }
327 else
328 *to = 0;
329 }
330 }
331
332 unsigned long
333 mkmtime(char *name)
334 {
335 struct stat st;
336
337 if(stat(name, &st) < 0)
338 return 0;
339
340 return st.st_mtime;
341 }
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.