From: Anatol Belski Date: Thu, 7 Dec 2017 15:52:23 +0000 (+0100) Subject: Allow delete-sharing mode for CreateFile by default X-Git-Tag: php-7.3.0alpha1~852 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=17d621e7d3bc0a97d1ddddeb3e7fbdea25548637;p=php Allow delete-sharing mode for CreateFile by default This effectively allows a UNIX like semantics for deleting files with an open handle. Some OS related limitations still persist, but the Windows 95 times can be considered as definitely over. --- diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 132b68f39c..32c71a6149 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -187,8 +187,8 @@ CWD_API ssize_t php_sys_readlink(const char *link, char *target, size_t target_l } hFile = CreateFileW(linkw, // file to open - GENERIC_READ, // open for reading - FILE_SHARE_READ, // share for reading + 0, // query possible attributes + PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, NULL, // default security OPEN_EXISTING, // existing file only FILE_FLAG_BACKUP_SEMANTICS, // normal file @@ -299,7 +299,13 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{ REPARSE_DATA_BUFFER * pbuffer; DWORD retlength = 0; - hLink = CreateFileW(pathw, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); + hLink = CreateFileW(pathw, + FILE_READ_ATTRIBUTES, + PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + NULL); if(hLink == INVALID_HANDLE_VALUE) { free(pathw); return -1; @@ -879,7 +885,13 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim return (size_t)-1; } - hLink = CreateFileW(pathw, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); + hLink = CreateFileW(pathw, + 0, + PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + NULL); if(hLink == INVALID_HANDLE_VALUE) { free_alloca(tmp, use_heap); FREE_PATHW() diff --git a/ext/standard/tests/file/fopen_unlink.phpt b/ext/standard/tests/file/fopen_unlink.phpt new file mode 100644 index 0000000000..c069ea1b94 --- /dev/null +++ b/ext/standard/tests/file/fopen_unlink.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test fopen() function : check fopen()ed descriptor is usable after the fs object is removed +--FILE-- + +===DONE=== +--EXPECTF-- +string(%d) "%stututu" +resource(%s) of type (Unknown) +bool(true) +bool(false) +int(5) +int(0) +string(5) "hello" +int(5) +int(0) +string(10) "helloworld" +bool(true) +===DONE=== diff --git a/ext/standard/tests/file/unlink_variation2-win32.phpt b/ext/standard/tests/file/unlink_variation2-win32.phpt deleted file mode 100644 index af7b381547..0000000000 --- a/ext/standard/tests/file/unlink_variation2-win32.phpt +++ /dev/null @@ -1,43 +0,0 @@ ---TEST-- -Test unlink() function : usage variations - unlink file in use ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -*** Testing unlink() on a file when file handle is open *** - -Warning: unlink(%s): %s in %s on line %d -bool(false) -bool(true) -bool(false) -Done diff --git a/ext/standard/tests/file/unlink_variation2.phpt b/ext/standard/tests/file/unlink_variation2.phpt index 071a65780c..0068dbfe17 100644 --- a/ext/standard/tests/file/unlink_variation2.phpt +++ b/ext/standard/tests/file/unlink_variation2.phpt @@ -1,11 +1,5 @@ --TEST-- Test unlink() function : usage variations - unlink file in use ---SKIPIF-- - --FILE-- share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; */ - /* XXX No UINX behavior Good to know it's doable. - Not being done as this means a behavior change. Should be evaluated properly. */ - opts->share = FILE_SHARE_READ | FILE_SHARE_WRITE; + opts->share = PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE; switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) { case 0: diff --git a/win32/ioutil.h b/win32/ioutil.h index c470fdbb1c..71737f697b 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -121,6 +121,8 @@ typedef enum { #define PHP_WIN32_IOUTIL_IS_UNC(pathw, path_lenw) (path_lenw >= 2 && PHP_WIN32_IOUTIL_IS_SLASHW(pathw[0]) && PHP_WIN32_IOUTIL_IS_SLASHW(pathw[1]) \ || path_lenw >= PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_UNC_PATH_PREFIXW, PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW)) +#define PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) + #define PHP_WIN32_IOUTIL_INIT_W(path) \ wchar_t *pathw = php_win32_ioutil_any_to_w(path); \