|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2006-05-31 18:26 UTC] mike@php.net
[2006-05-31 21:34 UTC] jdolecek at NetBSD dot org
[2007-01-02 15:38 UTC] nlopess@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 04:00:01 2025 UTC |
Description: ------------ The block spawning the child process for both Netware and UNIX-like OS contains this block in failure case: if (child < 0) { /* failed to fork() */ /* clean up all the descriptors */ for (i = 0; i < ndesc; i++) { close(descriptors[i].childend); close(descriptors[i].parentend); } ... } parentend is filled only for pipes, for 'file' handles it's not filled, and left '0' as initialized by memset() in proc_open.c line 537. So, if proc_open() was called with descriptorspec using 'file' and the fork() call fails, this results in closing descriptor 0. Quick fix is to only close parentend if it's non-zero, such as: --- ext/standard/proc_open.c.orig 2006-05-28 21:51:09.000000000 +0200 +++ ext/standard/proc_open.c @@ -796,7 +796,8 @@ PHP_FUNCTION(proc_open) /* clean up all the descriptors */ for (i = 0; i < ndesc; i++) { close(descriptors[i].childend); - close(descriptors[i].parentend); + if (descriptors[i].parentend) + close(descriptors[i].parentend); } php_error_docref(NULL TSRMLS_CC, E_WARNING, "procve failed - %s", strerror(errno)); goto exit_fail; @@ -863,7 +864,8 @@ PHP_FUNCTION(proc_open) /* clean up all the descriptors */ for (i = 0; i < ndesc; i++) { close(descriptors[i].childend); - close(descriptors[i].parentend); + if (descriptors[i].parentend) + close(descriptors[i].parentend); } php_error_docref(NULL TSRMLS_CC, E_WARNING, "fork failed - %s", strerror(errno)); Reproduce code: --------------- It's necessary to setup process limit via ulimit so that running the php script gets last allowed slot: > echo test > tst > ulimit -p `pgrep -u "\`id -u\`" | wc -l` > php script.php < tst script.php: <?php $p = proc_open("echo hello", array(0 => array('file', '/dev/null', 'r'), 1 => array('pipe', 'r')), $pipes1); echo file_get_contents("php://stdin")."\n"; Expected result: ---------------- PHP Warning: proc_open(): fork failed - Resource temporarily unavailable in /usr/home/dolecek/tmp/proc3.php on line 4 test Actual result: -------------- PHP Warning: proc_open(): fork failed - Resource temporarily unavailable in /usr/home/dolecek/tmp/proc3.php on line 4