diff options
author | Lukas Larsson <[email protected]> | 2014-01-17 14:37:39 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2014-01-27 15:25:27 +0100 |
commit | 8f8a03ba3556f2c2c70797bedf5d44b360659425 (patch) | |
tree | c0384560ea2e6e2b9a6d6d757e8a780ce8616490 /erts/emulator/drivers | |
parent | 25237481ccccd3ddfa74582dc267632ad618ba30 (diff) | |
download | otp-8f8a03ba3556f2c2c70797bedf5d44b360659425.tar.gz otp-8f8a03ba3556f2c2c70797bedf5d44b360659425.tar.bz2 otp-8f8a03ba3556f2c2c70797bedf5d44b360659425.zip |
erts: fix bug when using passive mode and sendfile
The bug incorrectly issued driver_select when un-ignoring an fd
for a socket in passive mode, which caused an incorrect error
tuple to be returned when the remote end closed the connection.
Diffstat (limited to 'erts/emulator/drivers')
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 45fac69303..fedab62866 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -846,9 +846,10 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define INET_IFNAMSIZ 16 /* INET Ignore states */ -#define INET_IGNORE_NONE 0 -#define INET_IGNORE_READ 1 -#define INET_IGNORE_WRITE 1 << 1 +#define INET_IGNORE_NONE 0 +#define INET_IGNORE_READ (1 << 0) +#define INET_IGNORE_WRITE (1 << 1) +#define INET_IGNORE_PASSIVE (1 << 2) /* Max length of Erlang Term Buffer (for outputting structured terms): */ #ifdef HAVE_SCTP @@ -8208,11 +8209,19 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, if (*buf == 1 && !desc->is_ignored) { sock_select(desc, (FD_READ|FD_WRITE|FD_CLOSE|ERL_DRV_USE_NO_CALLBACK), 0); - desc->is_ignored = INET_IGNORE_READ; + if (desc->active) + desc->is_ignored = INET_IGNORE_READ; + else + desc->is_ignored = INET_IGNORE_PASSIVE; } else if (*buf == 0 && desc->is_ignored) { - int flags = (FD_READ|FD_CLOSE|((desc->is_ignored & INET_IGNORE_WRITE)?FD_WRITE:0)); + int flags = FD_CLOSE; + if (desc->is_ignored & INET_IGNORE_READ) + flags |= FD_READ; + if (desc->is_ignored & INET_IGNORE_WRITE) + flags |= FD_WRITE; desc->is_ignored = INET_IGNORE_NONE; - sock_select(desc, flags, 1); + if (flags != FD_CLOSE) + sock_select(desc, flags, 1); } else return ctl_error(EINVAL, rbuf, rsize); @@ -8889,6 +8898,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, driver_set_timer(desc->inet.port, timeout); if (!INETP(desc)->is_ignored) sock_select(INETP(desc),(FD_READ|FD_CLOSE),1); + else + INETP(desc)->is_ignored |= INET_IGNORE_READ; } } return ctl_reply(INET_REP_OK, tbuf, 2, rbuf, rsize); |