Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4de8207

Browse files
committed
Allow to not close stream on rscr dtor in php cli sapi
1 parent 332ac8e commit 4de8207

File tree

4 files changed

+35
-12
lines changed

4 files changed

+35
-12
lines changed

‎main/php_streams.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ struct _php_stream_wrapper {
185185
* Currently for internal use only. */
186186
#define PHP_STREAM_FLAG_SUPPRESS_ERRORS 0x100
187187

188+
/* Do not close handle except it is explicitly closed by user (e.g. fclose) */
189+
#define PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE 0x200
190+
188191
#define PHP_STREAM_FLAG_WAS_WRITTEN 0x80000000
189192

190193
struct _php_stream {

‎main/streams/streams.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,8 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options) /* {{{ */
383383

384384
context = PHP_STREAM_CONTEXT(stream);
385385

386-
if (stream->flags & PHP_STREAM_FLAG_NO_CLOSE) {
386+
if ((stream->flags & PHP_STREAM_FLAG_NO_CLOSE) ||
387+
((stream->flags & PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE) && (close_options & PHP_STREAM_FREE_RSRC_DTOR))) {
387388
preserve_handle = 1;
388389
}
389390

‎sapi/cli/php_cli.c‎

Lines changed: 12 additions & 11 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(boolno_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_RSCR_DTOR_CLOSE;
544+
if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE;
545+
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_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);
@@ -567,7 +569,6 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
567569
ec.name = zend_string_init_interned("STDERR", sizeof("STDERR")-1, 0);
568570
zend_register_constant(&ec);
569571
}
570-
/* }}} */
571572

572573
static const char *param_mode_conflict = "Either execute direct code, process stdin or use a file.\n";
573574

@@ -954,7 +955,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
954955
switch (behavior) {
955956
case PHP_MODE_STANDARD:
956957
if (script_file) {
957-
cli_register_file_handles(/* no_close */PHP_DEBUG||num_repeats>1);
958+
cli_register_file_handles();
958959
}
959960

960961
if (interactive) {
@@ -990,7 +991,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
990991
}
991992
break;
992993
case PHP_MODE_CLI_DIRECT:
993-
cli_register_file_handles(/* no_close */PHP_DEBUG||num_repeats>1);
994+
cli_register_file_handles();
994995
zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
995996
break;
996997

@@ -1005,7 +1006,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
10051006
file_handle.filename = NULL;
10061007
}
10071008

1008-
cli_register_file_handles(/* no_close */PHP_DEBUG||num_repeats>1);
1009+
cli_register_file_handles();
10091010

10101011
if (exec_begin) {
10111012
zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);

‎sapi/cli/tests/gh8827.phpt‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
std handles can be deliberately closed
3+
--SKIPIF--
4+
<?php
5+
if (php_sapi_name() != "cli") {
6+
die("skip CLI only");
7+
}
8+
if (substr(PHP_OS, 0, 3) == 'WIN') {
9+
die("skip not for Windows");
10+
}
11+
?>
12+
--FILE--
13+
<?php
14+
fclose(STDERR);
15+
var_dump(@fopen('php://stderr', 'a'));
16+
?>
17+
--EXPECT--
18+
bool(false)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /