diff --git a/c_src/alcove.c b/c_src/alcove.c index 5e7812e..237f3b6 100644 --- a/c_src/alcove.c +++ b/c_src/alcove.c @@ -220,7 +220,7 @@ alcove_event_loop(alcove_state_t *ap) } } - if (fds[STDIN_FILENO].revents & (POLLIN|POLLERR|POLLHUP)) { + if (fds[STDIN_FILENO].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) { switch (alcove_stdin(ap)) { case -1: erl_err_sys("alcove_stdin"); @@ -663,7 +663,7 @@ read_from_pid(alcove_state_t *ap, alcove_child_t *c, void *arg1, void *arg2) { struct pollfd *fds = arg1; - if (c->fdctl > -1 && (fds[c->fdctl].revents & (POLLIN|POLLERR|POLLHUP))) { + if (c->fdctl > -1 && (fds[c->fdctl].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL))) { unsigned char buf; ssize_t n; @@ -679,7 +679,7 @@ read_from_pid(alcove_state_t *ap, alcove_child_t *c, void *arg1, void *arg2) } } - if (c->fdout > -1 && (fds[c->fdout].revents & (POLLIN|POLLERR|POLLHUP))) { + if (c->fdout > -1 && (fds[c->fdout].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL))) { switch (alcove_child_stdio(c->fdout, ap->depth, c, ALCOVE_MSG_TYPE(c))) { case -1: @@ -692,7 +692,7 @@ read_from_pid(alcove_state_t *ap, alcove_child_t *c, void *arg1, void *arg2) } } - if (c->fderr > -1 && (fds[c->fderr].revents & (POLLIN|POLLERR|POLLHUP))) { + if (c->fderr > -1 && (fds[c->fderr].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL))) { switch (alcove_child_stdio(c->fderr, ap->depth, c, ALCOVE_MSG_STDERR)) { case -1: diff --git a/test/alcove_tests.erl b/test/alcove_tests.erl index dc1f1cd..26767e4 100644 --- a/test/alcove_tests.erl +++ b/test/alcove_tests.erl @@ -59,6 +59,7 @@ run(State) -> portstress(State), forkstress(State), forkchain(State), + eof(State), prctl(State), execvp(State), stdout(State), @@ -398,6 +399,31 @@ forkchain(#state{port = Port}) -> ?_assertEqual(Pid, Child4). +eof(#state{port = Port}) -> + {ok, Child} = alcove:fork(Port), + {ok, Child0} = alcove:fork(Port, [Child]), + + ok = alcove:eof(Port, [Child,Child0], stderr), + Reply0 = alcove:eof(Port, [Child,Child0], stderr), + + ok = alcove:eof(Port, [Child,Child0], stdout), + Reply1 = alcove:eof(Port, [Child,Child0], stdout), + + ok = alcove:eof(Port, [Child,Child0]), + Reply2 = case alcove:eof(Port, [Child,Child0]) of + {error,esrch} -> ok; + {error,ebadf} -> ok; + N -> N + end, + + alcove:exit(Port, [Child], 0), + + [ + ?_assertEqual({error,ebadf}, Reply0), + ?_assertEqual({error,ebadf}, Reply1), + ?_assertEqual(ok, Reply2) + ]. + prctl(#state{os = {unix,linux}, port = Port}) -> {ok, Fork} = alcove:fork(Port),