Bug #77077 [Ver]: rmdir() should return FALSE if directory locked by dir()
| From: | ab@php.net | Date: | Mon, 10 Dec 2018 16:51:03 +0000 |
| Subject: | Bug #77077 [Ver]: rmdir() should return FALSE if directory locked by dir() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-218370@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77077&edit=1
ID: 77077
Updated by: ab@php.net
Reported by: edgaras dot janusauskas at gmail dot com
Summary: rmdir() should return FALSE if directory locked by
dir()
Status: Verified
Type: Bug
Package: *Directory/Filesystem functions
Operating System: Windows 10
PHP Version: 7.2.11
Block user comment: N
Private report: N
New Comment:
The described is the expected behavior. What indeed could be fixed, is that scandir shouldn't
deliver items scheduled for deletion. That however would require a refactoring of the
scandir/readdir implementation, not just a bugfix. However even then I'd be not sure it would
always deliver result by this usage. The enumeration used for the internal implementation would
deliver per se an undefined result, if items are deleted/created after the enumeration has been
started. Best way is to avoid such usage as there's in 99% of cases no need on this. Otherwise
we might be striving to satisfy an edge case while making the normal usage some slower.
Thanks.
Previous Comments:
------------------------------------------------------------------------
[2018-10-29 12:20:04] cmb@php.net
Well, the basic issue is that contrary to POSIX' rmdir()[1],
Windows' RemoveDirectory()[2] only âmarks a directory for deletion
on closeâ, but claims success, even if the directory is not
immediately removed.
The difference between glob() and scandir() on Windows is that the
former calls php_sys_lstat() on the directory (which fails), but
the latter does not.
[1] <http://pubs.opengroup.org/onlinepubs/9699919799/>
[1] <https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-removedirectoryw>
------------------------------------------------------------------------
[2018-10-28 20:45:18] edgaras dot janusauskas at gmail dot com
Description:
------------
On Windows, if directory is opened by dir() or opendir(), but not closed, then call to rmdir() on
that directory returns TRUE, but then there is few inconsistencies exist:
- Second call to rmdir() on same directory fails (Permission denied)
- You cannot delete parent directory (Directory not empty)
- glob() doesn't see directory, but scandir() still sees it as existing.
Test script:
---------------
mkdir('testdir');
mkdir('testdir/sub');
$d = dir('testdir/sub');
while (false !== ($entry = $d->read())) {
//echo $entry . "\n";
}
//$d->close();
printf("rmdir=%d\n", rmdir('testdir/sub'));
printf("glob=[%s]\n", implode(', ', glob('testdir/*')));
printf("scandir=[%s]\n", implode(', ', scandir('testdir')));
Expected result:
----------------
rmdir() should really succeed deleting folder and any further operations should work as with not
existing one.
rmdir=1
glob=[]
scandir=[., ..]
Deleting parent directory succeeds
or
rmdir() should fail with "Permission denied" on first try and any further operations
should work as with still existing one.
rmdir=0
glob=[testdir/sub]
scandir=[., .., sub]
Deleting parent directory fails
Actual result:
--------------
rmdir=1
glob=[] on PHP 7.0-7.2
glob=[testdir/sub] on PHP 5.6
scandir=[., .., sub]
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=77077&edit=1