Skip to content

Commit b9003e8

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 b9003e8

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

sapi/cli/php_cli.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ 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;
@@ -536,19 +536,21 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
536536
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
537537
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
538538

539+
/* Release stream resources, but don't free the underlying handles. Othewrise,
540+
* extensions which write to stderr or company during mshutdown/gshutdown
541+
* won't have the expected functionality.
542+
*/
543+
if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
544+
if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
545+
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
546+
539547
if (s_in==NULL || s_out==NULL || s_err==NULL) {
540548
if (s_in) php_stream_close(s_in);
541549
if (s_out) php_stream_close(s_out);
542550
if (s_err) php_stream_close(s_err);
543551
return;
544552
}
545553

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-
552554
s_in_process = s_in;
553555

554556
php_stream_to_zval(s_in, &ic.value);
@@ -954,7 +956,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
954956
switch (behavior) {
955957
case PHP_MODE_STANDARD:
956958
if (script_file) {
957-
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
959+
cli_register_file_handles();
958960
}
959961

960962
if (interactive) {
@@ -989,7 +991,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
989991
}
990992
break;
991993
case PHP_MODE_CLI_DIRECT:
992-
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
994+
cli_register_file_handles();
993995
zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
994996
break;
995997

@@ -1004,7 +1006,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
10041006
file_handle.filename = NULL;
10051007
}
10061008

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

10091011
if (exec_begin) {
10101012
zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);

0 commit comments

Comments
 (0)