int cosystem(const char* cmd) { Coshell_t* co; Cojob_t* cj; int status; if (!cmd) return !eaccess(pathshell(), X_OK); if (!(co = coopen(NiL, CO_ANY, NiL))) return -1; if (cj = coexec(co, cmd, CO_SILENT, NiL, NiL, NiL)) cj = cowait(co, cj, -1); if (!cj) return -1; /* * synthesize wait() status from shell status * lack of synthesis is the standard's proprietary sellout */ status = cj->status; if (EXITED_TERM(status)) status &= ((1<<(EXIT_BITS-1))-1); else status = (status & ((1<<EXIT_BITS)-1)) << EXIT_BITS; return status; }
static void execute(register Joblist_t* job) { register List_t* p; char* s; char* t; int flags; Rule_t* r; Var_t* v; Sfio_t* tmp; Sfio_t* att; Sfio_t* sp; att = sfstropen(); tmp = sfstropen(); restore(job, tmp, att); job->status = RUNNING; job->target->mark &= ~M_waiting; if (state.targetcontext || state.maxview && !state.fsview && *job->target->name != '/' && (!(job->target->dynamic & D_regular) || job->target->view)) commit(job, job->target->name); if ((state.mam.dynamic || state.mam.regress) && state.user && !(job->target->property & (P_after|P_before|P_dontcare|P_make|P_state|P_virtual))) sfprintf(state.mam.out, "%sinit %s %s\n", state.mam.label, mamname(job->target), timefmt(NiL, CURTIME)); t = sfstruse(tmp); if (!(job->flags & CO_ALWAYS)) { if (state.touch) { if (state.virtualdot) { state.virtualdot = 0; lockstate(1); } if (!(job->target->property & (P_attribute|P_virtual))) { acceptrule(job->target); if ((job->target->property & (P_joint|P_target)) == (P_joint|P_target)) for (p = job->target->prereqs->rule->prereqs; p; p = p->next) if (p->rule != job->target) acceptrule(p->rule); } } else if (*t && (!state.silent || state.mam.regress)) dumpaction(state.mam.out ? state.mam.out : sfstdout, NiL, t, NiL); done(job, 0, NiL); } else { if (state.virtualdot && !notfile(job->target)) { state.virtualdot = 0; lockstate(1); } if (!state.coshell) { sp = sfstropen(); sfprintf(sp, "label=%s", idname); expand(sp, " $(" CO_ENV_OPTIONS ")"); flags = CO_ANY; if (state.cross) flags |= CO_CROSS; if (state.serialize && state.jobs > 1) flags |= CO_SERIALIZE; if (!(state.coshell = coopen(getval(CO_ENV_SHELL, VAL_PRIMARY), flags, sfstruse(sp)))) error(ERROR_SYSTEM|3, "coshell open error"); sfstrclose(sp); } if (p = internal.exports->prereqs) { Sfio_t* exp; exp = sfstropen(); do { if (v = getvar(p->rule->name)) { expand(exp, v->value); coexport(state.coshell, p->rule->name, sfstruse(exp)); } else if (s = strchr(p->rule->name, '=')) { *s = 0; expand(exp, s + 1); coexport(state.coshell, p->rule->name, sfstruse(exp)); *s = '='; } } while (p = p->next); sfstrclose(exp); #if 0 freelist(internal.exports->prereqs); #endif internal.exports->prereqs = 0; } if (job->flags & CO_DATAFILE) { static char* dot; static char* tmp; if (job->target->property & P_read) { if (!dot) dot = pathtemp(NiL, 0, null, idname, NiL); state.tmpfile = dot; } else { if (!tmp) tmp = pathtemp(NiL, 0, NiL, idname, NiL); state.tmpfile = tmp; } } #if !_HUH_1992_02_29 /* i386 and ftx m68k dump without this statement -- help */ message((-99, "execute: %s: t=0x%08x &t=0x%08x", job->target->name, t, &t)); #endif if (state.mam.out) dumpaction(state.mam.out, MAMNAME(job->target), t, NiL); if (r = getrule(external.makerun)) maketop(r, P_dontcare|P_foreground, NiL); if (!(job->cojob = coexec(state.coshell, t, job->flags, state.tmpfile, NiL, sfstruse(att)))) error(3, "%s: cannot send action to coshell", job->target->name); job->cojob->local = (void*)job; /* * grab semaphores */ if (job->target->dynamic & D_hassemaphore) { job->flags |= CO_SEMAPHORES; for (p = job->prereqs; p; p = p->next) if (p->rule->semaphore && --p->rule->semaphore == 1) p->rule->status = MAKING; } /* * check status and sync */ if (job->target->dynamic & D_hasafter) save(job); if (job->flags & (CO_DATAFILE|CO_FOREGROUND)) { complete(job->target, NiL, NiL, 0); if (job->target->property & (P_functional|P_read)) { if (sp = sfopen(NiL, state.tmpfile, "r")) { remove(state.tmpfile); if (job->target->property & P_read) parse(sp, NiL, job->target->name, NiL); else { char* e; sfmove(sp, tmp, SF_UNBOUND, -1); t = sfstrbase(tmp); e = sfstrseek(tmp, 0, SEEK_CUR); while (e > t && *(e - 1) == '\n') e--; sfstrseek(tmp, e - t, SEEK_SET); setvar(job->target->name, sfstruse(tmp), 0); } sfclose(sp); } else error(2, "%s: cannot read temporary data output file %s", job->target->name, state.tmpfile); state.tmpfile = 0; } } } sfstrclose(att); sfstrclose(tmp); }