/* wait till none of the processes in the stack starting at k is live */ int waitstack(int k) { int npending, status, totstatus; int i; totstatus = 0; npending = 0; for(i=k ; i<nproc; ++i) if(! procstack[i].done) ++npending; enbint(SIG_IGN); if(dbgflag > 1) printf("waitstack(%d)\n", k); while(npending>0 && proclive>0) { if(waitproc(&status) >= k) --npending; totstatus |= status; } if(nproc > k) nproc = k; enbint(intrupt); return totstatus; }
static int doexec(char *str) { char *t, *tend; char **argv; char **p; int nargs; pid_t pid; while( *str==' ' || *str=='\t' ) ++str; if( *str == '\0' ) return(-1); /* no command */ nargs = 1; for(t = str ; *t ; ) { ++nargs; while(*t!=' ' && *t!='\t' && *t!='\0') ++t; if(*t) /* replace first white space with \0, skip rest */ for( *t++ = '\0' ; *t==' ' || *t=='\t' ; ++t) ; } /* now allocate args array, copy pointer to start of each string, then terminate array with a null */ p = argv = (char **) ckalloc(nargs*sizeof(char *)); tend = t; for(t = str ; t<tend ; ) { *p++ = t; while( *t ) ++t; do { ++t; } while(t<tend && (*t==' ' || *t=='\t') ); } *p = NULL; /*TEMP for(p=argv; *p; ++p)printf("arg=%s\n", *p);*/ if((pid = fork()) == 0) { enbint(SIG_DFL); doclose(); enbint(intrupt); execvp(str, argv); printf("\n"); fatal1("Cannot load %s",str); } free( (char *) argv); return pid; }
int dosys(char *comstring, int nohalt, int nowait, char *prefix) { int status; struct process *procp; /* make sure there is room in the process stack */ if(nproc >= MAXPROC) waitstack(MAXPROC-1); /* make sure fewer than proclimit processes are running */ while(proclive >= proclimit) { enbint(SIG_IGN); waitproc(&status); enbint(intrupt); } if(prefix) { fputs(prefix, stdout); fputs(comstring, stdout); } procp = procstack + nproc; procp->pid = (forceshell || metas(comstring) ) ? doshell(comstring,nohalt) : doexec(comstring); if(procp->pid == -1) fatal("fork failed"); procstack[nproc].nohalt = nohalt; procstack[nproc].nowait = nowait; procstack[nproc].done = NO; ++proclive; ++nproc; if(nowait) { printf(" &%d\n", procp->pid); fflush(stdout); return 0; } if(prefix) { putchar('\n'); fflush(stdout); } return waitstack(nproc-1); }
static int await(int wait_pid) { int w, status; enbint(SIG_IGN); while ( (w = wait(&status)) != wait_pid) if(w == -1) fatal1("bad wait code"); enbint(intrupt); if(status & 0377) { if(status != SIGINT) fprintf(diagfile, "Termination code %d", status); done(3); } return(status>>8); }
static int doshell(char *comstring, int nohalt) { pid_t pid; if((pid = fork()) == 0) { enbint(SIG_DFL); doclose(); execl(SHELLCOM, "sh", (nohalt ? "-c" : "-ce"), comstring, NULL); fatal("Couldn't load Shell"); } return pid; }
static int sys(char *str) { char *s, *t; char *argv[100], path[100]; char *inname, *outname; int append = 0; int wait_pid; int argc; if(debugflag) fprintf(diagfile, "%s\n", str); inname = NULL; outname = NULL; argv[0] = shellname; argc = 1; t = str; while( isspace((int)*t) ) ++t; while(*t) { if(*t == '<') inname = t+1; else if(*t == '>') { if(t[1] == '>') { append = YES; outname = t+2; } else { append = NO; outname = t+1; } } else argv[argc++] = t; while( !isspace((int)*t) && *t!='\0' ) ++t; if(*t) { *t++ = '\0'; while( isspace((int)*t) ) ++t; } } if(argc == 1) /* no command */ return(-1); argv[argc] = 0; s = path; t = "/usr/bin/"; while(*t) *s++ = *t++; for(t = argv[1] ; (*s++ = *t++) ; ) ; if((wait_pid = fork()) == 0) { if(inname) freopen(inname, "r", stdin); if(outname) freopen(outname, (append ? "a" : "w"), stdout); enbint(SIG_DFL); texec(path+9, argv); /* command */ texec(path+4, argv); /* /bin/command */ texec(path , argv); /* /usr/bin/command */ fatal1("Cannot load %s",path+9); } return( await(wait_pid) ); }
int main(int argc, char **argv) { int i, c, status; char *s; char fortfile[20], *t; char buff[100]; diagfile = stderr; sigivalue = (int) signal(SIGINT, SIG_IGN) & 01; sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01; enbint(intrupt); pid = getpid(); crfnames(); loadargs = (char **)calloc(1, (argc + 20) * sizeof(*loadargs)); if (!loadargs) fatal1("out of memory"); loadp = loadargs; --argc; ++argv; while(argc>0 && argv[0][0]=='-' && argv[0][1]!='\0') { for(s = argv[0]+1 ; *s ; ++s) switch(*s) { case 'T': /* use special passes */ switch(*++s) { case '1': fcom = s+1; goto endfor; case 'a': asmname = s+1; goto endfor; case 'l': ldname = s+1; goto endfor; case 'm': macroname = s+1; goto endfor; default: fatal1("bad option -T%c", *s); } break; case 'w': /* F66 warn or no warn */ addarg(ffary, &ffmax, s-1); break; case 'q': /* * Suppress printing of procedure names during * compilation. */ addarg(ffary, &ffmax, s-1); break; copyfflag: case 'u': case 'U': case 'M': case '1': case 'C': addarg(ffary, &ffmax, s-1); break; case 'O': optimflag = YES; addarg(ffary, &ffmax, s-1); break; case 'm': if(s[1] == '4') ++s; macroflag = YES; break; case 'S': saveasmflag = YES; case 'c': loadflag = NO; break; case 'v': verbose = YES; break; case 'd': debugflag = YES; goto copyfflag; case 'p': profileflag = YES; goto copyfflag; case 'o': if(!strcmp(s, "onetrip")) { addarg(ffary, &ffmax, s-1); goto endfor; } oflag = 1; aoutname = *++argv; --argc; break; case 'F': fortonly = YES; loadflag = NO; break; case 'I': if(s[1]=='2' || s[1]=='4' || s[1]=='s') goto copyfflag; fprintf(diagfile, "invalid flag -I%c\n", s[1]); done(1); case 'l': /* letter ell--library */ s[-1] = '-'; *loadp++ = s-1; goto endfor; case 'E': /* EFL flag argument */ while(( *eflagp++ = *++s)) ; *eflagp++ = ' '; goto endfor; case 'R': while(( *rflagp++ = *++s )) ; *rflagp++ = ' '; goto endfor; default: lflag[1] = *s; *loadp++ = copyn(strlen(lflag), lflag); break; } endfor: --argc; ++argv; } if (verbose) fprintf(stderr, xxxvers); if (argc == 0) errorx("No input files"); #ifdef mach_pdp11 if(nofloating) *loadp++ = (profileflag ? NOFLPROF : NOFLFOOT); else #endif for(i = 0 ; i<argc ; ++i) switch(c = dotchar(infname = argv[i]) ) { case 'r': /* Ratfor file */ case 'e': /* EFL file */ if( unreadable(argv[i]) ) break; s = fortfile; t = lastfield(argv[i]); while(( *s++ = *t++)) ; s[-2] = 'f'; if(macroflag) { snprintf(buff, sizeof(buff), "%s %s >%s", macroname, infname, prepfname); if(sys(buff)) { rmf(prepfname); break; } infname = prepfname; } if(c == 'e') snprintf(buff, sizeof(buff), "efl %s %s >%s", eflags, infname, fortfile); else snprintf(buff, sizeof(buff), "ratfor %s %s >%s", rflags, infname, fortfile); status = sys(buff); if(macroflag) rmf(infname); if(status) { loadflag = NO; rmf(fortfile); break; } if( ! fortonly ) { infname = argv[i] = lastfield(argv[i]); *lastchar(infname) = 'f'; if( dofort(argv[i]) ) loadflag = NO; else { if( nodup(t = setdoto(argv[i])) ) *loadp++ = t; rmf(fortfile); } } break; case 'f': /* Fortran file */ case 'F': if( unreadable(argv[i]) ) break; if( dofort(argv[i]) ) loadflag = NO; else if( nodup(t=setdoto(argv[i])) ) *loadp++ = t; break; case 'c': /* C file */ case 's': /* Assembler file */ if( unreadable(argv[i]) ) break; fprintf(diagfile, "%s:\n", argv[i]); snprintf(buff, sizeof(buff), "cc -c %s", argv[i]); if( sys(buff) ) loadflag = NO; else if( nodup(t = setdoto(argv[i])) ) *loadp++ = t; break; case 'o': if( nodup(argv[i]) ) *loadp++ = argv[i]; break; default: if( ! strcmp(argv[i], "-o") ) aoutname = argv[++i]; else *loadp++ = argv[i]; break; } if(loadflag) doload(loadargs, loadp); done(0); return 0; }