Exemplo n.º 1
0
Arquivo: job.c Projeto: UNGLinux/Obase
static Job *
prepare_job(GNode *gn, int flags)
{
	bool cmdsOK;     	/* true if the nodes commands were all right */
	bool noExec;     	/* Set true if we decide not to run the job */

	/*
	 * Check the commands now so any attributes from .DEFAULT have a chance
	 * to migrate to the node
	 */
	cmdsOK = Job_CheckCommands(gn);
	expand_commands(gn);

	if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
		/*
		 * We're serious here, but if the commands were bogus, we're
		 * also dead...
		 */
		if (!cmdsOK)
			job_failure(gn, Punt);

		if (Lst_IsEmpty(&gn->commands))
			noExec = true;
		else
			noExec = false;

	} else if (noExecute) {
		if (!cmdsOK || Lst_IsEmpty(&gn->commands))
			noExec = true;
		else
			noExec = false;
	} else {
		/*
		 * Just touch the target and note that no shell should be
		 * executed.  Check
		 * the commands, too, but don't die if they're no good -- it
		 * does no harm to keep working up the graph.
		 */
		Job_Touch(gn);
		noExec = true;
	}

	/*
	 * If we're not supposed to execute a shell, don't.
	 */
	if (noExec) {
		/*
		 * We only want to work our way up the graph if we aren't here
		 * because the commands for the job were no good.
		 */
		if (cmdsOK && !aborting) {
			gn->built_status = MADE;
			Make_Update(gn);
		}
		return NULL;
	} else {
		Job *job;       	/* new job descriptor */
		job = emalloc(sizeof(Job));
		if (job == NULL)
			Punt("JobStart out of memory");

		job->node = gn;

		/*
		 * Set the initial value of the flags for this job based on the
		 * global ones and the node's attributes... Any flags supplied
		 * by the caller are also added to the field.
		 */
		job->flags = flags;

		if (gn->type & OP_CHEAP)
			return job;
		if ((gn->type & OP_EXPENSIVE) || 
		    expensive_commands(&gn->expanded))
			job->flags |= JOB_IS_EXPENSIVE;

		return job;
	}
}
Exemplo n.º 2
0
Arquivo: make.c Projeto: aharri/base
static bool
try_to_make_node(GNode *gn)
{
	if (DEBUG(MAKE))
		printf("Examining %s...", gn->name);
		
	if (gn->unmade != 0) {
		if (DEBUG(MAKE))
			printf(" Requeuing (%d)\n", gn->unmade);
		add_targets_to_make(&gn->children);
		Array_Push(&toBeMade, gn);
		return false;
	}
	if (has_been_built(gn)) {
		if (DEBUG(MAKE))
			printf(" already made\n");
			return false;
	}
	if (has_unmade_predecessor(gn)) {
		if (DEBUG(MAKE))
			printf(" Dropping for now\n");
		return false;
	}

	/* SIB: this is where there should be a siblings loop */
	Suff_FindDeps(gn);
	if (gn->unmade != 0) {
		if (DEBUG(MAKE))
			printf(" Requeuing (after deps: %d)\n", gn->unmade);
		add_targets_to_make(&gn->children);
		return false;
	}
	if (Make_OODate(gn)) {
		/* SIB: if a sibling is getting built, I don't build it right now */
		if (DEBUG(MAKE))
			printf("out-of-date\n");
		if (queryFlag)
			return true;
		/* SIB: this is where commands should get prepared */
		Make_DoAllVar(gn);
		/* SIB: this is where I should make the gn as `being built */
		gn->build_lock = true;
		Job_Make(gn);
	} else {
		if (DEBUG(MAKE))
			printf("up-to-date\n");
		gn->built_status = UPTODATE;
		if (gn->type & OP_JOIN) {
			/*
			 * Even for an up-to-date .JOIN node, we need it
			 * to have its context variables so references
			 * to it get the correct value for .TARGET when
			 * building up the context variables of its
			 * parent(s)...
			 */
			Make_DoAllVar(gn);
		}

		Make_Update(gn);
	}
	return false;
}
Exemplo n.º 3
0
Arquivo: job.c Projeto: UNGLinux/Obase
static void
process_job_status(Job *job, int status)
{
	int reason, code;
	bool	 done;

	debug_printf("Process %ld (%s) exited with status %d.\n",
	    (long)job->pid, job->node->name, status);
	/* parse status */
	if (WIFEXITED(status)) {
		reason = JOB_EXITED;
		code = WEXITSTATUS(status);
	} else if (WIFSIGNALED(status)) {
		reason = JOB_SIGNALED;
		code = WTERMSIG(status);
	} else {
		/* can't happen, set things to be bad. */
		reason = UNKNOWN;
		code = status;
	}

	if ((reason == JOB_EXITED &&
	     code != 0 && !(job->node->type & OP_IGNORE)) ||
	    reason == JOB_SIGNALED) {
		/*
		 * If it exited non-zero and either we're doing things our
		 * way or we're not ignoring errors, the job is finished.
		 * Similarly, if the shell died because of a signal
		 * the job is also finished. In these
		 * cases, finish out the job's output before printing the exit
		 * status...
		 */
		close_job_pipes(job);
		done = true;
	} else if (reason == JOB_EXITED) {
		/*
		 * Deal with ignored errors. We need to print a message telling
		 * of the ignored error as well as setting status.w_status to 0
		 * so the next command gets run. To do this, we set done to be
		 * true and the job exited non-zero.
		 */
		done = code != 0;
		close_job_pipes(job);
	} else {
		/*
		 * No need to close things down or anything.
		 */
		done = false;
	}

	if (done || DEBUG(JOB)) {
		if (reason == JOB_EXITED) {
			debug_printf("Process %ld (%s) exited.\n",
			    (long)job->pid, job->node->name);
			if (code != 0) {
				banner(job, stdout);
				(void)fprintf(stdout, "*** Error code %d %s\n",
				    code,
				    (job->node->type & OP_IGNORE) ?
				    "(ignored)" : "");

				if (job->node->type & OP_IGNORE) {
					reason = JOB_EXITED;
					code = 0;
				}
			} else if (DEBUG(JOB)) {
				(void)fprintf(stdout,
				    "*** %ld (%s) Completed successfully\n",
				    (long)job->pid, job->node->name);
			}
		} else {
			banner(job, stdout);
			(void)fprintf(stdout, "*** Signal %d\n", code);
		}

		(void)fflush(stdout);
	}

	done = true;

	if (done &&
	    aborting != ABORT_ERROR &&
	    aborting != ABORT_INTERRUPT &&
	    reason == JOB_EXITED && code == 0) {
		/* As long as we aren't aborting and the job didn't return a
		 * non-zero status that we shouldn't ignore, we call
		 * Make_Update to update the parents. */
		job->node->built_status = MADE;
		Make_Update(job->node);
	} else if (!(reason == JOB_EXITED && code == 0)) {
		register_error(reason, code, job);
	}
	free(job);

	if (errors && !keepgoing &&
	    aborting != ABORT_INTERRUPT)
		aborting = ABORT_ERROR;

	if (aborting == ABORT_ERROR && Job_Empty())
		Finish(errors);
}