AC_DEFINE(HAVE_IPV6,1,[Whether to enable IPv6 support])
fi
+AC_MSG_CHECKING([how big to make fd sets])
+AC_ARG_ENABLE(fd-setsize,
+[ --enable-fd-setsize Set size of descriptor sets],[
+ if test "x$enableval" != "xyes"; then
+ CPPFLAGS="$CPPFLAGS -DFD_SETSIZE=$enableval"
+ AC_MSG_RESULT(using $enableval)
+ else
+ AC_MSG_RESULT(using system default)
+ fi
+],[
+ AC_MSG_RESULT(using system default)
+])
+
AC_MSG_CHECKING([whether to enable versioning])
AC_ARG_ENABLE(versioning,
[ --enable-versioning Export only required symbols.
int
my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
{
- fd_set write_set;
- struct timeval tv;
int n, size, sent;
size = len;
while (size) {
- tv.tv_sec = ftp->timeout_sec;
- tv.tv_usec = 0;
-
- FD_ZERO(&write_set);
- FD_SET(s, &write_set);
-
- n = select(s + 1, NULL, &write_set, NULL, &tv);
+ n = php_pollfd_for_ms(s, POLLOUT, ftp->timeout_sec * 1000);
if (n < 1) {
int
my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
{
- fd_set read_set;
- struct timeval tv;
int n, nr_bytes;
- tv.tv_sec = ftp->timeout_sec;
- tv.tv_usec = 0;
-
- FD_ZERO(&read_set);
- FD_SET(s, &read_set);
-
- n = select(s + 1, &read_set, NULL, NULL, &tv);
+ n = php_pollfd_for_ms(s, PHP_POLLREADABLE, ftp->timeout_sec * 1000);
if (n < 1) {
#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK))
if (n == 0) {
int
data_available(ftpbuf_t *ftp, php_socket_t s)
{
- fd_set read_set;
- struct timeval tv;
int n;
- tv.tv_sec = 0;
- tv.tv_usec = 1;
-
- FD_ZERO(&read_set);
- FD_SET(s, &read_set);
- n = select(s + 1, &read_set, NULL, NULL, &tv);
+ n = php_pollfd_for_ms(s, PHP_POLLREADABLE, 1000);
if (n < 1) {
#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK))
if (n == 0) {
int
data_writeable(ftpbuf_t *ftp, php_socket_t s)
{
- fd_set write_set;
- struct timeval tv;
int n;
- tv.tv_sec = 0;
- tv.tv_usec = 1;
-
- FD_ZERO(&write_set);
- FD_SET(s, &write_set);
- n = select(s + 1, NULL, &write_set, NULL, &tv);
+ n = php_pollfd_for_ms(s, POLLOUT, 1000);
if (n < 1) {
#ifndef PHP_WIN32
if (n == 0) {
int
my_accept(ftpbuf_t *ftp, php_socket_t s, struct sockaddr *addr, socklen_t *addrlen)
{
- fd_set accept_set;
- struct timeval tv;
int n;
- tv.tv_sec = ftp->timeout_sec;
- tv.tv_usec = 0;
- FD_ZERO(&accept_set);
- FD_SET(s, &accept_set);
-
- n = select(s + 1, &accept_set, NULL, NULL, &tv);
+ n = php_pollfd_for_ms(s, PHP_POLLREADABLE, ftp->timeout_sec * 1000);
if (n < 1) {
#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK))
if (n == 0) {
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
#ifdef PHP_WIN32
- fd_set wrfds, efds;
int n;
- struct timeval timeout;
#endif
if (close_handle) {
if (sslsock->ssl_active) {
SSL_free(sslsock->ssl_handle);
sslsock->ssl_handle = NULL;
}
- if (sslsock->s.socket != -1) {
+ if (sslsock->s.socket != SOCK_ERR) {
#ifdef PHP_WIN32
/* prevent more data from coming in */
shutdown(sslsock->s.socket, SHUT_RD);
* but at the same time avoid hanging indefintely.
* */
do {
- FD_ZERO(&wrfds);
- FD_SET(sslsock->s.socket, &wrfds);
- efds = wrfds;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 5000; /* arbitrary */
-
- n = select(sslsock->s.socket + 1, NULL, &wrfds, &efds, &timeout);
+ n = php_pollfd_for_ms(sslsock->s.socket, POLLOUT, 500);
} while (n == -1 && php_socket_errno() == EINTR);
#endif
-
closesocket(sslsock->s.socket);
- sslsock->s.socket = -1;
+ sslsock->s.socket = SOCK_ERR;
}
}
char buf;
int alive = 1;
- if (sslsock->s.timeout.tv_sec == -1) {
- tv.tv_sec = FG(default_socket_timeout);
+ if (value == -1) {
+ if (sslsock->s.timeout.tv_sec == -1) {
+ tv.tv_sec = FG(default_socket_timeout);
+ tv.tv_usec = 0;
+ } else {
+ tv = sslsock->s.timeout;
+ }
} else {
- tv = sslsock->s.timeout;
+ tv.tv_sec = value;
+ tv.tv_usec = 0;
}
if (sslsock->s.socket == -1) {
alive = 0;
- } else {
- FD_ZERO(&rfds);
- FD_SET(sslsock->s.socket, &rfds);
-
- if (select(sslsock->s.socket + 1, &rfds, NULL, NULL, &tv) > 0 && FD_ISSET(sslsock->s.socket, &rfds)) {
- if (sslsock->ssl_active) {
- int n;
-
- do {
- n = SSL_peek(sslsock->ssl_handle, &buf, sizeof(buf));
- if (n <= 0) {
- int err = SSL_get_error(sslsock->ssl_handle, n);
-
- if (err == SSL_ERROR_SYSCALL) {
- alive = php_socket_errno() == EAGAIN;
- break;
- }
-
- if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
- /* re-negotiate */
- continue;
- }
-
- /* any other problem is a fatal error */
- alive = 0;
+ } else if (php_pollfd_for(sslsock->s.socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
+ if (sslsock->ssl_active) {
+ int n;
+
+ do {
+ n = SSL_peek(sslsock->ssl_handle, &buf, sizeof(buf));
+ if (n <= 0) {
+ int err = SSL_get_error(sslsock->ssl_handle, n);
+
+ if (err == SSL_ERROR_SYSCALL) {
+ alive = php_socket_errno() == EAGAIN;
+ break;
}
- /* either peek succeeded or there was an error; we
- * have set the alive flag appropriately */
- break;
- } while (1);
- } else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
- alive = 0;
- }
+
+ if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
+ /* re-negotiate */
+ continue;
+ }
+
+ /* any other problem is a fatal error */
+ alive = 0;
+ }
+ /* either peek succeeded or there was an error; we
+ * have set the alive flag appropriately */
+ break;
+ } while (1);
+ } else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
+ alive = 0;
}
}
return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
static int stream_alive(php_stream *stream TSRMLS_DC)
{
int socket;
- fd_set rfds;
- struct timeval tv;
char buf;
+ /* maybe better to use:
+ * php_stream_set_option(stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL)
+ * here instead */
+
if (stream == NULL || stream->eof || php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void**)&socket, 0) != SUCCESS) {
return FALSE;
}
if (socket == -1) {
return FALSE;
} else {
- FD_ZERO(&rfds);
- FD_SET(socket, &rfds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- if (select(socket + 1, &rfds, NULL, NULL, &tv) > 0 && FD_ISSET(socket, &rfds)) {
+ if (php_pollfd_for_ms(socket, PHP_POLLREADABLE, 0) > 0) {
if (0 == recv(socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
return FALSE;
}
if (peername) {
zval_dtor(peername);
- ZVAL_STRING(peername, "", 1);
+ ZVAL_STRING(peername, NULL, 0);
}
if (0 == php_stream_xport_accept(stream, &clistream,
if (errstr) {
efree(errstr);
}
+
+ if (peername && Z_STRVAL_P(peername) == NULL) {
+ ZVAL_STRING(peername, "", 1);
+ }
}
/* }}} */
* is not displayed.
* */
if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) {
- FD_SET(this_fd, fds);
+
+ PHP_SAFE_FD_SET(this_fd, fds);
+
if (this_fd > *max_fd) {
*max_fd = this_fd;
}
* is not displayed.
*/
if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) {
- if (FD_ISSET(this_fd, fds)) {
+ if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
if (dest_elem) {
zval_add_ref(dest_elem);
int max_fd = 0;
int retval, sets = 0;
long usec = 0;
+ int set_count, max_set_count = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE)
return;
FD_ZERO(&wfds);
FD_ZERO(&efds);
- if (r_array != NULL) sets += stream_array_to_fd_set(r_array, &rfds, &max_fd TSRMLS_CC);
- if (w_array != NULL) sets += stream_array_to_fd_set(w_array, &wfds, &max_fd TSRMLS_CC);
- if (e_array != NULL) sets += stream_array_to_fd_set(e_array, &efds, &max_fd TSRMLS_CC);
+ if (r_array != NULL) {
+ set_count = stream_array_to_fd_set(r_array, &rfds, &max_fd TSRMLS_CC);
+ if (set_count > max_set_count)
+ max_set_count = set_count;
+ sets += set_count;
+ }
+
+ if (w_array != NULL) {
+ set_count = stream_array_to_fd_set(w_array, &wfds, &max_fd TSRMLS_CC);
+ if (set_count > max_set_count)
+ max_set_count = set_count;
+ sets += set_count;
+ }
+
+ if (e_array != NULL) {
+ set_count = stream_array_to_fd_set(e_array, &efds, &max_fd TSRMLS_CC);
+ if (set_count > max_set_count)
+ max_set_count = set_count;
+ sets += set_count;
+ }
if (!sets) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were passed");
RETURN_FALSE;
}
+ PHP_SAFE_MAX_FD(max_fd, max_set_count);
+
/* If seconds is not set to null, build the timeval, else we wait indefinitely */
if (sec != NULL) {
convert_to_long_ex(&sec);
int error = 0;
socklen_t len;
int ret = 0;
- fd_set rset;
- fd_set wset;
- fd_set eset;
SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags);
goto ok;
}
- FD_ZERO(&rset);
- FD_ZERO(&eset);
- FD_SET(sockfd, &rset);
- FD_SET(sockfd, &eset);
-
- wset = rset;
-
- if ((n = select(sockfd + 1, &rset, &wset, &eset, timeout)) == 0) {
+ if ((n = php_pollfd_for(sockfd, PHP_POLLREADABLE|POLLOUT, timeout)) == 0) {
error = PHP_TIMEOUT_ERROR_VALUE;
}
- if(FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+ if (n > 0) {
len = sizeof(error);
/*
BSD-derived systems set errno correctly
TSRMLS_DC)
{
php_socket_t clisock = -1;
- fd_set rset;
int error = 0, n;
php_sockaddr_storage sa;
socklen_t sl;
-
- FD_ZERO(&rset);
- FD_SET(srvsock, &rset);
- n = select(srvsock + 1, &rset, NULL, NULL, timeout);
+ n = php_pollfd_for(srvsock, PHP_POLLREADABLE, timeout);
if (n == 0) {
error = PHP_TIMEOUT_ERROR_VALUE;
} else if (n == -1) {
error = php_socket_errno();
- } else if (FD_ISSET(srvsock, &rset)) {
+ } else {
sl = sizeof(sa);
clisock = accept(srvsock, (struct sockaddr*)&sa, &sl);
return ret;
}
+PHPAPI void _php_emit_fd_setsize_warning(int max_fd)
+{
+ TSRMLS_FETCH();
+
+#ifdef PHP_WIN32
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "PHP needs to be recompiled with a larger value of FD_SETSIZE.\n"
+ "If this binary is from an official www.php.net package, file a bug report\n"
+ "at http://bugs.php.net, including the following information:\n"
+ "FD_SETSIZE=%d, but you are using %d.\n"
+ " --enable-fd-setsize=%d is recommended, but you may want to set it\n"
+ "to match to maximum number of sockets each script will work with at\n"
+ "one time, in order to avoid seeing this error again at a later date.",
+ FD_SETSIZE, max_fd, (max_fd + 128) & ~127);
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "You MUST recompile PHP with a larger value of FD_SETSIZE.\n"
+ "It is set to %d, but you have descriptors numbered at least as high as %d.\n"
+ " --enable-fd-setsize=%d is recommended, but you may want to set it\n"
+ "to equal the maximum number of open files supported by your system,\n"
+ "in order to avoid seeing this error again at a later date.",
+ FD_SETSIZE, max_fd, (max_fd + 1024) & ~1023);
+#endif
+}
+
+#if defined(PHP_USE_POLL_2_EMULATION)
+
+/* emulate poll(2) using select(2), safely. */
+
+PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout)
+{
+ fd_set rset, wset, eset;
+ php_socket_t max_fd = SOCK_ERR;
+ unsigned int i, n;
+ struct timeval tv;
+
+ /* check the highest numbered descriptor */
+ for (i = 0; i < nfds; i++) {
+ if (ufds[i].fd > max_fd)
+ max_fd = ufds[i].fd;
+ }
+
+ PHP_SAFE_MAX_FD(max_fd, nfds + 1);
+
+ FD_ZERO(&rset);
+ FD_ZERO(&wset);
+ FD_ZERO(&eset);
+
+ for (i = 0; i < nfds; i++) {
+ if (ufds[i].events & PHP_POLLREADABLE) {
+ PHP_SAFE_FD_SET(ufds[i].fd, &rset);
+ }
+ if (ufds[i].events & POLLOUT) {
+ PHP_SAFE_FD_SET(ufds[i].fd, &wset);
+ }
+ if (ufds[i].events & POLLPRI) {
+ PHP_SAFE_FD_SET(ufds[i].fd, &eset);
+ }
+ }
+
+ if (timeout >= 0) {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout - (tv.tv_sec * 1000)) * 1000;
+ }
+ n = select(max_fd + 1, &rset, &wset, &eset, timeout >= 0 ? &tv : NULL);
+
+ if (n >= 0) {
+ for (i = 0; i < nfds; i++) {
+ ufds[i].revents = 0;
+
+ if (PHP_SAFE_FD_ISSET(ufds[i].fd, &rset)) {
+ /* could be POLLERR or POLLHUP but can't tell without probing */
+ ufds[i].revents |= POLLIN;
+ }
+ if (PHP_SAFE_FD_ISSET(ufds[i].fd, &wset)) {
+ ufds[i].revents |= POLLOUT;
+ }
+ if (PHP_SAFE_FD_ISSET(ufds[i].fd, &eset)) {
+ ufds[i].revents |= POLLPRI;
+ }
+ }
+ }
+ return n;
+}
+
+#endif
+
/*
* Local variables:
# define SOCK_RECV_ERR -1
#endif
+/* uncomment this to debug poll(2) emulation on systems that have poll(2) */
+/* #define PHP_USE_POLL_2_EMULATION 1 */
+
+#if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL)
+# include <sys/poll.h>
+typedef struct pollfd php_pollfd;
+#else
+typedef struct _php_pollfd {
+ php_socket_t fd;
+ short events;
+ short revents;
+} php_pollfd;
+
+PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout);
+
+# define POLLIN 0x0001 /* There is data to read */
+# define POLLPRI 0x0002 /* There is urgent data to read */
+# define POLLOUT 0x0004 /* Writing now will not block */
+# define POLLERR 0x0008 /* Error condition */
+# define POLLHUP 0x0010 /* Hung up */
+# define POLLNVAL 0x0020 /* Invalid request: fd not open */
+
+# ifndef PHP_USE_POLL_2_EMULATION
+# define PHP_USE_POLL_2_EMULATION 1
+# endif
+#endif
+
+#define PHP_POLLREADABLE (POLLIN|POLLERR|POLLHUP)
+
+#ifndef PHP_USE_POLL_2_EMULATION
+# define php_poll2(ufds, nfds, timeout) poll(ufds, nfds, timeout)
+#endif
+
+/* timeval-to-timeout (for poll(2)) */
+static inline int php_tvtoto(struct timeval *timeouttv)
+{
+ if (timeouttv) {
+ return (timeouttv->tv_sec * 1000) + (timeouttv->tv_usec / 1000);
+ }
+ return -1;
+}
+
+/* hybrid select(2)/poll(2) for a single descriptor.
+ * timeouttv follows same rules as select(2), but is reduced to millisecond accuracy.
+ * Returns 0 on timeout, -1 on error, or the event mask (ala poll(2)).
+ */
+static inline int php_pollfd_for(php_socket_t fd, int events, struct timeval *timeouttv)
+{
+ php_pollfd p;
+ int n;
+
+ p.fd = fd;
+ p.events = events;
+ p.revents = 0;
+
+ n = php_poll2(&p, 1, php_tvtoto(timeouttv));
+
+ if (n > 0) {
+ return p.revents;
+ }
+
+ return n;
+}
+
+static inline int php_pollfd_for_ms(php_socket_t fd, int events, int timeout)
+{
+ php_pollfd p;
+ int n;
+
+ p.fd = fd;
+ p.events = events;
+ p.revents = 0;
+
+ n = php_poll2(&p, 1, timeout);
+
+ if (n > 0) {
+ return p.revents;
+ }
+
+ return n;
+}
+
+/* emit warning and suggestion for unsafe select(2) usage */
+PHPAPI void _php_emit_fd_setsize_warning(int max_fd);
+
+#ifdef PHP_WIN32
+/* it is safe to FD_SET too many fd's under win32; the macro will simply ignore
+ * descriptors that go beyond the default FD_SETSIZE */
+# define PHP_SAFE_FD_SET(fd, set) FD_SET(fd, set)
+# define PHP_SAFE_FD_ISSET(fd, set) FD_ISSET(fd, set)
+# define PHP_SAFE_MAX_FD(m, n) do { if (n + 1 >= FD_SETSIZE) { _php_emit_fd_setsize_warning(n); }} while(0)
+#else
+# define PHP_SAFE_FD_SET(fd, set) do { if (fd < FD_SETSIZE) FD_SET(fd, set); } while(0)
+# define PHP_SAFE_FD_ISSET(fd, set) ((fd < FD_SETSIZE) && FD_ISSET(fd, set))
+# define PHP_SAFE_MAX_FD(m, n) do { if (m >= FD_SETSIZE) { _php_emit_fd_setsize_warning(m); m = FD_SETSIZE - 1; }} while(0)
+#endif
+
+
#define PHP_SOCK_CHUNK_SIZE 8192
#ifdef HAVE_SOCKADDR_STORAGE
{
php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract;
int didwrite;
+ struct timeval *ptimeout;
if (sock->socket == -1) {
return 0;
}
+ if (sock->timeout.tv_sec == -1)
+ ptimeout = NULL;
+ else
+ ptimeout = &sock->timeout;
+
retry:
didwrite = send(sock->socket, buf, count, 0);
char *estr;
if (sock->is_blocked && err == EWOULDBLOCK) {
- fd_set fdw, tfdw;
int retval;
- struct timeval timeout, *ptimeout;
- FD_ZERO(&fdw);
- FD_SET(sock->socket, &fdw);
sock->timeout_event = 0;
- if (sock->timeout.tv_sec == -1)
- ptimeout = NULL;
- else
- ptimeout = &timeout;
-
do {
- tfdw = fdw;
- timeout = sock->timeout;
-
- retval = select(sock->socket + 1, NULL, &tfdw, NULL, ptimeout);
+ retval = php_pollfd_for(sock->socket, POLLOUT, ptimeout);
if (retval == 0) {
sock->timeout_event = 1;
static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data_t *sock TSRMLS_DC)
{
- fd_set fdr, tfdr;
int retval;
- struct timeval timeout, *ptimeout;
+ struct timeval *ptimeout;
if (sock->socket == -1) {
return;
}
- FD_ZERO(&fdr);
- FD_SET(sock->socket, &fdr);
sock->timeout_event = 0;
if (sock->timeout.tv_sec == -1)
ptimeout = NULL;
else
- ptimeout = &timeout;
-
+ ptimeout = &sock->timeout;
while(1) {
- tfdr = fdr;
- timeout = sock->timeout;
-
- retval = select(sock->socket + 1, &tfdr, NULL, NULL, ptimeout);
+ retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout);
if (retval == 0)
sock->timeout_event = 1;
if (retval >= 0)
break;
+
+ if (php_socket_errno() != EINTR)
+ break;
}
}
{
php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract;
#ifdef PHP_WIN32
- fd_set wrfds, efds;
int n;
- struct timeval timeout;
#endif
if (close_handle) {
- if (sock->socket != -1) {
+ if (sock->socket != SOCK_ERR) {
#ifdef PHP_WIN32
/* prevent more data from coming in */
shutdown(sock->socket, SHUT_RD);
* but at the same time avoid hanging indefintely.
* */
do {
- FD_ZERO(&wrfds);
- FD_SET(sock->socket, &wrfds);
- efds = wrfds;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 5000; /* arbitrary */
-
- n = select(sock->socket + 1, NULL, &wrfds, &efds, &timeout);
+ n = php_pollfd_for_ms(sock->socket, POLLOUT, 500);
} while (n == -1 && php_socket_errno() == EINTR);
#endif
-
closesocket(sock->socket);
- sock->socket = -1;
+ sock->socket = SOCK_ERR;
}
}
switch(option) {
case PHP_STREAM_OPTION_CHECK_LIVENESS:
{
- fd_set rfds;
struct timeval tv;
char buf;
int alive = 1;
if (sock->socket == -1) {
alive = 0;
- } else {
- FD_ZERO(&rfds);
- FD_SET(sock->socket, &rfds);
-
- if (select(sock->socket + 1, &rfds, NULL, NULL, &tv) > 0 && FD_ISSET(sock->socket, &rfds)) {
- if (0 == recv(sock->socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
- 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() != EAGAIN) {
+ alive = 0;
}
}
return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
AC_DEFINE('HAVE_GAI_STRERROR', main_network_has_ipv6);
AC_DEFINE('HAVE_IPV6', main_network_has_ipv6);
+/* this allows up to 256 sockets to be select()ed in a single
+ * call to select(), instead of the usual 64 */
+ARG_ENABLE('fd-setsize', "Set maximum number of sockets for select(2)", "256");
+ADD_FLAG("CFLAGS", "/D FD_SETSIZE=" + parseInt(PHP_FD_SETSIZE));
+
ARG_ENABLE("memory-limit", "Enable memory limit checking code", "no");
AC_DEFINE('MEMORY_LIMIT', PHP_MEMORY_LIMIT == "yes" ? 1 : 0);
AC_DEFINE('HAVE_USLEEP', 1);
+AC_DEFINE('HAVE_STRCOLL', 1);
/* For snapshot builders, where can we find the additional
* files that make up the snapshot template? */