Skip to content

Commit e8eb980

Browse files
committed
Stop closing stderr and stdout streams
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.
1 parent 7850c10 commit e8eb980

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

sapi/cli/php_cli.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,21 @@ static void php_cli_usage(char *argv0)
526526

527527
static php_stream *s_in_process = NULL;
528528

529-
static void cli_register_file_handles(bool no_close) /* {{{ */
529+
static void cli_register_file_handles(void) /* {{{ */
530530
{
531531
php_stream *s_in, *s_out, *s_err;
532532
php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
533533
zend_constant ic, oc, ec;
534534

535-
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
536-
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
537-
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
535+
/* Release stream resources, but don't free the underlying handles. Othewrise,
536+
* extensions which write to stderr or company during mshutdown/gshutdown
537+
* won't have the expected functionality.
538+
*/
539+
int options = PHP_STREAM_FLAG_NO_CLOSE;
540+
541+
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", options, NULL, sc_in);
542+
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", options, NULL, sc_out);
543+
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", options, NULL, sc_err);
538544

539545
if (s_in==NULL || s_out==NULL || s_err==NULL) {
540546
if (s_in) php_stream_close(s_in);
@@ -543,12 +549,6 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
543549
return;
544550
}
545551

546-
if (no_close) {
547-
s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
548-
s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
549-
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
550-
}
551-
552552
s_in_process = s_in;
553553

554554
php_stream_to_zval(s_in, &ic.value);
@@ -954,7 +954,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
954954
switch (behavior) {
955955
case PHP_MODE_STANDARD:
956956
if (script_file) {
957-
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
957+
cli_register_file_handles();
958958
}
959959

960960
if (interactive) {
@@ -989,7 +989,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
989989
}
990990
break;
991991
case PHP_MODE_CLI_DIRECT:
992-
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
992+
cli_register_file_handles();
993993
zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
994994
break;
995995

@@ -1004,7 +1004,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
10041004
file_handle.filename = NULL;
10051005
}
10061006

1007-
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
1007+
cli_register_file_handles();
10081008

10091009
if (exec_begin) {
10101010
zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);

0 commit comments

Comments
 (0)