Convert Compat_RunCommand() to use ProcWait(). This also gives Cmd_Exec()

the potential to handle interrupts which it doesn't currently.

Submitted by:	Max Okumoto <okumoto@ucsd.edu> (7.228)
This commit is contained in:
Hartmut Brandt 2005-05-12 11:09:45 +00:00
parent 32b5d9451b
commit f7a01b8dcc

View File

@ -580,6 +580,7 @@ ProcExec(const ProcStuff *ps)
}
/**
* Wait for child process to terminate.
*/
static int
ProcWait(ProcStuff *ps)
@ -590,8 +591,18 @@ ProcWait(ProcStuff *ps)
/*
* Wait for the process to exit.
*/
while (((pid = wait(&status)) != ps->child_pid) && (pid >= 0)) {
continue;
for (;;) {
pid = wait(&status);
if (pid == -1 && errno != EINTR) {
Fatal("error in wait: %d", pid);
/* NOTREACHED */
}
if (pid == ps->child_pid) {
break;
}
if (interrupted) {
break;
}
}
return (status);
@ -3225,7 +3236,6 @@ Compat_RunCommand(char *cmd, GNode *gn)
Boolean errCheck; /* Check errors */
int reason; /* Reason for child's death */
int status; /* Description of child's death */
ReturnStatus rstat; /* Status of fork */
LstNode *cmdNode; /* Node where current command is located */
char **av; /* Argument vector for thing to exec */
char *cmd_save; /* saved cmd */
@ -3343,85 +3353,70 @@ Compat_RunCommand(char *cmd, GNode *gn)
*/
ProcExec(&ps);
/* NOTREACHED */
}
if (av == NULL) {
free(ps.argv[2]);
free(ps.argv[1]);
free(ps.argv[0]);
free(ps.argv);
}
/*
* we need to print out the command associated with this
* Gnode in Targ_PrintCmd from Targ_PrintGraph when debugging
* at level g2, in main(), Fatal() and DieHorribly(),
* therefore do not free it when debugging.
*/
if (!DEBUG(GRAPH2)) {
free(cmdStart);
Lst_Replace(cmdNode, cmd_save);
}
/*
* The child is off and running. Now all we can do is wait...
*/
while (1) {
while ((rstat = wait(&reason)) != ps.child_pid) {
if (interrupted || (rstat == -1 && errno != EINTR)) {
break;
}
} else {
if (av == NULL) {
free(ps.argv[2]);
free(ps.argv[1]);
free(ps.argv[0]);
free(ps.argv);
}
/*
* we need to print out the command associated with this
* Gnode in Targ_PrintCmd from Targ_PrintGraph when debugging
* at level g2, in main(), Fatal() and DieHorribly(),
* therefore do not free it when debugging.
*/
if (!DEBUG(GRAPH2)) {
free(cmdStart);
Lst_Replace(cmdNode, cmd_save);
}
/*
* The child is off and running. Now all we can do is wait...
*/
reason = ProcWait(&ps);
if (interrupted)
CompatInterrupt(interrupted);
if (rstat > -1) {
if (WIFSTOPPED(reason)) {
/* stopped */
status = WSTOPSIG(reason);
} else if (WIFEXITED(reason)) {
/* exited */
status = WEXITSTATUS(reason);
if (status != 0) {
printf("*** Error code %d",
status);
}
} else {
/* signaled */
status = WTERMSIG(reason);
printf("*** Signal %d", status);
}
if (!WIFEXITED(reason) || status != 0) {
if (errCheck) {
gn->made = ERROR;
if (keepgoing) {
/*
* Abort the current
* target, but let
* others continue.
*/
printf(" (continuing)\n");
}
} else {
/*
* Continue executing
* commands for this target.
* If we return 0, this will
* happen...
*/
printf(" (ignored)\n");
status = 0;
}
}
break;
if (WIFEXITED(reason)) {
/* exited */
status = WEXITSTATUS(reason);
if (status == 0) {
return (0);
} else {
printf("*** Error code %d", status);
}
} else if (WIFSTOPPED(reason)) {
status = WSTOPSIG(reason);
} else {
Fatal("error in wait: %d", rstat);
/* NOTREACHED */
status = WTERMSIG(reason);
printf("*** Signal %d", status);
}
if (errCheck) {
gn->made = ERROR;
if (keepgoing) {
/*
* Abort the current
* target, but let
* others continue.
*/
printf(" (continuing)\n");
}
return (status);
} else {
/*
* Continue executing
* commands for this target.
* If we return 0, this will
* happen...
*/
printf(" (ignored)\n");
return (0);
}
}
return (status);
}
/*-