From: roelf at neology dot co dot za
Operating system: Debian GNU/Linux Etch
PHP version: 5.2.5
PHP Bug Type: Feature/Change Request
Bug description: Proposed new socket function: socket_set_close_on_exec
Description:
------------
I would like to propose a new socket function:
socket_set_close_on_exec
Reasoning:
I have a case where I developed a php CLI sapi script, that manages an
entire Linux system's bootup process, and acts as a system process
supervisor, similar to 'init'. The supervisor listens using php socket
functions on port 19992, in order to receive text commands that administer
the supervisor.
One of the processes that my script supervises, is a PHP CLI
implementation of a webserver, called 'nanoweb'.
When the supervisor 'exec()'s the nanoweb server (and any other process
for that matter) the child inherits the listening socket, port 19992.
If the supervisor is unexpectedly killed e.g. 'kill -9' nanoweb typically
starts listening on this socket. The problem is that the supervisor is
incapable now of being restarted, due to the fact that it's port is in use,
and the supervisor is unable to bind the port.
The problem is not with nanoweb, itsself, but the behaviour where the
listening socket is inherited.
I propose an additional socket function socket_set_close_on_exec() which
will do the appropriate fcntl() on the socket handle, so that child
processes do not inherit the socket. This elegantly solves the problem in
my case without changing the default behaviour of php.
Below is the example code I used to patch my PHP - it is based entirely on
the socket_set_nonblock() function's code.
Reproduce code:
---------------
/* {{{ proto bool socket_set_close_on_exec(resource socket)
Sets close-on-exec mode on a socket resource */
PHP_FUNCTION(socket_set_close_on_exec)
{
zval *arg1;
php_socket *php_sock;
int flags;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) ==
FAILURE)
return;
ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name,
le_socket);
flags = fcntl(php_sock->bsd_socket, F_GETFD);
/* Safely append close-on-exec to other flags unless the get fails.
*/
if (flags > -1) flags |= FD_CLOEXEC;
else flags = FD_CLOEXEC;
if (fcntl(php_sock->bsd_socket, F_SETFD, flags) > -1) {
RETURN_TRUE;
}
RETURN_FALSE;
}
/* }}} */
Expected result:
----------------
I expect a function to be available to set the FD_CLOEXEC flag on socket
handles
Actual result:
--------------
There is no such function available
--
Edit bug report at http://bugs.php.net/?id=43290&edit=1
--
Try a CVS snapshot (PHP 4.4):
http://bugs.php.net/fix.php?id=43290&r=trysnapshot44
Try a CVS snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=43290&r=trysnapshot52
Try a CVS snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=43290&r=trysnapshot53
Try a CVS snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=43290&r=trysnapshot60
Fixed in CVS: http://bugs.php.net/fix.php?id=43290&r=fixedcvs
Fixed in release:
http://bugs.php.net/fix.php?id=43290&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=43290&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=43290&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=43290&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=43290&r=support
Expected behavior: http://bugs.php.net/fix.php?id=43290&r=notwrong
Not enough info:
http://bugs.php.net/fix.php?id=43290&r=notenoughinfo
Submitted twice:
http://bugs.php.net/fix.php?id=43290&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=43290&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=43290&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=43290&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=43290&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=43290&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=43290&r=float
No Zend Extensions: http://bugs.php.net/fix.php?id=43290&r=nozend
MySQL Configuration Error: http://bugs.php.net/fix.php?id=43290&r=mysqlcfg