summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-02-16 03:48:49 +0000
committerWez Furlong <wez@php.net>2003-02-16 03:48:49 +0000
commit0a18a9d744afb9d97d46bad1f40c11a047bad5df (patch)
tree993ffad34c5dc4fb92e92b559e13cc95f2f32145 /ext
parent5edec2a91005a4c378c56801585c89029926c5b3 (diff)
downloadphp-git-0a18a9d744afb9d97d46bad1f40c11a047bad5df.tar.gz
A add much more useful select(2) implementation than is provided by
windows sockets. The winsock implementation will only work with sockets; our implementation works with sockets and file descriptors. By association, stream_select() will now operate correctly with files, pipes and sockets. This change required linking against the winsock2 library. In terms of compatibility, only older versions of windows 95 do not have winsock2 installed by default. It is available as a redistributable file, and is most likely installed by any OS patches (eg: Internet Explorer) applied by the user. Also, add a win32 compatible pipe test when opening a stream from a pipe. This test will only work on NT, win2k and XP platforms. Without this test, interleaved fread() and select() calls would cause the read buffer to be clobbered. I will be working on a fix for this issue for win9x.
Diffstat (limited to 'ext')
-rw-r--r--ext/curl/interface.c2
-rw-r--r--ext/curl/streams.c2
-rw-r--r--ext/fbsql/php_fbsql.c2
-rw-r--r--ext/ftp/ftp.c2
-rw-r--r--ext/hyperwave/hg_comm.c2
-rw-r--r--ext/hyperwave/hw.c2
-rw-r--r--ext/imap/php_imap.c2
-rw-r--r--ext/ldap/ldap.c2
-rw-r--r--ext/mcal/php_mcal.c2
-rw-r--r--ext/mysql/php_mysql.c2
-rw-r--r--ext/odbc/php_odbc.c2
-rw-r--r--ext/rpc/com/com_wrapper.c6
-rw-r--r--ext/snmp/snmp.c2
-rw-r--r--ext/standard/dns.c2
-rw-r--r--ext/standard/file.c162
-rw-r--r--ext/standard/fsock.c2
-rw-r--r--ext/standard/ftp_fopen_wrapper.c4
-rw-r--r--ext/standard/http_fopen_wrapper.c4
-rw-r--r--ext/standard/pack.c2
-rw-r--r--ext/zlib/zlib.c2
20 files changed, 181 insertions, 27 deletions
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 2b5c48a61e..3286543f51 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -30,7 +30,7 @@
#include <string.h>
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#include <sys/types.h>
#endif
diff --git a/ext/curl/streams.c b/ext/curl/streams.c
index 58695bd50a..ed57749318 100644
--- a/ext/curl/streams.c
+++ b/ext/curl/streams.c
@@ -36,7 +36,7 @@
#include <string.h>
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#include <sys/types.h>
#endif
diff --git a/ext/fbsql/php_fbsql.c b/ext/fbsql/php_fbsql.c
index df19e70a9d..0b278f2d02 100644
--- a/ext/fbsql/php_fbsql.c
+++ b/ext/fbsql/php_fbsql.c
@@ -43,7 +43,7 @@
#include "ext/standard/php_string.h"
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#else
#include <php_config.h>
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
index 1ebce4e470..233c832508 100644
--- a/ext/ftp/ftp.c
+++ b/ext/ftp/ftp.c
@@ -33,7 +33,7 @@
#include <string.h>
#include <time.h>
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#elif defined(NETWARE)
#ifdef USE_WINSOCK /* Modified to use Winsock (NOVSOCK2.H), atleast for now */
#include <novsock2.h>
diff --git a/ext/hyperwave/hg_comm.c b/ext/hyperwave/hg_comm.c
index 856b1c1bfa..5aaae3dcfd 100644
--- a/ext/hyperwave/hg_comm.c
+++ b/ext/hyperwave/hg_comm.c
@@ -31,7 +31,7 @@
#include <string.h>
#include <sys/types.h>
#ifdef PHP_WIN32
-# include <winsock.h>
+# include <winsock2.h>
# define EWOULDBLOCK WSAEWOULDBLOCK
# define ETIMEDOUT WSAETIMEDOUT
# define bcopy memcpy
diff --git a/ext/hyperwave/hw.c b/ext/hyperwave/hw.c
index 4975b9586f..8859e13952 100644
--- a/ext/hyperwave/hw.c
+++ b/ext/hyperwave/hw.c
@@ -34,7 +34,7 @@
#include "SAPI.h"
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#endif
#if HYPERWAVE
diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
index e43f513f98..77c9aceb2a 100644
--- a/ext/imap/php_imap.c
+++ b/ext/imap/php_imap.c
@@ -50,7 +50,7 @@
#include <signal.h>
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#include <stdlib.h>
#include "win32/sendmail.h"
MAILSTREAM DEFAULTPROTO;
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
index 96adc911d3..a4dbca40bc 100644
--- a/ext/ldap/ldap.c
+++ b/ext/ldap/ldap.c
@@ -46,7 +46,7 @@
#ifdef PHP_WIN32
#include <string.h>
#if HAVE_NSLDAP
-#include <winsock.h>
+#include <winsock2.h>
#endif
#define strdup _strdup
#undef WINDOWS
diff --git a/ext/mcal/php_mcal.c b/ext/mcal/php_mcal.c
index 6ecd3a5419..3ef97c5683 100644
--- a/ext/mcal/php_mcal.c
+++ b/ext/mcal/php_mcal.c
@@ -42,7 +42,7 @@
#include "ext/standard/info.h"
#include "ext/standard/basic_functions.h"
#ifdef PHP_WIN32
-#include "winsock.h"
+#include "winsock2.h"
#endif
static void cal_close_it(zend_rsrc_list_entry *rsrc TSRMLS_DC);
diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c
index ef46b204a0..6a493ba3a1 100644
--- a/ext/mysql/php_mysql.c
+++ b/ext/mysql/php_mysql.c
@@ -37,7 +37,7 @@
#if HAVE_MYSQL
#ifdef PHP_WIN32
-# include <winsock.h>
+# include <winsock2.h>
# define signal(a, b) NULL
#elif defined(NETWARE)
# include <sys/socket.h>
diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index 5583a4dfcb..ba473e8911 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -44,7 +44,7 @@
#include "php_ini.h"
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#define ODBC_TYPE "Win32"
#define PHP_ODBC_TYPE ODBC_TYPE
diff --git a/ext/rpc/com/com_wrapper.c b/ext/rpc/com/com_wrapper.c
index 1c27c4d774..04e9a74f08 100644
--- a/ext/rpc/com/com_wrapper.c
+++ b/ext/rpc/com/com_wrapper.c
@@ -56,13 +56,13 @@
#define _WIN32_DCOM
+#include "php.h"
+#include "php_ini.h"
+
#include <iostream.h>
#include <math.h>
#include <ocidl.h>
-#include "php.h"
-#include "php_ini.h"
-
#include "../rpc.h"
#include "../php_rpc.h"
#include "../handler.h"
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index 6f95b28772..ad76753633 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -33,7 +33,7 @@
#include <sys/types.h>
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#include <errno.h>
#include <process.h>
#include "win32/time.h"
diff --git a/ext/standard/dns.c b/ext/standard/dns.c
index 32641382fa..916ff4637d 100644
--- a/ext/standard/dns.c
+++ b/ext/standard/dns.c
@@ -44,7 +44,7 @@
#include "resolv.h"
#endif
#endif /* HAVE_LIBBIND */
-#include <winsock.h>
+#include <winsock2.h>
#else /* This holds good for NetWare too, both for Winsock and Berkeley sockets */
#include <netinet/in.h>
#if HAVE_ARPA_INET_H
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 25d1257330..d5024cc396 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -44,7 +44,7 @@
#include <fcntl.h>
#ifdef PHP_WIN32
#include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
#define O_RDONLY _O_RDONLY
#include "win32/param.h"
#include "win32/winutil.h"
@@ -821,6 +821,160 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC)
}
/* }}} */
+#ifdef PHP_WIN32
+/* Win32 select() will only work with sockets, so we roll our own implementation that will
+ * get the OS file handle from regular fd's and sockets and then use WaitForMultipleObjects().
+ * This implementation is not as feature-full as posix select, but it works for our purposes
+ */
+static int php_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
+{
+ HANDLE *handles;
+ DWORD ms, waitret;
+ DWORD ms_total;
+ int i, f, s, fd_count = 0, sock_count = 0;
+ int retval;
+ fd_set ard, awr, aex; /* active fd sets */
+ long sock_events;
+
+ for (i = 0; i < max_fd; i++) {
+ if (FD_ISSET(i, rfds) || FD_ISSET(i, wfds) || FD_ISSET(i, efds)) {
+ if (_get_osfhandle(i) == 0xffffffff) {
+ /* it is a socket */
+ sock_count++;
+ } else {
+ fd_count++;
+ }
+ }
+ }
+
+ if (fd_count + sock_count == 0) {
+ return 0;
+ }
+
+ handles = (HANDLE*)emalloc((fd_count + sock_count) * sizeof(HANDLE));
+
+ /* populate the events and handles arrays */
+ f = 0;
+ s = 0;
+ for (i = 0; i < max_fd; i++) {
+ if (FD_ISSET(i, rfds) || FD_ISSET(i, wfds) || FD_ISSET(i, efds)) {
+ long h = _get_osfhandle(i);
+ if (h == 0xFFFFFFFF) {
+ HANDLE evt;
+ long evt_flags = 0;
+
+ if (FD_ISSET(i, rfds)) {
+ evt_flags |= FD_READ|FD_CONNECT|FD_ACCEPT|FD_CLOSE;
+ }
+ if (FD_ISSET(i, wfds)) {
+ evt_flags |= FD_WRITE;
+ }
+ if (FD_ISSET(i, efds)) {
+ evt_flags |= FD_OOB;
+ }
+
+ evt = WSACreateEvent();
+ WSAEventSelect(i, evt, evt_flags);
+
+ handles[fd_count + s] = evt;
+ s++;
+ } else {
+ handles[f++] = (HANDLE)h;
+ }
+ }
+ }
+
+ /* calculate how long we need to wait in milliseconds */
+ if (tv == NULL) {
+ ms_total = INFINITE;
+ } else {
+ ms_total = tv->tv_sec * 1000;
+ ms_total += tv->tv_usec / 1000;
+ }
+
+ waitret = MsgWaitForMultipleObjects(fd_count + sock_count, handles, FALSE, ms_total, QS_ALLEVENTS);
+
+ if (waitret == WAIT_TIMEOUT) {
+ retval = 0;
+ } else if (waitret == 0xFFFFFFFF) {
+ retval = -1;
+ } else {
+
+ FD_ZERO(&ard);
+ FD_ZERO(&awr);
+ FD_ZERO(&aex);
+
+ f = 0;
+ retval = 0;
+ for (i = 0; i < max_fd; i++) {
+ if (FD_ISSET(i, rfds) || FD_ISSET(i, wfds) || FD_ISSET(i, efds)) {
+ if (f >= fd_count) {
+ /* socket event */
+ HANDLE evt = handles[f];
+
+ if (WAIT_OBJECT_0 == WaitForSingleObject(evt, 0)) {
+ /* check for various signal states */
+ if (FD_ISSET(i, rfds)) {
+ WSAEventSelect(i, evt, FD_READ|FD_CONNECT|FD_ACCEPT|FD_CLOSE);
+ if (WAIT_OBJECT_0 == WaitForSingleObject(evt, 0)) {
+ FD_SET(i, &ard);
+ }
+ }
+ if (FD_ISSET(i, wfds)) {
+ WSAEventSelect(i, evt, FD_WRITE);
+ if (WAIT_OBJECT_0 == WaitForSingleObject(evt, 0)) {
+ FD_SET(i, &awr);
+ }
+ }
+ if (FD_ISSET(i, efds)) {
+ WSAEventSelect(i, evt, FD_OOB);
+ if (WAIT_OBJECT_0 == WaitForSingleObject(evt, 0)) {
+ FD_SET(i, &aex);
+ }
+ }
+ retval++;
+ }
+
+ WSACloseEvent(evt);
+
+ } else {
+ if (WAIT_OBJECT_0 == WaitForSingleObject(handles[f], 0)) {
+ if (FD_ISSET(i, rfds)) {
+ FD_SET(i, &ard);
+ }
+ if (FD_ISSET(i, wfds)) {
+ FD_SET(i, &awr);
+ }
+ if (FD_ISSET(i, efds)) {
+ FD_SET(i, &aex);
+ }
+ retval++;
+ }
+
+ }
+ f++;
+ }
+ }
+
+ if (rfds) {
+ *rfds = ard;
+ }
+ if (wfds) {
+ *wfds = awr;
+ }
+ if (efds) {
+ *efds = aex;
+ }
+ }
+
+ efree(handles);
+
+ return retval;
+}
+#else
+#define php_select(m, r, w, e, t) select(m, r, w, e, t)
+#endif
+
/* {{{ proto int stream_select(array &read_streams, array &write_streams, array &except_streams, int tv_sec[, int tv_usec])
Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec */
PHP_FUNCTION(stream_select)
@@ -867,11 +1021,11 @@ PHP_FUNCTION(stream_select)
}
}
- retval = select(max_fd+1, &rfds, &wfds, &efds, tv_p);
+ retval = php_select(max_fd+1, &rfds, &wfds, &efds, tv_p);
if (retval == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: %s",
- errno, strerror(errno));
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: %s (max_fd=%d)",
+ errno, strerror(errno), max_fd);
RETURN_FALSE;
}
diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c
index d1f37a46dc..bbe6d7debb 100644
--- a/ext/standard/fsock.c
+++ b/ext/standard/fsock.c
@@ -46,7 +46,7 @@
#include <sys/socket.h>
#endif
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#elif defined(NETWARE)
#ifdef NEW_LIBC
#ifdef USE_WINSOCK
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index c68ff5fcf3..a603b464b3 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -32,7 +32,7 @@
#ifdef PHP_WIN32
#include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
#define O_RDONLY _O_RDONLY
#include "win32/param.h"
#elif defined(NETWARE)
@@ -55,7 +55,7 @@
#endif
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#elif defined(NETWARE) && defined(USE_WINSOCK)
/*#include <ws2nlm.h>*/
#include <novsock2.h>
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 55f9ef26c0..d12c61b5f5 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -36,7 +36,7 @@
#ifdef PHP_WIN32
#include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
#define O_RDONLY _O_RDONLY
#include "win32/param.h"
#elif defined(NETWARE)
@@ -59,7 +59,7 @@
#endif
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <winsock2.h>
#elif defined(NETWARE) && defined(USE_WINSOCK)
/*#include <ws2nlm.h>*/
#include <novsock2.h>
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index 0002aaeb37..755665d636 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -27,7 +27,7 @@
#include <fcntl.h>
#ifdef PHP_WIN32
#include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
#define O_RDONLY _O_RDONLY
#include "win32/param.h"
#elif defined(NETWARE)
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 3a2c13e2d8..b04ca107eb 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -36,7 +36,7 @@
#include <fcntl.h>
#ifdef PHP_WIN32
#include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
#define O_RDONLY _O_RDONLY
#include "win32/param.h"
#else