1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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.
This commit is contained in:
Anatol Belski
2017-12-07 16:52:23 +01:00
parent 0acda9103b
commit 17d621e7d3
7 changed files with 54 additions and 58 deletions

View File

@@ -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()

View File

@@ -0,0 +1,34 @@
--TEST--
Test fopen() function : check fopen()ed descriptor is usable after the fs object is removed
--FILE--
<?php
var_dump(
$p = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tututu',
$f = fopen($p, 'w+'),
unlink($p),
file_exists($p),
fwrite($f, 'hello'),
fseek($f, 0),
fread($f, 16),
fwrite($f, 'world'),
fseek($f, 0),
fread($f, 16),
fclose($f)
);
?>
===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===

View File

@@ -1,43 +0,0 @@
--TEST--
Test unlink() function : usage variations - unlink file in use
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) != 'WIN') {
die('skip only on Windows');
}
?>
--FILE--
<?php
/* Prototype : bool unlink ( string $filename [, resource $context] );
Description : Deletes filename
*/
/* Try to unlink file when file handle is still in use */
$file_path = dirname(__FILE__);
echo "*** Testing unlink() on a file when file handle is open ***\n";
// temp file name used here
$filename = "$file_path/unlink_variation2-win32.tmp";
// create file
$fp = fopen($filename, "w");
// try unlink() on $filename
var_dump( unlink($filename) ); // expected: false as file handle is still open
// now close file handle
fclose($fp);
// now unlink file
var_dump( unlink($filename) ); // expected: true
var_dump( file_exists($filename) ); // confirm file is deleted
echo "Done\n";
?>
--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

View File

@@ -1,11 +1,5 @@
--TEST--
Test unlink() function : usage variations - unlink file in use
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) == 'WIN') {
die('skip only on Linux');
}
?>
--FILE--
<?php
/* Prototype : bool unlink ( string $filename [, resource $context] );

View File

@@ -41,7 +41,7 @@ ftok(const char *pathname, int proj_id)
return (key_t)-1;
}
if ((fh = CreateFileW(pathw, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
if ((fh = CreateFileW(pathw, FILE_GENERIC_READ, PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
PHP_WIN32_IOUTIL_CLEANUP_W()
return (key_t)-1;
}

View File

@@ -111,10 +111,7 @@ PW32IO BOOL php_win32_ioutil_posix_to_open_opts(int flags, mode_t mode, php_iout
* UNIX semantics. In particular, this ensures that the file can
* be deleted even whilst it's open.
*/
/* opts->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:

View File

@@ -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); \