Stop closing stderr and stdout streams (#8570)

Extensions may (and do) write to stderr in mshutdown and similar. In
the best case, with the stderr stream closed, it's just swallowed.

However, some libraries will do things like try to detect color, and
these will outright fail and cause an error path to be taken.
This commit is contained in:
Levi Morrison 2022-05-16 16:54:47 -06:00 committed by Arnaud Le Blanc
parent c88dc44a75
commit ffd27bdec4
4 changed files with 15 additions and 10 deletions

3
NEWS
View file

@ -2,6 +2,9 @@ PHP NEWS
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.1.7 ?? ??? ????, PHP 8.1.7
- CLI:
. Fixed bug GH-8575 (CLI closes standard streams too early). (Levi Morrison)
- FPM: - FPM:
. Fixed ACL build check on MacOS. (David Carlier) . Fixed ACL build check on MacOS. (David Carlier)
. Fixed bug #72185: php-fpm writes empty fcgi record causing nginx 502. . Fixed bug #72185: php-fpm writes empty fcgi record causing nginx 502.

View file

@ -51,6 +51,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
HashTable global_weakmap; HashTable global_weakmap;
int replace_zend_execute_ex; int replace_zend_execute_ex;
int register_passes; int register_passes;
bool print_stderr_mshutdown;
zend_test_fiber *active_fiber; zend_test_fiber *active_fiber;
ZEND_END_MODULE_GLOBALS(zend_test) ZEND_END_MODULE_GLOBALS(zend_test)

View file

@ -1,10 +1,9 @@
--TEST-- --TEST--
CLI: stderr is available in mshutdown CLI: stderr is available in mshutdown
--SKIPIF-- --SKIPIF--
<?php <?php if (php_sapi_name() != "cli") die('skip cli test only'); ?>
if (!extension_loaded('zend-test')) die('skip zend-test extension required'); --EXTENSIONS--
if (php_sapi_name() != "cli") die('skip cli test only'); zend_test
?>
--INI-- --INI--
zend_test.print_stderr_mshutdown=1 zend_test.print_stderr_mshutdown=1
--FILE-- --FILE--

View file

@ -542,9 +542,11 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
* extensions which write to stderr or company during mshutdown/gshutdown * extensions which write to stderr or company during mshutdown/gshutdown
* won't have the expected functionality. * won't have the expected functionality.
*/ */
if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE; if (no_close) {
if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE; if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE; if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
}
if (s_in==NULL || s_out==NULL || s_err==NULL) { if (s_in==NULL || s_out==NULL || s_err==NULL) {
if (s_in) php_stream_close(s_in); if (s_in) php_stream_close(s_in);
@ -958,7 +960,7 @@ do_repeat:
switch (behavior) { switch (behavior) {
case PHP_MODE_STANDARD: case PHP_MODE_STANDARD:
if (script_file) { if (script_file) {
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); cli_register_file_handles(/* no_close */ true);
} }
if (interactive) { if (interactive) {
@ -993,7 +995,7 @@ do_repeat:
} }
break; break;
case PHP_MODE_CLI_DIRECT: case PHP_MODE_CLI_DIRECT:
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); cli_register_file_handles(/* no_close */ true);
zend_eval_string_ex(exec_direct, NULL, "Command line code", 1); zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
break; break;
@ -1008,7 +1010,7 @@ do_repeat:
file_handle.filename = NULL; file_handle.filename = NULL;
} }
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); cli_register_file_handles(/* no_close */ true);
if (exec_begin) { if (exec_begin) {
zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1); zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);