From ffd27bdec443d3aa50c8072ee8320f18d0fc516e Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Mon, 16 May 2022 16:54:47 -0600 Subject: [PATCH] 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. --- NEWS | 3 +++ ext/zend_test/php_test.h | 1 + ext/zend_test/tests/gh8575.phpt | 7 +++---- sapi/cli/php_cli.c | 14 ++++++++------ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index 37375067b46..b2811f43707 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.7 +- CLI: + . Fixed bug GH-8575 (CLI closes standard streams too early). (Levi Morrison) + - FPM: . Fixed ACL build check on MacOS. (David Carlier) . Fixed bug #72185: php-fpm writes empty fcgi record causing nginx 502. diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h index e51854699ca..a08c080ee37 100644 --- a/ext/zend_test/php_test.h +++ b/ext/zend_test/php_test.h @@ -51,6 +51,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test) HashTable global_weakmap; int replace_zend_execute_ex; int register_passes; + bool print_stderr_mshutdown; zend_test_fiber *active_fiber; ZEND_END_MODULE_GLOBALS(zend_test) diff --git a/ext/zend_test/tests/gh8575.phpt b/ext/zend_test/tests/gh8575.phpt index 8cf1d68dcab..9830547479f 100644 --- a/ext/zend_test/tests/gh8575.phpt +++ b/ext/zend_test/tests/gh8575.phpt @@ -1,10 +1,9 @@ --TEST-- CLI: stderr is available in mshutdown --SKIPIF-- - + +--EXTENSIONS-- +zend_test --INI-- zend_test.print_stderr_mshutdown=1 --FILE-- diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 47241f8af4e..c2de8bd5230 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -542,9 +542,11 @@ static void cli_register_file_handles(bool no_close) /* {{{ */ * extensions which write to stderr or company during mshutdown/gshutdown * won't have the expected functionality. */ - if (s_in) s_in->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 (no_close) { + if (s_in) s_in->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) php_stream_close(s_in); @@ -958,7 +960,7 @@ do_repeat: switch (behavior) { case PHP_MODE_STANDARD: if (script_file) { - cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); + cli_register_file_handles(/* no_close */ true); } if (interactive) { @@ -993,7 +995,7 @@ do_repeat: } break; 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); break; @@ -1008,7 +1010,7 @@ do_repeat: 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) { zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);