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