|
|
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.