We avoid the problem by using poll(2).
On systems without poll(2) (older bsd-ish systems, and win32), we emulate
poll(2) using select(2) and check for valid descriptors before attempting
to access them via the descriptor sets.
If an out-of-range descriptor is detected, an E_WARNING is raised suggesting
that PHP should be recompiled with a larger FD_SETSIZE (and also with a
suggested value).
Most uses of select(2) in the source are to poll a single descriptor, so
a couple of handy wrapper functions have been added to make this easier.
A configure option --enable-fd-setsize has been added to both the unix and
win32 builds; on unix we default to 16384 and on windows we default to 256.
Windows FD_SETSIZE imposes a limit on the maximum number of descriptors that
can be select()ed at once, whereas the unix FD_SETSIZE limit is based on the
highest numbered descriptor; 256 should be plenty for PHP scripts under windows
(the default OS setting is 64).
The win32 specific parts are untested; will do that now.
- This solves alot of platform compatibility problems
- The possible security issue of allocating an incredibly large vector
pool is prevented
- They are of little to no benefit in a high level language
- 99% of all things done with these functions can be done using
sendto/recvfrom
There was a memory leak in the error handling system on win32, that this patch
circumvented (by preventing the errors (EAGAIN mesages) from being generated).
# I must have forgotten to remove this when I fixed the leak
was occurring in the error reporting system. The reason why sleepex appeared
to be working was because it suppressed EWOULDBLOCK errors in the example
(which was non-blocking)
@Fix win32 memory leak in /ext/sockets that would occur on any error condition
@Fix host resolution error messages on win32
because it does not include <sys/socket.h> which is necessary
for the definition of struct msghdr. This include file is not
part of ac_includes_default.
Regardless, AC_CHECK_MEMBER is a autoconf-2.5x macro and thus we
expand it here for 2.13 compatibility.
- Force fourth argument to be passed by reference
- Since the argument is modified there is no need to force it to be an array
since it's destroyed anyway
- Only modify the argument if socketpair() was successfully
- Fix string modified for error message message
- Set global last_error when socketpair() fails
@Fixed a bug in socket_select() that could cause unexpected behavior when using a statement
@ like $w=$e=array($sock);
@This change unfortunately prevents the use of constant values(NULL) for the socket array paramaters.
@Instead use a temporary variable or an expression with the leftmost member being a temporary variable.
@ ex. socket_select($w, $r, $e=NULL, 10);
Also fix small memory leak.
- Set the global 'last_error' explicitely for functions which can't return an
error withing a single socket context (socket_create and socket_select)
- Modified socket_last_error() to return global modules last
error if no socket resource is given
- Added a couple of more E_WARNING messages in case something
goes foobar so the user isn't left alone in the dark.
Fixed bug where socket_select was not producing an error message on error
Fixed bug where -1 was getting returned instead of FALSE in socket_recv(),
socket_send(), socket_sendto(), and socket_select()
Redesigned socket_recv() as outlined on php-dev
Modified socket_last_error() to no longer clear the error
Added socket_clear_error()
Fixed socket_set_nonblock()
Added socket_set_block()
Fixed a proto
Saved 1 byte of RAM : )
Abstracted string -> ipv4 value conversion which unifies all functions
Standardized Host Lookups
Fixed Broken host error values
Fixed error detection in sendmsg
Added some safety struct zeroing
Modified bind to consitentlyy use sockaddr_storage(not just for AF_UNIX)
#Note this could potentially break the build on other platforms, as I have
#not tested them yet (Will soon though)
take any args. In some cases we probably want to skip the check for
performance reasons, but in other cases where performance is unlikely
to be a factor, not throwing a warning on the wrong number of args passed
to a function is at best inconsistent, and at worst it could hide a bug.
So, add a few such checks. There are still lots of cases out there.
- nuke first parameter to socket_select (detemine it ourself)
- swap parameters for socket_fd_set, socket_fd_clear & socket_fd_isset
- allow to pass an array of sockets to socket_fd_set + socket_fd_clear
include nuking unnecessary extra copies, fixing handling of optional args,
adding an additional argument.
also, fix socket_read() which used the php_read function by
default (by default, reading 4k would cause 4k calls to the read() function),
now it uses the system's built-in read() function, only uses php_read()
when its explicitly specified.
All compilers on Solaris should build this extension correctly now.
It turns out the SUN CC, by default, enables a define that enables the use of
#pragma redefine extname in sun header files. This is why cc would work,
and gcc wouldn't.
-Jason
take 4th parameter specifying whether to use the read() wrapper or the
system read() function, and modified the wrapper() so that it worked (mostly)
properly once again.
calling the read() system call.
# Some people were commenting about "oddities" in the wrapper that I hadn't
# noticed before, though I've used it in many places before now..
symbol on Solaris.. s_un isn't...), and corrected bugs with checking for a
string by checking if Z_STRVAL_PP(ptr) == NULL instead of
Z_STRLEN_PP == 0, causing segfaults when uninitialized values were passed
into certain functions.
@- Attempted to make compile fixes for Solaris in ext/sockets/sockets.c (Chris Vandomelen)
# OK, so I have a tendency to make lots and lots of bug fixes in big spurts..
on most varieties of Linux, and should hopefully fix at least 3 of the
compile errors that were discovered). Also modified read() slightly
to take an optional parameter as to whether the data was binary or
text so it wouldn't stop reading on a newline or null byte received.
@- Made read() binary-safe in sockets.c (Chris Vandomelen)
@- Attempted fixing some compile failures (Chris Vandomelen)
# Hopefully someone will attempt to compile this on other systems, I
# have no access to other platforms to compile it on ....
* Fixed a bug in zend_rsrc_list_get_rsrc_type()
* Switched register_list_destructors() to use
zend_register_list_destructors_ex() instead
* Updated all relevant modules to provide the resource type name
to register_list_destructors() call
* Updated var_dump() to output resource type name instead of number
@- Made resource type names visible, e.g. var_dump() and
@ get_resource_type() display "file" for file resources. (Andrei)
- Make constants case-sensitive, conforming with the rest of PHP &
the C API.
- Make module compatible with thread safety features.
- open_listen_sok() -> open_listen_sock()
- Remove ext_skel comments
- Get rid of the ZVAL macro and replace with the correct Z_*_*
macros
- declare all functions local to the file as static.
- Remove empty PHP_MSHUTDOWN() function.
- Removed confirm_sockets_compiled()
- Changed RETVAL_* macro's to RETURN_* macro's eliminating errors
with incorrect return values and a potential leak/crash or two.
- functions that return void, actually return void
- Replaced 'long' in the prototypes with 'int'
- Fixed fd_zero() function, it gave a WRONG_PARAM_COUNT when you
gave it the proper parameter count.
- Changed the way an arbitrary number of parameters were accessed
from build_iovec() to use the Zend API.
- Added socketpair() and shutdown() functions.
Numerous changes. Many prototypes changed to be more like the
appropriate *NIX counterparts. Many new prototypes defining many
more advanced socket routines. Better AF_UNIX socket support.
bind() now recognizes the socket type and acts appropriately,
instead of needing the AF_* for the socket passed in.
# Something I'd like to write yet is proper signal() support. Unfortunately,
# the last time I tried, doing anything with the signal except ignoring it
# caused PHP to segfault. And to have decent socket support.. at least, from
# my experience, having signals is a good thing. Only problem.. to implement
# it, some changes would have to be made to the parser - since that is where
# the problems lie on handling asynchronous signals.