From f3df938969f50dcffa8f9430786caf727e8a9866 Mon Sep 17 00:00:00 2001 From: Michael Santos Date: Sun, 23 Mar 2014 16:06:32 -0400 Subject: [PATCH] Set the exec() status of the child Set the exec() status of the child before reading from the child's stdin/stderr: the exec status determines the message type (proxy or stdout) returned by the port. Begin recording the exit status of the child. Currently it is just a non-zero number. It should be set to the actual exit status of the child. The value should be reported to the erlang side as well: {exit_status, integer()} --- c_src/alcove.c | 52 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/c_src/alcove.c b/c_src/alcove.c index ee0cac6..761143e 100644 --- a/c_src/alcove.c +++ b/c_src/alcove.c @@ -516,9 +516,20 @@ pid_not_equal(pid_t p1, pid_t p2) static int exited_pid(alcove_child_t *c, void *arg1, void *arg2) { + int *status = arg1; + + c->exited = 1 << 0; + + if (WIFEXITED(*status) && WEXITSTATUS(*status) != 0) { + c->exited |= 1 << 1; + } + + if (WIFSIGNALED(*status)) { + c->exited |= 1 << 2; + } + (void)close(c->fdin); c->fdin = -1; - c->exited = 1; return 0; } @@ -571,6 +582,22 @@ read_from_pid(alcove_child_t *c, void *arg1, void *arg2) { fd_set *rfds = arg1; + if (c->fdctl > -1 && FD_ISSET(c->fdctl, rfds)) { + unsigned char buf; + ssize_t n; + + n = read(c->fdctl, &buf, sizeof(buf)); + (void)close(c->fdctl); + c->fdctl = -1; + + if (n == 0) { + c->fdctl = ALCOVE_CHILD_EXEC; + if (alcove_call_stdio(c->pid, ALCOVE_MSG_CALL, + erl_mk_atom("ok")) < 0) + return -1; + } + } + if (c->fdout > -1 && FD_ISSET(c->fdout, rfds)) { switch (alcove_child_stdio(c->fdout, c, ALCOVE_MSG_TYPE(c))) { case -1: @@ -595,23 +622,6 @@ read_from_pid(alcove_child_t *c, void *arg1, void *arg2) } } - if (c->fdctl > -1 && FD_ISSET(c->fdctl, rfds)) { - unsigned char buf; - ssize_t n; - - n = read(c->fdctl, &buf, sizeof(buf)); - (void)close(c->fdctl); - c->fdctl = -1; - - if (n == 0 && !c->exited && c->fdin > -1 && c->fdout > -1 - && c->fderr > -1) { - c->fdctl = ALCOVE_CHILD_EXEC; - if (alcove_call_stdio(c->pid, ALCOVE_MSG_CALL, - erl_mk_atom("ok")) < 0) - return -1; - } - } - return 1; } @@ -619,6 +629,7 @@ read_from_pid(alcove_child_t *c, void *arg1, void *arg2) alcove_handle_signal(alcove_state_t *ap) { int signum = 0; ETERM *reply = NULL; + int status = 0; int rv = -1; if (!sigcaught) @@ -633,7 +644,7 @@ alcove_handle_signal(alcove_state_t *ap) { for ( ; ; ) { errno = 0; - pid = waitpid(-1, 0, WNOHANG); + pid = waitpid(-1, &status, WNOHANG); if (errno == ECHILD || pid == 0) break; @@ -641,7 +652,8 @@ alcove_handle_signal(alcove_state_t *ap) { if (pid < 0) return -1; - (void)pid_foreach(ap, pid, NULL, NULL, pid_equal, exited_pid); + (void)pid_foreach(ap, pid, &status, NULL, + pid_equal, exited_pid); } }