From e7a7c5dabeca0eb4fed070341b0e2c971cbff52f Mon Sep 17 00:00:00 2001 From: Shafreeck Sea Date: Wed, 5 Aug 2015 10:19:44 +0800 Subject: [PATCH] Fix: Checking liveness does not work as expected Syscall recv won't set errno if the call successes. So if errno is EWOULDBLOCK and the peer closed connection, recv returns 0 and errno remains EWOULDBLOCK. That will fail the if condition. The bug may confuse the users with some unexpected behavier. --- main/streams/xp_socket.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index 13ed7036826c3..ab7afaf865ef9 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -284,7 +284,7 @@ static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t bu static int php_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam) { - int oldmode, flags; + int oldmode, flags, ret; php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; php_stream_xport_param *xparam; @@ -314,7 +314,11 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void if (sock->socket == -1) { alive = 0; } else if (php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) { - if (0 >= recv(sock->socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EWOULDBLOCK) { + ret = recv(sock->socket, &buf, sizeof(buf), MSG_PEEK); + if (0 > ret && php_socket_errno() != EWOULDBLOCK && php_socket_errno() != EAGAIN) { + alive = 0; + } + if (0 == ret) { alive = 0; } }