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:
@@ -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()
|
||||
|
||||
34
ext/standard/tests/file/fopen_unlink.phpt
Normal file
34
ext/standard/tests/file/fopen_unlink.phpt
Normal 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===
|
||||
@@ -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
|
||||
@@ -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] );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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); \
|
||||
|
||||
|
||||
Reference in New Issue
Block a user