mirror of
https://github.com/uselessd/alcove.git
synced 2026-04-15 17:25:33 +00:00
Check for invalid fd's
Add a test for closing stdio. The final test (closing stdin) is marked
as passing if {error,esrch} or {error,ebadf} is returned because there
is a race condition: the event loop may not have noticed the fd is
closed depending on how quickly the test is run.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user