From ccb5c84b6c5014d5f01746b84c3ce3dcd296f7c8 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Fri, 9 Aug 2002 21:02:36 +0000 Subject: [PATCH] Centralize some blocking socket related code. # It's been a while since I wrote this! --- configure.in | 1 + ext/standard/file.c | 41 --------------------------------- main/network.c | 55 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/configure.in b/configure.in index ddccc16475..129fdfeb2c 100644 --- a/configure.in +++ b/configure.in @@ -447,6 +447,7 @@ memmove \ mkstemp \ mmap \ nl_langinfo \ +poll \ putenv \ realpath \ random \ diff --git a/ext/standard/file.c b/ext/standard/file.c index 58e1245421..e5ea504fc1 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -956,44 +956,12 @@ PHPAPI PHP_FUNCTION(feof) } /* }}} */ -/* TODO: move to main/network.c */ -PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC) -{ - int ret = SUCCESS; - int flags; - int myflag = 0; - -#ifdef PHP_WIN32 - /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ - flags = !block; - if (ioctlsocket(socketd, FIONBIO, &flags)==SOCKET_ERROR){ - php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), WSAGetLastError()); - ret = FALSE; - } -#else - flags = fcntl(socketd, F_GETFL); -#ifdef O_NONBLOCK - myflag = O_NONBLOCK; /* POSIX version */ -#elif defined(O_NDELAY) - myflag = O_NDELAY; /* old non-POSIX version */ -#endif - if (!block) { - flags |= myflag; - } else { - flags &= ~myflag; - } - fcntl(socketd, F_SETFL, flags); -#endif - return ret; -} - /* {{{ proto bool socket_set_blocking(resource socket, int mode) Set blocking/non-blocking mode on a socket */ PHP_FUNCTION(socket_set_blocking) { zval **arg1, **arg2; int block, type; - int socketd = 0; void *what; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { @@ -1007,15 +975,6 @@ PHP_FUNCTION(socket_set_blocking) block = Z_LVAL_PP(arg2); if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - /* TODO: check if the blocking mode is changed elsewhere, and see if we - * can integrate these calls into php_stream_sock_set_blocking */ - if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_SOCKETD, (void *) &socketd, REPORT_ERRORS)) { - RETURN_FALSE; - } - - if (php_set_sock_blocking(socketd, block TSRMLS_CC) == FAILURE) - RETURN_FALSE; - php_stream_sock_set_blocking((php_stream*)what, block == 0 ? 0 : 1 TSRMLS_CC); RETURN_TRUE; } diff --git a/main/network.c b/main/network.c index c697907b31..87d0296415 100644 --- a/main/network.c +++ b/main/network.c @@ -627,6 +627,36 @@ PHPAPI void php_stream_sock_set_timeout(php_stream *stream, struct timeval *time sock->timeout_event = 0; } +PHPAPI int php_set_sock_blocking(int socketd, int block) +{ + int ret = SUCCESS; + int flags; + int myflag = 0; + +#ifdef PHP_WIN32 + /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ + flags = !block; + if (ioctlsocket(socketd, FIONBIO, &flags)==SOCKET_ERROR){ + php_error(E_WARNING, "%s", WSAGetLastError()); + ret = FALSE; + } +#else + flags = fcntl(socketd, F_GETFL); +#ifdef O_NONBLOCK + myflag = O_NONBLOCK; /* POSIX version */ +#elif defined(O_NDELAY) + myflag = O_NDELAY; /* old non-POSIX version */ +#endif + if (!block) { + flags |= myflag; + } else { + flags &= ~myflag; + } + fcntl(socketd, F_SETFL, flags); +#endif + return ret; +} + PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC) { int oldmode; @@ -636,9 +666,17 @@ PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC) return 0; oldmode = sock->is_blocked; - sock->is_blocked = mode; + + /* no need to change anything */ + if (mode == oldmode) + return oldmode; + + if (SUCCESS == php_set_sock_blocking(sock->socket, mode)) { + sock->is_blocked = mode; + return oldmode; + } - return oldmode; + return -1; } PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC) @@ -809,6 +847,8 @@ static size_t php_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS if (buf == NULL && count == 0) { /* check for EOF condition */ + int save_blocked; + DUMP_SOCK_STATE("check for EOF", sock); if (sock->eof) @@ -818,7 +858,7 @@ DUMP_SOCK_STATE("check for EOF", sock); return 0; /* no data in the buffer - lets examine the socket */ -#if HAVE_SYS_POLL_H +#if HAVE_SYS_POLL_H && HAVE_POLL { struct pollfd topoll; @@ -831,13 +871,16 @@ DUMP_SOCK_STATE("check for EOF", sock); } } #endif - + /* in the absence of other methods of checking if the - * socket is still active, try to read a chunk of data */ + * socket is still active, try to read a chunk of data, + * but lets not block. */ sock->timeout_event = 0; + save_blocked = php_stream_sock_set_blocking(stream, 1 TSRMLS_CC); php_sock_stream_read_internal(stream, sock TSRMLS_CC); + php_stream_sock_set_blocking(stream, save_blocked TSRMLS_CC); - if (sock->timeout_event || sock->eof) + if (sock->eof) return EOF; return 0; -- 2.40.0