From 945bd53314ff6c01498e02ac571554e7b23f1d2e Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Mon, 20 Jun 2022 14:14:29 +0100 Subject: [PATCH] Allow to not close stream on rscr dtor in php cli sapi --- main/php_streams.h | 3 +++ main/streams/streams.c | 3 ++- sapi/cli/php_cli.c | 6 +++--- sapi/cli/tests/gh8827.phpt | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 sapi/cli/tests/gh8827.phpt diff --git a/main/php_streams.h b/main/php_streams.h index 3742290218e95..5067b69054695 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -185,6 +185,9 @@ struct _php_stream_wrapper { * Currently for internal use only. */ #define PHP_STREAM_FLAG_SUPPRESS_ERRORS 0x100 +/* Do not close handle except it is explicitly closed by user (e.g. fclose) */ +#define PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE 0x200 + #define PHP_STREAM_FLAG_WAS_WRITTEN 0x80000000 struct _php_stream { diff --git a/main/streams/streams.c b/main/streams/streams.c index c10af433904bc..bafb2793be1cf 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -383,7 +383,8 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options) /* {{{ */ context = PHP_STREAM_CONTEXT(stream); - if (stream->flags & PHP_STREAM_FLAG_NO_CLOSE) { + if ((stream->flags & PHP_STREAM_FLAG_NO_CLOSE) || + ((stream->flags & PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE) && (close_options & PHP_STREAM_FREE_RSRC_DTOR))) { preserve_handle = 1; } diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 625a6534b75f9..f66f0c86a0b46 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -540,9 +540,9 @@ static void cli_register_file_handles(void) /* {{{ */ * 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 (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE; + if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE; + if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE; if (s_in==NULL || s_out==NULL || s_err==NULL) { if (s_in) php_stream_close(s_in); diff --git a/sapi/cli/tests/gh8827.phpt b/sapi/cli/tests/gh8827.phpt new file mode 100644 index 0000000000000..cbe62a3b48de8 --- /dev/null +++ b/sapi/cli/tests/gh8827.phpt @@ -0,0 +1,18 @@ +--TEST-- +std handles can be deliberately closed +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false)