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