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