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