From c7f24d9ca4ccc7c6fef90ea9d733a5fff9127a4a Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 16 Aug 2022 17:06:30 +0200 Subject: [PATCH 1/2] Fix GH-7910: rename fails on Windows if the target is being executed Prior to commit c732ab4[1], the script file was closed immediately after compilation, but the destruction has been properly moved to the initialization side. Still, at least closing the stream needs to be done right after compilation to avoid too many open file handles (e.g. `php -F`), and to avoid some limitations on Windows. Thus, we introduce `zend_stream_close()` which only closes the stream, and is called from `zend_file_handle_dtor()`. [1] --- Zend/tests/gh7910.phpt | 14 ++++++++++++++ Zend/zend.c | 1 + Zend/zend_stream.c | 7 ++++++- Zend/zend_stream.h | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/gh7910.phpt diff --git a/Zend/tests/gh7910.phpt b/Zend/tests/gh7910.phpt new file mode 100644 index 000000000000..63b2f77bf2a3 --- /dev/null +++ b/Zend/tests/gh7910.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-7910 (rename fails on Windows if the target is being executed) +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) diff --git a/Zend/zend.c b/Zend/zend.c index be7fa210fff7..ffb77554821f 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1795,6 +1795,7 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count if (file_handle->opened_path) { zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path); } + zend_stream_close(file_handle); if (op_array) { zend_execute(op_array, retval); zend_exception_restore(); diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index ae2c734b09b4..629905167c99 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -210,7 +210,7 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf return SUCCESS; } /* }}} */ -static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ +ZEND_API void zend_stream_close(zend_file_handle *fh) /* {{{ */ { switch (fh->type) { case ZEND_HANDLE_FP: @@ -231,6 +231,11 @@ static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ */ break; } +} /* }}} */ + +static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ +{ + zend_stream_close(fh); if (fh->opened_path) { zend_string_release_ex(fh->opened_path, 0); fh->opened_path = NULL; diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h index 047719e175a0..38e11a108e33 100644 --- a/Zend/zend_stream.h +++ b/Zend/zend_stream.h @@ -68,6 +68,7 @@ ZEND_API void zend_stream_init_filename(zend_file_handle *handle, const char *fi ZEND_API void zend_stream_init_filename_ex(zend_file_handle *handle, zend_string *filename); ZEND_API zend_result zend_stream_open(zend_file_handle *handle); ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len); +ZEND_API void zend_stream_close(zend_file_handle *handle); ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle); void zend_stream_init(void); From 0b148eaebbba22e96ffee822fe73ab508099666b Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 6 Sep 2022 15:38:37 +0200 Subject: [PATCH 2/2] Only close handle streams which have been opened by zend_stream_fixup() --- Zend/zend_stream.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index 629905167c99..8693d6aef610 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -210,7 +210,17 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf return SUCCESS; } /* }}} */ +/* Closes handle stream if opened by zend_stream_fixup() */ ZEND_API void zend_stream_close(zend_file_handle *fh) /* {{{ */ +{ + if (fh->type == ZEND_HANDLE_STREAM && fh->handle.stream.handle + && fh->handle.stream.closer == (zend_stream_closer_t)zend_stream_stdio_closer) { + fh->handle.stream.closer(fh->handle.stream.handle); + fh->handle.stream.closer = NULL; + } +} /* }}} */ + +static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ { switch (fh->type) { case ZEND_HANDLE_FP: @@ -231,11 +241,6 @@ ZEND_API void zend_stream_close(zend_file_handle *fh) /* {{{ */ */ break; } -} /* }}} */ - -static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ -{ - zend_stream_close(fh); if (fh->opened_path) { zend_string_release_ex(fh->opened_path, 0); fh->opened_path = NULL;