13e12c5d1SDavid du Colombier #include "mk.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier typedef struct Event 43e12c5d1SDavid du Colombier { 53e12c5d1SDavid du Colombier int pid; 63e12c5d1SDavid du Colombier Job *job; 73e12c5d1SDavid du Colombier } Event; 83e12c5d1SDavid du Colombier static Event *events; 93e12c5d1SDavid du Colombier static int nevents, nrunning; 103e12c5d1SDavid du Colombier typedef struct Process 113e12c5d1SDavid du Colombier { 123e12c5d1SDavid du Colombier int pid; 133e12c5d1SDavid du Colombier int status; 143e12c5d1SDavid du Colombier struct Process *b, *f; 153e12c5d1SDavid du Colombier } Process; 163e12c5d1SDavid du Colombier static Process *phead, *pfree; 173e12c5d1SDavid du Colombier static void sched(void); 183e12c5d1SDavid du Colombier static void pnew(int, int), pdelete(Process *); 193e12c5d1SDavid du Colombier static Envy *envy; 203e12c5d1SDavid du Colombier static int special; 213e12c5d1SDavid du Colombier #define ENVQUANTA 10 223e12c5d1SDavid du Colombier static int envsize; 233e12c5d1SDavid du Colombier static int nextv; 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier static int pidslot(int); 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier int 283e12c5d1SDavid du Colombier Execl(char *p, char *a, ...) 293e12c5d1SDavid du Colombier { 303e12c5d1SDavid du Colombier if (envy) 31*219b2ee8SDavid du Colombier exportenv(envy, nextv); 323e12c5d1SDavid du Colombier exec(p, &a); 333e12c5d1SDavid du Colombier return -1; 343e12c5d1SDavid du Colombier } 353e12c5d1SDavid du Colombier 363e12c5d1SDavid du Colombier void 373e12c5d1SDavid du Colombier run(Job *j) 383e12c5d1SDavid du Colombier { 393e12c5d1SDavid du Colombier Job *jj; 403e12c5d1SDavid du Colombier 413e12c5d1SDavid du Colombier if(jobs){ 423e12c5d1SDavid du Colombier for(jj = jobs; jj->next; jj = jj->next) 433e12c5d1SDavid du Colombier ; 443e12c5d1SDavid du Colombier jj->next = j; 453e12c5d1SDavid du Colombier } else 463e12c5d1SDavid du Colombier jobs = j; 473e12c5d1SDavid du Colombier j->next = 0; 483e12c5d1SDavid du Colombier /* this code also in waitup after parse redirect */ 493e12c5d1SDavid du Colombier if(nrunning < nproclimit) 503e12c5d1SDavid du Colombier sched(); 513e12c5d1SDavid du Colombier } 523e12c5d1SDavid du Colombier 533e12c5d1SDavid du Colombier static void 543e12c5d1SDavid du Colombier sched(void) 553e12c5d1SDavid du Colombier { 563e12c5d1SDavid du Colombier Job *j; 573e12c5d1SDavid du Colombier Bufblock *buf; 583e12c5d1SDavid du Colombier int slot, pip[2], pid; 593e12c5d1SDavid du Colombier Node *n; 603e12c5d1SDavid du Colombier 613e12c5d1SDavid du Colombier if(jobs == 0){ 62*219b2ee8SDavid du Colombier usage(); 633e12c5d1SDavid du Colombier return; 643e12c5d1SDavid du Colombier } 653e12c5d1SDavid du Colombier j = jobs; 663e12c5d1SDavid du Colombier jobs = j->next; 673e12c5d1SDavid du Colombier if(DEBUG(D_EXEC)) 683e12c5d1SDavid du Colombier fprint(1, "firing up job for target %s\n", wtos(j->t)); 693e12c5d1SDavid du Colombier slot = nextslot(); 703e12c5d1SDavid du Colombier events[slot].job = j; 713e12c5d1SDavid du Colombier dovars(j, slot); 723e12c5d1SDavid du Colombier buf = newbuf(); 733e12c5d1SDavid du Colombier shprint(j->r->recipe, envy, buf); 743e12c5d1SDavid du Colombier if(!tflag && (nflag || !(j->r->attr&QUIET))) 753e12c5d1SDavid du Colombier Bwrite(&stdout, buf->start, (long)strlen(buf->start)); 763e12c5d1SDavid du Colombier freebuf(buf); 773e12c5d1SDavid du Colombier if(nflag||tflag){ 783e12c5d1SDavid du Colombier for(n = j->n; n; n = n->next){ 793e12c5d1SDavid du Colombier if(tflag){ 803e12c5d1SDavid du Colombier if(!(n->flags&VIRTUAL)) 813e12c5d1SDavid du Colombier touch(n->name); 823e12c5d1SDavid du Colombier else if(explain) 833e12c5d1SDavid du Colombier Bprint(&stdout, "no touch of virtual '%s'\n", n->name); 843e12c5d1SDavid du Colombier } 853e12c5d1SDavid du Colombier n->time = time((long *)0); 863e12c5d1SDavid du Colombier MADESET(n, MADE); 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier } else { 893e12c5d1SDavid du Colombier /*Bprint(&stdout, "recipe='%s'\n", j->r->recipe);/**/ 903e12c5d1SDavid du Colombier Bflush(&stdout); 913e12c5d1SDavid du Colombier if(j->r->attr&RED){ 923e12c5d1SDavid du Colombier if(pipe(pip) < 0){ 933e12c5d1SDavid du Colombier perror("pipe"); 943e12c5d1SDavid du Colombier Exit(); 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier if((pid = rfork(RFPROC|RFFDG|RFENVG)) < 0){ 983e12c5d1SDavid du Colombier perror("mk rfork"); 993e12c5d1SDavid du Colombier Exit(); 1003e12c5d1SDavid du Colombier } 1013e12c5d1SDavid du Colombier if(pid == 0){ 1023e12c5d1SDavid du Colombier if(j->r->attr&RED){ 1033e12c5d1SDavid du Colombier close(pip[0]); 104*219b2ee8SDavid du Colombier dup(pip[1], 1); 1053e12c5d1SDavid du Colombier close(pip[1]); 1063e12c5d1SDavid du Colombier } 1073e12c5d1SDavid du Colombier if(pipe(pip) < 0){ 1083e12c5d1SDavid du Colombier perror("pipe-i"); 1093e12c5d1SDavid du Colombier Exit(); 1103e12c5d1SDavid du Colombier } 1113e12c5d1SDavid du Colombier if((pid = fork()) < 0){ 1123e12c5d1SDavid du Colombier perror("mk fork"); 1133e12c5d1SDavid du Colombier Exit(); 1143e12c5d1SDavid du Colombier } 1153e12c5d1SDavid du Colombier if(pid != 0){ 1163e12c5d1SDavid du Colombier close(pip[1]); 117*219b2ee8SDavid du Colombier dup(pip[0], 0); 1183e12c5d1SDavid du Colombier close(pip[0]); 1193e12c5d1SDavid du Colombier if(j->r->attr&NOMINUSE) 1203e12c5d1SDavid du Colombier 1213e12c5d1SDavid du Colombier Execl(shell, shellname, "-I", (char *)0); 1223e12c5d1SDavid du Colombier else 1233e12c5d1SDavid du Colombier Execl(shell, shellname, "-eI", (char *)0); 1243e12c5d1SDavid du Colombier perror(shell); 125*219b2ee8SDavid du Colombier _exits("exec"); 1263e12c5d1SDavid du Colombier } else { 1273e12c5d1SDavid du Colombier int k; 1283e12c5d1SDavid du Colombier char *s, *send; 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier close(pip[0]); 1313e12c5d1SDavid du Colombier s = j->r->recipe; 1323e12c5d1SDavid du Colombier send = s+strlen(s); 1333e12c5d1SDavid du Colombier while(s < send){ 1343e12c5d1SDavid du Colombier if((k = write(pip[1], s, send-s)) < 0) 1353e12c5d1SDavid du Colombier break; 1363e12c5d1SDavid du Colombier s += k; 1373e12c5d1SDavid du Colombier } 138*219b2ee8SDavid du Colombier _exits(0); 1393e12c5d1SDavid du Colombier } 1403e12c5d1SDavid du Colombier } 141*219b2ee8SDavid du Colombier usage(); 1423e12c5d1SDavid du Colombier nrunning++; 1433e12c5d1SDavid du Colombier if(j->r->attr&RED) 1443e12c5d1SDavid du Colombier close(pip[1]), j->fd = pip[0]; 1453e12c5d1SDavid du Colombier else 1463e12c5d1SDavid du Colombier j->fd = -1; 1473e12c5d1SDavid du Colombier if(DEBUG(D_EXEC)) 1483e12c5d1SDavid du Colombier fprint(1, "pid for target %s = %d\n", wtos(j->t), pid); 1493e12c5d1SDavid du Colombier events[slot].pid = pid; 1503e12c5d1SDavid du Colombier } 1513e12c5d1SDavid du Colombier } 1523e12c5d1SDavid du Colombier 1533e12c5d1SDavid du Colombier int 1543e12c5d1SDavid du Colombier waitup(int echildok, int *retstatus) 1553e12c5d1SDavid du Colombier { 1563e12c5d1SDavid du Colombier int pid; 1573e12c5d1SDavid du Colombier int slot; 1583e12c5d1SDavid du Colombier Symtab *s; 1593e12c5d1SDavid du Colombier Word *w; 1603e12c5d1SDavid du Colombier Job *j; 161*219b2ee8SDavid du Colombier char buf[ERRLEN]; 1623e12c5d1SDavid du Colombier Bufblock *bp; 1633e12c5d1SDavid du Colombier int uarg = 0; 1643e12c5d1SDavid du Colombier int done; 1653e12c5d1SDavid du Colombier Node *n; 1663e12c5d1SDavid du Colombier Process *p; 167*219b2ee8SDavid du Colombier extern int runerrs; 1683e12c5d1SDavid du Colombier 1693e12c5d1SDavid du Colombier /* first check against the proces slist */ 1703e12c5d1SDavid du Colombier if(retstatus) 1713e12c5d1SDavid du Colombier for(p = phead; p; p = p->f) 1723e12c5d1SDavid du Colombier if(p->pid == *retstatus){ 1733e12c5d1SDavid du Colombier *retstatus = p->status; 1743e12c5d1SDavid du Colombier pdelete(p); 1753e12c5d1SDavid du Colombier return(-1); 1763e12c5d1SDavid du Colombier } 1773e12c5d1SDavid du Colombier again: /* rogue processes */ 178*219b2ee8SDavid du Colombier if((pid = waitfor(buf)) < 0){ 1793e12c5d1SDavid du Colombier if(echildok > 0) 1803e12c5d1SDavid du Colombier return(1); 1813e12c5d1SDavid du Colombier else { 1823e12c5d1SDavid du Colombier fprint(2, "mk: (waitup %d) ", echildok); 1833e12c5d1SDavid du Colombier perror("mk wait"); 1843e12c5d1SDavid du Colombier Exit(); 1853e12c5d1SDavid du Colombier } 1863e12c5d1SDavid du Colombier } 1873e12c5d1SDavid du Colombier if(DEBUG(D_EXEC)) 188*219b2ee8SDavid du Colombier fprint(1, "waitup got pid=%d, status=%s\n", pid, buf); 1893e12c5d1SDavid du Colombier if(retstatus && (pid == *retstatus)){ 190*219b2ee8SDavid du Colombier *retstatus = buf[0]? 1:0; 1913e12c5d1SDavid du Colombier return(-1); 1923e12c5d1SDavid du Colombier } 1933e12c5d1SDavid du Colombier slot = pidslot(pid); 1943e12c5d1SDavid du Colombier if(slot < 0){ 1953e12c5d1SDavid du Colombier if(DEBUG(D_EXEC)) 1963e12c5d1SDavid du Colombier fprint(2, "mk: wait returned unexpected process %d\n", pid); 197*219b2ee8SDavid du Colombier pnew(pid, buf[0]? 1:0); 1983e12c5d1SDavid du Colombier goto again; 1993e12c5d1SDavid du Colombier } 2003e12c5d1SDavid du Colombier j = events[slot].job; 201*219b2ee8SDavid du Colombier usage(); 2023e12c5d1SDavid du Colombier nrunning--; 2033e12c5d1SDavid du Colombier events[slot].pid = -1; 204*219b2ee8SDavid du Colombier if(buf[0]){ 2053e12c5d1SDavid du Colombier dovars(j, slot); 2063e12c5d1SDavid du Colombier bp = newbuf(); 2073e12c5d1SDavid du Colombier shprint(j->r->recipe, envy, bp); 2083e12c5d1SDavid du Colombier front(bp->start); 209*219b2ee8SDavid du Colombier fprint(2, "mk: %s: exit status=%s", bp->start, buf); 2103e12c5d1SDavid du Colombier freebuf(bp); 2113e12c5d1SDavid du Colombier for(n = j->n, done = 0; n; n = n->next) 2123e12c5d1SDavid du Colombier if(n->flags&DELETE){ 2133e12c5d1SDavid du Colombier if(done++ == 0) 2143e12c5d1SDavid du Colombier fprint(2, ", deleting"); 2153e12c5d1SDavid du Colombier fprint(2, " '%s'", n->name); 2163e12c5d1SDavid du Colombier } 2173e12c5d1SDavid du Colombier fprint(2, "\n"); 2183e12c5d1SDavid du Colombier for(n = j->n, done = 0; n; n = n->next) 2193e12c5d1SDavid du Colombier if(n->flags&DELETE){ 2203e12c5d1SDavid du Colombier if(done++ == 0) 2213e12c5d1SDavid du Colombier /*Fflush(2)*/; 2223e12c5d1SDavid du Colombier delete(n->name); 2233e12c5d1SDavid du Colombier } 2243e12c5d1SDavid du Colombier if(kflag){ 2253e12c5d1SDavid du Colombier runerrs++; 2263e12c5d1SDavid du Colombier uarg = 1; 2273e12c5d1SDavid du Colombier } else { 2283e12c5d1SDavid du Colombier jobs = 0; 2293e12c5d1SDavid du Colombier Exit(); 2303e12c5d1SDavid du Colombier } 2313e12c5d1SDavid du Colombier } 2323e12c5d1SDavid du Colombier if(j->fd >= 0){ 2333e12c5d1SDavid du Colombier sprint(buf, "process %d", pid); 2343e12c5d1SDavid du Colombier parse(buf, j->fd, 0, 0); 2353e12c5d1SDavid du Colombier execinit(); /* reread environ */ 2363e12c5d1SDavid du Colombier nproc(); 2373e12c5d1SDavid du Colombier while(jobs && (nrunning < nproclimit)) 2383e12c5d1SDavid du Colombier sched(); 2393e12c5d1SDavid du Colombier } 2403e12c5d1SDavid du Colombier for(w = j->t; w; w = w->next){ 2413e12c5d1SDavid du Colombier if((s = symlook(w->s, S_NODE, (char *)0)) == 0) 2423e12c5d1SDavid du Colombier continue; /* not interested in this node */ 2433e12c5d1SDavid du Colombier update(uarg, (Node *)s->value); 2443e12c5d1SDavid du Colombier } 2453e12c5d1SDavid du Colombier if(nrunning < nproclimit) 2463e12c5d1SDavid du Colombier sched(); 2473e12c5d1SDavid du Colombier return(0); 2483e12c5d1SDavid du Colombier } 2493e12c5d1SDavid du Colombier 2503e12c5d1SDavid du Colombier enum { 2513e12c5d1SDavid du Colombier TARGET, 2523e12c5d1SDavid du Colombier STEM, 2533e12c5d1SDavid du Colombier PREREQ, 2543e12c5d1SDavid du Colombier PID, 2553e12c5d1SDavid du Colombier NPROC, 2563e12c5d1SDavid du Colombier NEWPREREQ, 2573e12c5d1SDavid du Colombier ALLTARGET, 2583e12c5d1SDavid du Colombier STEM0, 2593e12c5d1SDavid du Colombier STEM1, 2603e12c5d1SDavid du Colombier STEM2, 2613e12c5d1SDavid du Colombier STEM3, 2623e12c5d1SDavid du Colombier STEM4, 2633e12c5d1SDavid du Colombier STEM5, 2643e12c5d1SDavid du Colombier STEM6, 2653e12c5d1SDavid du Colombier STEM7, 2663e12c5d1SDavid du Colombier STEM8, 2673e12c5d1SDavid du Colombier STEM9, 2683e12c5d1SDavid du Colombier }; 2693e12c5d1SDavid du Colombier 2703e12c5d1SDavid du Colombier struct Myenv { 2713e12c5d1SDavid du Colombier char *name; 2723e12c5d1SDavid du Colombier Word w; 2733e12c5d1SDavid du Colombier } myenv[] = 2743e12c5d1SDavid du Colombier { 2753e12c5d1SDavid du Colombier [TARGET] "target", {"",0}, /* really sleazy */ 2763e12c5d1SDavid du Colombier [STEM] "stem", {"",0}, 2773e12c5d1SDavid du Colombier [PREREQ] "prereq", {"",0}, 2783e12c5d1SDavid du Colombier [PID] "pid", {"",0}, 2793e12c5d1SDavid du Colombier [NPROC] "nproc", {"",0}, 2803e12c5d1SDavid du Colombier [NEWPREREQ] "newprereq", {"",0}, 2813e12c5d1SDavid du Colombier [ALLTARGET] "alltarget", {"",0}, 2823e12c5d1SDavid du Colombier [STEM0] "stem0", {"",0}, /* retain order of rest */ 2833e12c5d1SDavid du Colombier [STEM1] "stem1", {"",0}, 2843e12c5d1SDavid du Colombier [STEM2] "stem2", {"",0}, 2853e12c5d1SDavid du Colombier [STEM3] "stem3", {"",0}, 2863e12c5d1SDavid du Colombier [STEM4] "stem4", {"",0}, 2873e12c5d1SDavid du Colombier [STEM5] "stem5", {"",0}, 2883e12c5d1SDavid du Colombier [STEM6] "stem6", {"",0}, 2893e12c5d1SDavid du Colombier [STEM7] "stem7", {"",0}, 2903e12c5d1SDavid du Colombier [STEM8] "stem8", {"",0}, 2913e12c5d1SDavid du Colombier [STEM9] "stem9", {"",0}, 2923e12c5d1SDavid du Colombier 0, {0,0}, 2933e12c5d1SDavid du Colombier }; 2943e12c5d1SDavid du Colombier 2953e12c5d1SDavid du Colombier void 2963e12c5d1SDavid du Colombier execinit(void) 2973e12c5d1SDavid du Colombier { 2983e12c5d1SDavid du Colombier struct Myenv *mp; 2993e12c5d1SDavid du Colombier 3003e12c5d1SDavid du Colombier nextv = 0; /* fill env from beginning */ 3013e12c5d1SDavid du Colombier vardump(); 3023e12c5d1SDavid du Colombier special = nextv-1; /* pointer to last original env*/ 3033e12c5d1SDavid du Colombier for (mp = myenv; mp->name; mp++) 3043e12c5d1SDavid du Colombier symlook(mp->name, S_WESET, ""); 3053e12c5d1SDavid du Colombier } 3063e12c5d1SDavid du Colombier 3073e12c5d1SDavid du Colombier int 3083e12c5d1SDavid du Colombier internalvar(char *name, Word *w) 3093e12c5d1SDavid du Colombier { 3103e12c5d1SDavid du Colombier struct Myenv *mp; 3113e12c5d1SDavid du Colombier 3123e12c5d1SDavid du Colombier for (mp = myenv; mp->name; mp++) 3133e12c5d1SDavid du Colombier if (strcmp(name, mp->name) == 0) { 3143e12c5d1SDavid du Colombier mp->w.s = w->s; 3153e12c5d1SDavid du Colombier mp->w.next = w->next; 3163e12c5d1SDavid du Colombier return 1; 3173e12c5d1SDavid du Colombier } 3183e12c5d1SDavid du Colombier return 0; 3193e12c5d1SDavid du Colombier } 3203e12c5d1SDavid du Colombier 3213e12c5d1SDavid du Colombier void 3223e12c5d1SDavid du Colombier dovars(Job *j, int slot) 3233e12c5d1SDavid du Colombier { 3243e12c5d1SDavid du Colombier int c; 3253e12c5d1SDavid du Colombier char *s; 3263e12c5d1SDavid du Colombier struct Myenv *mp; 3273e12c5d1SDavid du Colombier int i; 3283e12c5d1SDavid du Colombier char buf[20]; 3293e12c5d1SDavid du Colombier 3303e12c5d1SDavid du Colombier nextv = special; 3313e12c5d1SDavid du Colombier envinsert(myenv[TARGET].name, j->t); 3323e12c5d1SDavid du Colombier envinsert(myenv[STEM].name, &myenv[STEM].w); 3333e12c5d1SDavid du Colombier if(j->r->attr®EXP) { /* memory leak */ 3343e12c5d1SDavid du Colombier if (j->match[1].sp && j->match[1].ep) { 3353e12c5d1SDavid du Colombier s = j->match[1].ep+1; 3363e12c5d1SDavid du Colombier c = *s; 337*219b2ee8SDavid du Colombier *s = 0; 3383e12c5d1SDavid du Colombier myenv[STEM].w.s = strdup(j->match[1].sp); 3393e12c5d1SDavid du Colombier *s = c; 3403e12c5d1SDavid du Colombier } else 3413e12c5d1SDavid du Colombier myenv[STEM].w.s = ""; 3423e12c5d1SDavid du Colombier } else 3433e12c5d1SDavid du Colombier myenv[STEM].w.s = j->stem; 3443e12c5d1SDavid du Colombier envinsert(myenv[PREREQ].name, j->p); 3453e12c5d1SDavid du Colombier sprint(buf, "%d", getpid()); 3463e12c5d1SDavid du Colombier myenv[PID].w.s = strdup(buf); /* memory leak */ 3473e12c5d1SDavid du Colombier envinsert(myenv[PID].name, &myenv[PID].w); 3483e12c5d1SDavid du Colombier sprint(buf, "%d", slot); 3493e12c5d1SDavid du Colombier myenv[NPROC].w.s = strdup(buf); /* memory leak */ 3503e12c5d1SDavid du Colombier envinsert(myenv[NPROC].name, &myenv[NPROC].w); 3513e12c5d1SDavid du Colombier envinsert(myenv[NEWPREREQ].name, j->np); 3523e12c5d1SDavid du Colombier envinsert(myenv[ALLTARGET].name, j->at); 3533e12c5d1SDavid du Colombier mp = &myenv[STEM0]; /* careful - assumed order*/ 3543e12c5d1SDavid du Colombier for(i = 0; i <= 9; i++){ 3553e12c5d1SDavid du Colombier if((j->r->attr®EXP) && j->match[i].sp && j->match[i].ep) { 3563e12c5d1SDavid du Colombier s = j->match[i].ep; 3573e12c5d1SDavid du Colombier c = *s; 3583e12c5d1SDavid du Colombier *s = 0; 3593e12c5d1SDavid du Colombier mp->w.s = strdup(j->match[i].sp); /*leak*/ 3603e12c5d1SDavid du Colombier *s = c; 3613e12c5d1SDavid du Colombier envinsert(mp->name, &mp->w); 3623e12c5d1SDavid du Colombier } else 3633e12c5d1SDavid du Colombier envinsert(mp->name, 0); 3643e12c5d1SDavid du Colombier mp++; 3653e12c5d1SDavid du Colombier } 3663e12c5d1SDavid du Colombier envinsert(0, 0); 3673e12c5d1SDavid du Colombier } 3683e12c5d1SDavid du Colombier 3693e12c5d1SDavid du Colombier void 3703e12c5d1SDavid du Colombier nproc(void) 3713e12c5d1SDavid du Colombier { 3723e12c5d1SDavid du Colombier Symtab *sym; 3733e12c5d1SDavid du Colombier Word *w; 3743e12c5d1SDavid du Colombier 3753e12c5d1SDavid du Colombier if(sym = symlook("NPROC", S_VAR, (char *)0)) { 3763e12c5d1SDavid du Colombier w = (Word *) sym->value; 3773e12c5d1SDavid du Colombier if (w && w->s && w->s[0]) 3783e12c5d1SDavid du Colombier nproclimit = atoi(w->s); 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier if(nproclimit < 1) 3813e12c5d1SDavid du Colombier nproclimit = 1; 3823e12c5d1SDavid du Colombier if(DEBUG(D_EXEC)) 3833e12c5d1SDavid du Colombier fprint(1, "nprocs = %d\n", nproclimit); 3843e12c5d1SDavid du Colombier if(nproclimit > nevents){ 3853e12c5d1SDavid du Colombier if(nevents) 3863e12c5d1SDavid du Colombier events = (Event *)Realloc((char *)events, nproclimit*sizeof(Event)); 3873e12c5d1SDavid du Colombier else 3883e12c5d1SDavid du Colombier events = (Event *)Malloc(nproclimit*sizeof(Event)); 3893e12c5d1SDavid du Colombier while(nevents < nproclimit) 3903e12c5d1SDavid du Colombier events[nevents++].pid = 0; 3913e12c5d1SDavid du Colombier } 3923e12c5d1SDavid du Colombier } 3933e12c5d1SDavid du Colombier 3943e12c5d1SDavid du Colombier int 3953e12c5d1SDavid du Colombier nextslot(void) 3963e12c5d1SDavid du Colombier { 3973e12c5d1SDavid du Colombier int i; 3983e12c5d1SDavid du Colombier 3993e12c5d1SDavid du Colombier for(i = 0; i < nproclimit; i++) 4003e12c5d1SDavid du Colombier if(events[i].pid <= 0) return i; 4013e12c5d1SDavid du Colombier assert("out of slots!!", 0); 4023e12c5d1SDavid du Colombier return 0; /* cyntax */ 4033e12c5d1SDavid du Colombier } 4043e12c5d1SDavid du Colombier 4053e12c5d1SDavid du Colombier int 4063e12c5d1SDavid du Colombier pidslot(int pid) 4073e12c5d1SDavid du Colombier { 4083e12c5d1SDavid du Colombier int i; 4093e12c5d1SDavid du Colombier 4103e12c5d1SDavid du Colombier for(i = 0; i < nevents; i++) 4113e12c5d1SDavid du Colombier if(events[i].pid == pid) return(i); 4123e12c5d1SDavid du Colombier if(DEBUG(D_EXEC)) 4133e12c5d1SDavid du Colombier fprint(2, "mk: wait returned unexpected process %d\n", pid); 4143e12c5d1SDavid du Colombier return(-1); 4153e12c5d1SDavid du Colombier } 4163e12c5d1SDavid du Colombier 4173e12c5d1SDavid du Colombier 4183e12c5d1SDavid du Colombier static void 4193e12c5d1SDavid du Colombier pnew(int pid, int status) 4203e12c5d1SDavid du Colombier { 4213e12c5d1SDavid du Colombier Process *p; 4223e12c5d1SDavid du Colombier 4233e12c5d1SDavid du Colombier if(pfree){ 4243e12c5d1SDavid du Colombier p = pfree; 4253e12c5d1SDavid du Colombier pfree = p->f; 4263e12c5d1SDavid du Colombier } else 4273e12c5d1SDavid du Colombier p = (Process *)Malloc(sizeof(Process)); 4283e12c5d1SDavid du Colombier p->pid = pid; 4293e12c5d1SDavid du Colombier p->status = status; 4303e12c5d1SDavid du Colombier p->f = phead; 4313e12c5d1SDavid du Colombier phead = p; 4323e12c5d1SDavid du Colombier if(p->f) 4333e12c5d1SDavid du Colombier p->f->b = p; 4343e12c5d1SDavid du Colombier p->b = 0; 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier 4373e12c5d1SDavid du Colombier static void 4383e12c5d1SDavid du Colombier pdelete(Process *p) 4393e12c5d1SDavid du Colombier { 4403e12c5d1SDavid du Colombier if(p->f) 4413e12c5d1SDavid du Colombier p->f->b = p->b; 4423e12c5d1SDavid du Colombier if(p->b) 4433e12c5d1SDavid du Colombier p->b->f = p->f; 4443e12c5d1SDavid du Colombier else 4453e12c5d1SDavid du Colombier phead = p->f; 4463e12c5d1SDavid du Colombier p->f = pfree; 4473e12c5d1SDavid du Colombier pfree = p; 4483e12c5d1SDavid du Colombier } 4493e12c5d1SDavid du Colombier 4503e12c5d1SDavid du Colombier void 4513e12c5d1SDavid du Colombier killchildren(char *msg) 4523e12c5d1SDavid du Colombier { 4533e12c5d1SDavid du Colombier Process *p; 4543e12c5d1SDavid du Colombier 455*219b2ee8SDavid du Colombier for(p = phead; p; p = p->f) 456*219b2ee8SDavid du Colombier expunge(p->pid, msg); 4573e12c5d1SDavid du Colombier } 458*219b2ee8SDavid du Colombier 459*219b2ee8SDavid du Colombier int 460*219b2ee8SDavid du Colombier notifyf(void *a, char *msg) 461*219b2ee8SDavid du Colombier { 462*219b2ee8SDavid du Colombier static int nnote; 463*219b2ee8SDavid du Colombier 464*219b2ee8SDavid du Colombier USED(a); 465*219b2ee8SDavid du Colombier if(++nnote > 100){ /* until andrew fixes his program */ 466*219b2ee8SDavid du Colombier fprint(2, "mk: too many notes\n"); 467*219b2ee8SDavid du Colombier notify(0); 468*219b2ee8SDavid du Colombier abort(); 4693e12c5d1SDavid du Colombier } 470*219b2ee8SDavid du Colombier if(strcmp(msg, "interrupt")!=0 && strcmp(msg, "hangup")!=0) 471*219b2ee8SDavid du Colombier return 0; 472*219b2ee8SDavid du Colombier kflag = 1; /* to make sure waitup doesn't exit */ 473*219b2ee8SDavid du Colombier jobs = 0; /* make sure no more get scheduled */ 474*219b2ee8SDavid du Colombier killchildren(msg); 475*219b2ee8SDavid du Colombier while(waitup(1, (int *)0) == 0) 476*219b2ee8SDavid du Colombier ; 477*219b2ee8SDavid du Colombier Bprint(&stdout, "mk: %s\n", msg); 478*219b2ee8SDavid du Colombier Exit(); 479*219b2ee8SDavid du Colombier return -1; 4803e12c5d1SDavid du Colombier } 4813e12c5d1SDavid du Colombier /* 4823e12c5d1SDavid du Colombier * execute a shell command capturing the output into the buffer. 4833e12c5d1SDavid du Colombier */ 4843e12c5d1SDavid du Colombier void 4853e12c5d1SDavid du Colombier rcexec(char *cstart, char *cend, Bufblock *buf) 4863e12c5d1SDavid du Colombier { 4873e12c5d1SDavid du Colombier int childin[2], childout[2], pid; 4883e12c5d1SDavid du Colombier int tot, n; 4893e12c5d1SDavid du Colombier 4903e12c5d1SDavid du Colombier Bflush(&stdout); 4913e12c5d1SDavid du Colombier if(pipe(childin) < 0){ 4923e12c5d1SDavid du Colombier SYNERR(-1); perror("pipe1"); 4933e12c5d1SDavid du Colombier Exit(); 4943e12c5d1SDavid du Colombier } 4953e12c5d1SDavid du Colombier if(pipe(childout) < 0){ 4963e12c5d1SDavid du Colombier SYNERR(-1); perror("pipe2"); 4973e12c5d1SDavid du Colombier Exit(); 4983e12c5d1SDavid du Colombier } 4993e12c5d1SDavid du Colombier if((pid = rfork(RFPROC|RFFDG|RFENVG)) < 0){ 5003e12c5d1SDavid du Colombier SYNERR(-1); perror("fork"); 5013e12c5d1SDavid du Colombier Exit(); 5023e12c5d1SDavid du Colombier } 5033e12c5d1SDavid du Colombier if(pid){ /* parent */ 5043e12c5d1SDavid du Colombier close(childin[0]); 5053e12c5d1SDavid du Colombier close(childout[1]); 5063e12c5d1SDavid du Colombier if(cstart < cend) 5073e12c5d1SDavid du Colombier write(childin[1], cstart, cend-cstart+1); 5083e12c5d1SDavid du Colombier close(childin[1]); 5093e12c5d1SDavid du Colombier tot = n = 0; 5103e12c5d1SDavid du Colombier do { 5113e12c5d1SDavid du Colombier tot += n; 5123e12c5d1SDavid du Colombier buf->current += n; 5133e12c5d1SDavid du Colombier if (buf->current >= buf->end) 5143e12c5d1SDavid du Colombier growbuf(buf); 5153e12c5d1SDavid du Colombier } while((n = read(childout[0], buf->current, buf->end-buf->current)) > 0); 5163e12c5d1SDavid du Colombier if (tot && buf->current[-1] == '\n') 5173e12c5d1SDavid du Colombier buf->current--; 5183e12c5d1SDavid du Colombier close(childout[0]); 5193e12c5d1SDavid du Colombier } else { 520*219b2ee8SDavid du Colombier dup(childin[0], 0); 521*219b2ee8SDavid du Colombier dup(childout[1], 1); 5223e12c5d1SDavid du Colombier close(childin[0]); 5233e12c5d1SDavid du Colombier close(childin[1]); 5243e12c5d1SDavid du Colombier close(childout[0]); 5253e12c5d1SDavid du Colombier close(childout[1]); 526*219b2ee8SDavid du Colombier Execl(shell, shellname, "-I", (char *)0); 5273e12c5d1SDavid du Colombier perror(shell); 528*219b2ee8SDavid du Colombier _exits("exec"); 5293e12c5d1SDavid du Colombier } 5303e12c5d1SDavid du Colombier } 5313e12c5d1SDavid du Colombier 5323e12c5d1SDavid du Colombier void 5333e12c5d1SDavid du Colombier envinsert(char *name, Word *value) 5343e12c5d1SDavid du Colombier { 5353e12c5d1SDavid du Colombier if (nextv >= envsize) { 5363e12c5d1SDavid du Colombier envsize += ENVQUANTA; 5373e12c5d1SDavid du Colombier envy = (Envy *) Realloc((char *) envy, envsize*sizeof(Envy)); 5383e12c5d1SDavid du Colombier } 5393e12c5d1SDavid du Colombier envy[nextv].name = name; 5403e12c5d1SDavid du Colombier envy[nextv++].values = value; 5413e12c5d1SDavid du Colombier } 542*219b2ee8SDavid du Colombier 543*219b2ee8SDavid du Colombier static long tslot[1000]; 544*219b2ee8SDavid du Colombier static long tick; 545*219b2ee8SDavid du Colombier 546*219b2ee8SDavid du Colombier void 547*219b2ee8SDavid du Colombier usage(void) 548*219b2ee8SDavid du Colombier { 549*219b2ee8SDavid du Colombier long t; 550*219b2ee8SDavid du Colombier 551*219b2ee8SDavid du Colombier time(&t); 552*219b2ee8SDavid du Colombier if(tick) 553*219b2ee8SDavid du Colombier tslot[nrunning] += (t-tick); 554*219b2ee8SDavid du Colombier tick = t; 555*219b2ee8SDavid du Colombier } 556*219b2ee8SDavid du Colombier 557*219b2ee8SDavid du Colombier void 558*219b2ee8SDavid du Colombier prusage(void) 559*219b2ee8SDavid du Colombier { 560*219b2ee8SDavid du Colombier int i; 561*219b2ee8SDavid du Colombier 562*219b2ee8SDavid du Colombier usage(); 563*219b2ee8SDavid du Colombier for(i = 0; i <= nevents; i++) 564*219b2ee8SDavid du Colombier fprint(1, "%d: %ld\n", i, tslot[i]); 565*219b2ee8SDavid du Colombier } 566