Example #1
0
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;
}
Example #2
0
int
cokill(register Coshell_t* co, register Cojob_t* cj, int sig)
{
	int	any;
	int	n;

	if (cj)
	{
		if (!co)
			co = cj->coshell;
		else if (co != cj->coshell)
			return -1;
		any = 0;
	}
	else if (co)
		any = 0;
	else if (!(co = state.coshells))
		return -1;
	else
		any = 1;
	if (co->flags & CO_DEBUG)
		errormsg(state.lib, 2, "coshell %d kill co=%d cj=%d sig=%d", co->index, co ? co->pid : 0, cj ? cj->pid : 0, sig);
	switch (sig)
	{
	case SIGINT:
		sig = SIGTERM;
		break;
#if defined(SIGSTOP) && defined(SIGTSTP)
	case SIGTSTP:
		sig = SIGSTOP;
		break;
#endif
	}
	n = 0;
	do
	{
		cowait(co, (Cojob_t*)co, 0);
		n |= cokillshell(co, cj, sig);
	} while (any && (co = co->next));
	return n;
}
Example #3
0
int
block(int check)
{
	register Cojob_t*	cojob;
	register Joblist_t*	job;
	Rule_t*			r;
	int			n;
	int			clear = 0;
	int			resume = 0;

	if (!state.coshell || !copending(state.coshell))
	{
		if (jobs.intermediate)
		{
			/*
			 * mark the jobs that must be generated
			 */

			n = 0;
			for (job = jobs.firstjob; job; job = job->next)
				if (job->target->must > ((unsigned int)(job->target->dynamic & D_intermediate) != 0))
				{
					n = 1;
					break;
				}
			if (n)
			{
				/*
				 * some intermediates must be generated
				 */


				error(2, "some intermediates must be generated");
			}
			else
			{
				/*
				 * accept missing intermediates
				 */

				while (job = jobs.firstjob)
				{
					if (error_info.trace || state.explain)
						error(state.explain ? 0 : -1, "cancelling %s action -- %s", job->target->name, job->status == INTERMEDIATE ? "intermediate not needed" : "missing intermediates accepted");
					job->target->status = EXISTS;
					discard(job);
				}
				jobs.intermediate = 0;
				return 1;
			}
		}
		return 0;
	}
	for (;;)
	{
		state.waiting = 1;
		if ((cojob = cowait(state.coshell, check ? (Cojob_t*)state.coshell : (Cojob_t*)0, -1)) && (job = (Joblist_t*)cojob->local))
			job->cojob = 0;
		if (trap())
		{
			if (state.interpreter)
				clear = resume = 1;
			if (!cojob)
				continue;
		}
		state.waiting = 0;
		if (!cojob)
		{
			if (check)
				return 0;
			break;
		}
		if (r = getrule(external.jobdone))
		{
			if (!jobs.tmp)
				jobs.tmp = sfstropen();
			sfprintf(jobs.tmp, "%s %d %s %s", job->target->name, cojob->status, fmtelapsed(cojob->user, CO_QUANT), fmtelapsed(cojob->sys, CO_QUANT));
			call(r, sfstruse(jobs.tmp));
		}
		if (cojob->status)
		{
			if (n = !EXITED_TERM(cojob->status) || EXIT_CODE(cojob->status))
			{
				if ((job->target->dynamic & D_hasafter) && hasafter(job->target, P_failure))
					n = 0;
				error(n ? 2 : state.explain ? 0 : -1, "%s%s code %d making %s%s", n ? "*** " : null, ERROR_translate(NiL, NiL, NiL, EXITED_TERM(cojob->status) ? "termination" : "exit"), EXIT_CODE(cojob->status), job->target->name, (job->flags & CO_IGNORE) ? ERROR_translate(NiL, NiL, NiL, " ignored") : null);
			}
			if (!(job->flags & CO_IGNORE))
			{
				job->flags |= CO_ERRORS;
				if (state.keepgoing || !n)
				{
					if (n)
						state.errors++;
					job->flags |= CO_KEEPGOING;
				}
			}
			if (state.interrupt || !(job->flags & (CO_IGNORE|CO_KEEPGOING)))
				clear = 1;
		}
		message((-3, "job: %s: interrupt=%d clear=%d status=%d flags=%08x", job->target->name, state.interrupt, clear, cojob->status, job->flags));

		/*
		 * job is done
		 */

		if (done(job, clear, cojob))
			return 1;
	}
	if (resume)
		longjmp(state.resume.label, 1);
	if (!state.finish)
	{
		if (!copending(state.coshell))
		{
			if (clear)
				finish(1);
		}
		else if (!state.interrupt)
			error(3, "lost contact with coshell");
	}
	return 0;
}