|
|
1.1 root 1: /*
2: * sh/exec2.c
3: * Bourne shell.
4: * System part of execution.
5: */
6:
7: #include "sh.h"
8: #include <errno.h>
9: #include <sys/param.h>
10: #include <signal.h>
11: #include <sys/stat.h>
12:
13: /*
14: * Wait for the given process to complete.
15: */
16: waitc(pid)
17: int pid;
18: {
19: register int f;
20: unsigned s;
21: register int w, n;
22: int (*ssig)();
23:
24: if (pid < 0)
25: f = -pid;
26: else
27: f = pid;
28: if ((ssig=signal(SIGINT, SIG_IGN)) != SIG_IGN)
29: signal(SIGINT, sigintr);
30: for (;;) {
31: if ((w=wait(&s)) >= 0) {
32: if (n = (s&0177)) {
33: if (n==SIGINT)
34: sigintr(n);
35: else if (n==SIGPIPE && spipe
36: && (w >= spipe && w <= f))
37: ;
38: else {
39: if (w != f)
40: prints("%d: ", w);
41: if (n==SIGSYS && (s&0200)==0)
42: prints("exec failed");
43: else if (n>0 && n<=NSIG)
44: prints("%s", signame[n]);
45: else
46: prints("status %d", n);
47: if (s & 0200)
48: prints(" -- core dumped");
49: prints("\n");
50: }
51: s = 200 + n;
52: } else
53: s >>= 8;
54: if (w == f) {
55: slret = s;
56: break;
57: }
58: } else if (errno==EINTR) {
59: if (pid > 0)
60: continue;
61: else {
62: slret = 0;
63: break;
64: }
65: } else if (errno==ECHILD) {
66: if (pid == 0)
67: slret = 0;
68: else
69: slret = ECHILD;
70: break;
71: } else {
72: panic(6);
73: NOTREACHED;
74: }
75: }
76: signal(SIGINT, ssig);
77: return (slret);
78: }
79:
80: /*
81: * Make an imperfect copy of ourself.
82: */
83: clone()
84: {
85: register int f;
86: register SES *sp;
87:
88: if ((f=fork()) < 0) {
89: prints("Try again\n");
90: reset(RSYSER);
91: NOTREACHED;
92: } else if (f == 0) {
93: nllflag = 1;
94: sflag = iflag = cflag = no1flag = lgnflag = 0;
95: slret = spipe = 0;
96: sp = sesp;
97: sp->s_con->c_next = NULL;
98: while (sp) {
99: if (sp->s_type == SFILE)
100: fclose(sp->s_ifp);
101: sp = sp->s_next;
102: }
103: dflttrp(IFORK);
104: }
105: return (f);
106: }
107:
108: /*
109: * Open a pipe, panic on failure.
110: * Otherwise return as a clone.
111: */
112: pipeline(pv)
113: int *pv;
114: {
115: if (pipe(pv) < 0) {
116: prints("Pipe failed\n");
117: reset(RSYSER);
118: NOTREACHED;
119: }
120: return (clone());
121: }
122:
123: /*
124: * Try to execute a file in several ways.
125: * A return is always an error.
126: * Used by exec in inline.
127: */
128: flexec()
129: {
130: ffind(NULL);
131: while (ffind(vpath, *nargv, 1)) {
132: execve(strt, nargv, nenvp);
133: if (errno==ENOEXEC) {
134: scmdp = duplstr(strt, 0);
135: nargc += 1;
136: nargv -= 1;
137: nargv = vdupl(nargv);
138: nenvp = vdupl(nenvp);
139: while (sesp) {
140: freebuf(sesp->s_bpp);
141: sesp = sesp->s_next;
142: }
143: longjmp(restart, 1);
144: }
145: if (errno==E2BIG) {
146: e2big(nargv[0]);
147: return(-1);
148: }
149: }
150: ecantfind(nargv[0]);
151: return (-1);
152: }
153:
154: /*
155: * Process a redirection vector.
156: * Abort and return -1 at the first failure, return 0 for success.
157: */
158: redirect(iovp)
159: char **iovp;
160: {
161: register char **iopp;
162: register char *io;
163: register int op;
164: int u1, u2;
165:
166: for (iopp = iovp;(io = *iopp++)!=NULL; ) {
167: if (class(*io, MDIGI))
168: u1 = *io++ - '0';
169: else
170: u1 = *io=='<' ? 0 : 1;
171: for (op=0; ; io+=1)
172: if (*io=='>')
173: op += 1;
174: else if (*io=='<')
175: op -= 1;
176: else
177: break;
178: if (*io++ == '&') {
179: if (op != 1 && op != -1) {
180: panic(7);
181: NOTREACHED;
182: }
183: u2 = *io++;
184: if (u2 == '-') {
185: close(u1);
186: continue;
187: } else if (!class(u2, MDIGI)) {
188: eredir();
189: return (-1);
190: } else {
191: u2 -= '0';
192: dup2(u2, u1);
193: continue;
194: }
195: }
196: for (io-=1; *io==' '||*io=='\t'; io+=1);
197: switch (op) {
198: case -2: /* Unquoted here */
199: /* Fall through */
200: case -1: /* Input file, quoted here */
201: if ((u2 = open(io, 0)) < 0) {
202: ecantopen(io);
203: return (-1);
204: }
205: if (op == -2 && (u2 = evalhere(u2)) < 0)
206: return (-1);
207: dup2(u2, u1);
208: close(u2);
209: continue;
210: case 2: /* Append to output */
211: if ((u2 = open(io, 1)) >= 0) {
212: lseek(u2, 0L, 2);
213: dup2(u2, u1);
214: close(u2);
215: continue;
216: } /* else fall through */
217: case 1: /* Output file */
218: if ((u2 = creat(io, 0666)) < 0) {
219: ecantmake(io);
220: return (-1);
221: }
222: dup2(u2, u1);
223: close(u2);
224: continue;
225: default:
226: panic(8);
227: NOTREACHED;
228: }
229: }
230: return (0);
231: }
232:
233: #ifdef NAMEPIPE
234: /*
235: * Create a named pipe.
236: */
237: npipe(np)
238: register NODE *np;
239: {
240: register char *tmp;
241: register int f;
242: char *tvec[2];
243:
244: tmp = shtmp();
245: mknod(tmp, S_IFPIP, 0);
246: if ((f = clone()) == 0) {
247: if (np->n_type==NRPIPE)
248: strt[0] = '<';
249: else
250: strt[0] = '>';
251: strt[1] = '\0';
252: tvec[0] = strcat(strt, tmp);
253: tvec[1] = NULL;
254: redirect(tvec);
255: command(np->n_auxp);
256: exit(slret);
257: NOTREACHED;
258: }
259: cleanup(0, tmp);
260: strcpy(strt, tmp);
261: return;
262: }
263: #endif
264:
265: /*
266: * Search a path, perhaps repeatedly, for a file with access mode.
267: * Is called with paths == NULL to reset pointers.
268: * UGLY, but it works.
269: */
270: ffind(paths, file, mode)
271: char *paths, *file;
272: {
273: register char c, *cp1, *cp2;
274: static char *fp, *ff, *fcp;
275:
276: if (paths==NULL) {
277: fp = ff = fcp = NULL;
278: return (0);
279: }
280: if (ff!=file) {
281: fp = fcp = paths;
282: ff = file;
283: if (index(ff, '/')!=NULL)
284: fcp = "";
285: }
286: for (c=':'; c==':'; ) {
287: cp1 = fcp;
288: cp2 = strt;
289: while (*cp1 && *cp1!=':')
290: *cp2++ = *cp1++;
291: if (cp2 != strt)
292: *cp2++ = '/';
293: c = *cp1++;
294: fcp = cp1;
295: cp1 = ff;
296: while (*cp2++ = *cp1++);
297: if (access(strt, mode)>=0)
298: return (1);
299: }
300: return (0);
301: }
302:
303: /*
304: * execute a non standard shell.
305: */
306: exshell(vp) VAR *vp;
307: {
308: char *vshell;
309: register char *p;
310:
311: vshell = vp->v_strp;
312: while (*vshell && *vshell++ != '=');
313: /* Construct -name argv[0] */
314: if ((p = rindex(vshell, '/')) != NULL)
315: p += 1;
316: else
317: p = vshell;
318: strcpy(strt, "-");
319: strcat(strt, p);
320: /* Construct argv */
321: nargv = makargl();
322: nargv = addargl(nargv, "sh");
323: nargv = addargl(nargv, duplstr(strt, 0));
324: nargc = 2;
325: /* Construct envp */
326: nenvp = makargl();
327: nenvp = envlvar(nenvp);
328: /* Try exec */
329: execve(vshell, nargv+1, nenvp);
330:
331: if (errno==ENOEXEC) {
332: fakearg(1, nargc, nargv, nenvp);
333: sargc = 0;
334: sargp = nargv+2;
335: sarg0 = nargv[1];
336: nllflag = 0;
337: return session(SFILE, vshell);
338: }
339: fprintf(stderr, "No shell: %s\n", vshell);
340: exit(1);
341: }
342:
343: /*
344: * Check to see if we have mail.
345: */
346: checkmail()
347: {
348: static long mailsize = -1;
349: struct stat sbuf;
350:
351: if (*vmail == '\0')
352: return;
353: if (stat(vmail, &sbuf)<0) {
354: mailsize = 0;
355: } else {
356: if (sbuf.st_size != 0
357: && sbuf.st_size > mailsize) {
358: if (mailsize == -1)
359: prints("You have mail.\n");
360: else
361: prints("You have new mail.\n");
362: }
363: mailsize = sbuf.st_size;
364: }
365: }
366:
367: /* end of sh/exec2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.