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