|
|
1.1 root 1: static char *sccsid = "@(#)dosys.c 8th Edition (Bell Labs) 85/10/28";
2: #include "defs"
3: #include <signal.h>
4: #include <wait.h>
5: #include <errno.h>
6: int intrupt();
7: extern int errno;
8:
9: #ifdef VERSION8
10: # define FORK fork
11: #else
12: # define FORK vfork
13: #endif
14:
15: dosys(comstring, nohalt, nowait, prefix)
16: register char *comstring;
17: int nohalt;
18: int nowait;
19: char *prefix;
20: {
21: int status;
22: register struct process *procp;
23:
24: /* make sure there is room in the process stack */
25: if(nproc >= MAXPROC)
26: waitstack(MAXPROC-1);
27:
28: /* make sure fewer than proclimit processes are running */
29: while(proclive >= proclimit)
30: {
31: enbint(SIG_IGN);
32: waitproc(&status);
33: enbint(intrupt);
34: }
35:
36: if(prefix)
37: {
38: fputs(prefix, stdout);
39: fputs(comstring, stdout);
40: }
41:
42: procp = procstack + nproc;
43: procp->pid = (forceshell || metas(comstring) ) ?
44: doshell(comstring,nohalt) : doexec(comstring);
45: procstack[nproc].nohalt = nohalt;
46: procstack[nproc].nowait = nowait;
47: procstack[nproc].done = NO;
48: ++proclive;
49: ++nproc;
50:
51: if(nowait)
52: {
53: printf(" &%d\n", procp->pid);
54: fflush(stdout);
55: return 0;
56: }
57: if(prefix)
58: {
59: putchar('\n');
60: fflush(stdout);
61: }
62: return waitstack(nproc-1);
63: }
64:
65: metas(s) /* Are there are any Shell meta-characters? */
66: register char *s;
67: {
68: register char c;
69:
70: while( (funny[c = *s++] & META) == 0 )
71: ;
72: return( c );
73: }
74:
75:
76:
77:
78: doclose() /* Close open directory files before exec'ing */
79: {
80: register struct dirhd *od;
81:
82: for (od = firstod; od; od = od->nxtdirhd)
83: if(od->dirfc)
84: closedir(od->dirfc);
85: }
86:
87: /* wait till none of the processes in the stack starting at k is live */
88: int waitstack(k)
89: int k;
90: {
91: int npending, status, totstatus;
92: register int i;
93:
94: totstatus = 0;
95: npending = 0;
96: for(i=k ; i<nproc; ++i)
97: if(! procstack[i].done)
98: ++npending;
99: enbint(SIG_IGN);
100: if(dbgflag > 1)
101: printf("waitstack(%d)\n", k);
102:
103: while(npending>0 && proclive>0)
104: {
105: if(waitproc(&status) >= k)
106: --npending;
107: totstatus |= status;
108: }
109:
110: if(nproc > k)
111: nproc = k;
112: enbint(intrupt);
113: return totstatus;
114: }
115:
116: waitproc(statp)
117: int *statp;
118: {
119: int pid;
120: union wait status;
121: register int i;
122: register struct process *procp;
123: char junk[50];
124: static int inwait = NO;
125:
126: if(inwait) /* avoid infinite recursions on errors */
127: return MAXPROC;
128: inwait = YES;
129:
130: pid = wait(&status);
131: if(dbgflag > 1)
132: fprintf(stderr, "process %d done, status = %d\n", pid, status.w_status);
133: if(pid == -1)
134: {
135: if(errno == ECHILD) /* multiple deaths, no problem */
136: {
137: if(proclive)
138: {
139: for(i=0, procp=procstack; i<nproc; ++i, ++procp)
140: procp->done = YES;
141: proclive = nproc = 0;
142: }
143: return MAXPROC;
144: }
145: fatal("bad wait code");
146: }
147: for(i=0, procp=procstack; i<nproc; ++i, ++procp)
148: if(procp->pid == pid)
149: {
150: --proclive;
151: procp->done = YES;
152:
153: if(status.w_status)
154: {
155: if(procp->nowait)
156: printf("%d: ", pid);
157: if( status.w_T.w_Retcode )
158: printf("*** Error code %d", status.w_T.w_Retcode );
159: else printf("*** Termination code %d", status.w_T.w_Termsig);
160:
161: printf(procp->nohalt ? "(ignored)\n" : "\n");
162: fflush(stdout);
163: if(!keepgoing && !procp->nohalt)
164: fatal(CHNULL);
165: }
166: *statp = status.w_status;
167: inwait = NO;
168: return i;
169: }
170:
171: sprintf(junk, "spurious return from process %d", pid);
172: fatal(junk);
173: /*NOTREACHED*/
174: }
175:
176: doshell(comstring,nohalt)
177: char *comstring;
178: int nohalt;
179: {
180: int pid;
181: #ifdef SHELLENV
182: char *getenv(), *rindex();
183: char *shellcom = getenv("SHELL");
184: char *shellstr;
185: #endif
186:
187: if((pid = FORK()) == 0)
188: {
189: enbint(SIG_DFL);
190: doclose();
191:
192: #ifdef SHELLENV
193: if (shellcom == 0) shellcom = SHELLCOM;
194: shellstr = rindex(shellcom, '/') + 1;
195: execl(shellcom, shellstr, (nohalt ? "-c" : "-ce"), comstring, 0);
196: #else
197: execl(SHELLCOM, "sh", (nohalt ? "-c" : "-ce"), comstring, 0);
198: #endif
199: fatal("Couldn't load Shell");
200: }
201:
202: return pid;
203: }
204:
205: doexec(str)
206: register char *str;
207: {
208: register char *t, *tend;
209: char **argv;
210: register char **p;
211: int nargs;
212: int pid;
213:
214: while( *str==' ' || *str=='\t' )
215: ++str;
216: if( *str == '\0' )
217: return(-1); /* no command */
218:
219: nargs = 1;
220: for(t = str ; *t ; )
221: {
222: ++nargs;
223: while(*t!=' ' && *t!='\t' && *t!='\0')
224: ++t;
225: if(*t) /* replace first white space with \0, skip rest */
226: for( *t++ = '\0' ; *t==' ' || *t=='\t' ; ++t)
227: ;
228: }
229:
230: /* now allocate args array, copy pointer to start of each string,
231: then terminate array with a null
232: */
233: p = argv = (char **) ckalloc(nargs*sizeof(char *));
234: tend = t;
235: for(t = str ; t<tend ; )
236: {
237: *p++ = t;
238: while( *t )
239: ++t;
240: do {
241: ++t;
242: } while(t<tend && (*t==' ' || *t=='\t') );
243: }
244: *p = NULL;
245: /*TEMP for(p=argv; *p; ++p)printf("arg=%s\n", *p); */
246:
247: if((pid = FORK()) == 0)
248: {
249: enbint(SIG_DFL);
250: doclose();
251: enbint(intrupt);
252: execvp(str, argv);
253: printf("\n");
254: fatal1("Cannot load %s",str);
255: }
256:
257: free( (char *) argv);
258: return pid;
259: }
260:
261: #include <sys/types.h>
262: #include <sys/stat.h>
263:
264:
265:
266:
267: touch(force, name)
268: int force;
269: char *name;
270: {
271: struct stat stbuff;
272: char junk[1];
273: int fd;
274:
275: if( stat(name,&stbuff) < 0)
276: if(force)
277: goto create;
278: else
279: {
280: fprintf(stderr, "touch: file %s does not exist.\n", name);
281: return;
282: }
283:
284: if(stbuff.st_size == 0)
285: goto create;
286:
287: if( (fd = open(name, 2)) < 0)
288: goto bad;
289:
290: if( read(fd, junk, 1) < 1)
291: {
292: close(fd);
293: goto bad;
294: }
295: lseek(fd, 0L, 0);
296: if( write(fd, junk, 1) < 1 )
297: {
298: close(fd);
299: goto bad;
300: }
301: close(fd);
302: return;
303:
304: bad:
305: fprintf(stderr, "Cannot touch %s\n", name);
306: return;
307:
308: create:
309: if( (fd = creat(name, 0666)) < 0)
310: goto bad;
311: close(fd);
312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.