* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: main.c,v 1.149 2004/11/14 22:53:42 carlsonj Exp $"
+#define RCSID "$Id: main.c,v 1.153 2006/06/04 03:52:50 paulus Exp $"
#include <stdio.h>
#include <ctype.h>
static void open_ccp __P((int));
static void bad_signal __P((int));
static void holdoff_end __P((void *));
+static void forget_child __P((int pid, int status));
static int reap_kids __P((void));
static void childwait_end __P((void *));
script_unsetenv("BYTES_RCVD");
lcp_open(0); /* Start protocol */
+ start_link(0);
while (phase != PHASE_DEAD) {
handle_events();
get_input();
}
}
}
+ /* restore FSMs to original state */
+ lcp_close(0, "");
if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail))
break;
/*
* run-program - execute a program with given arguments,
- * but don't wait for it.
+ * but don't wait for it unless wait is non-zero.
* If the program can't be executed, logs an error unless
* must_exist is 0 and the program file doesn't exist.
* Returns -1 if it couldn't fork, 0 if the file doesn't exist
* reap_kids) iff the return value is > 0.
*/
pid_t
-run_program(prog, args, must_exist, done, arg)
+run_program(prog, args, must_exist, done, arg, wait)
char *prog;
char **args;
int must_exist;
void (*done) __P((void *));
void *arg;
+ int wait;
{
- int pid;
+ int pid, status;
struct stat sbuf;
/*
if (debug)
dbglog("Script %s started (pid %d)", prog, pid);
record_child(pid, prog, done, arg);
+ if (wait) {
+ while (waitpid(pid, &status, 0) < 0) {
+ if (errno == EINTR)
+ continue;
+ fatal("error waiting for script %s: %m", prog);
+ }
+ forget_child(pid, status);
+ }
return pid;
}
childwait_done = 1;
}
+/*
+ * forget_child - clean up after a dead child
+ */
+static void
+forget_child(pid, status)
+ int pid, status;
+{
+ struct subprocess *chp, **prevp;
+
+ for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) {
+ if (chp->pid == pid) {
+ --n_children;
+ *prevp = chp->next;
+ break;
+ }
+ }
+ if (WIFSIGNALED(status)) {
+ warn("Child process %s (pid %d) terminated with signal %d",
+ (chp? chp->prog: "??"), pid, WTERMSIG(status));
+ } else if (debug)
+ dbglog("Script %s finished (pid %d), status = 0x%x",
+ (chp? chp->prog: "??"), pid,
+ WIFEXITED(status) ? WEXITSTATUS(status) : status);
+ if (chp && chp->done)
+ (*chp->done)(chp->arg);
+ if (chp)
+ free(chp);
+}
+
/*
* reap_kids - get status from any dead child processes,
* and log a message for abnormal terminations.
reap_kids()
{
int pid, status;
- struct subprocess *chp, **prevp;
if (n_children == 0)
return 0;
while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) {
- for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) {
- if (chp->pid == pid) {
- --n_children;
- *prevp = chp->next;
- break;
- }
- }
- if (WIFSIGNALED(status)) {
- warn("Child process %s (pid %d) terminated with signal %d",
- (chp? chp->prog: "??"), pid, WTERMSIG(status));
- } else if (debug)
- dbglog("Script %s finished (pid %d), status = 0x%x",
- (chp? chp->prog: "??"), pid,
- WIFEXITED(status) ? WEXITSTATUS(status) : status);
- if (chp && chp->done)
- (*chp->done)(chp->arg);
- if (chp)
- free(chp);
+ forget_child(pid, status);
}
if (pid == -1) {
if (errno == ECHILD)