php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77077 rmdir() should return FALSE if directory locked by dir()
Submitted: 2018-10-28 20:45 UTC Modified: 2021-07-07 14:01 UTC
From: edgaras dot janusauskas at gmail dot com Assigned: cmb (profile)
Status: Wont fix Package: *Directory/Filesystem functions
PHP Version: 7.2.11 OS: Windows 10
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: edgaras dot janusauskas at gmail dot com
New email:
PHP Version: OS:

 

 [2018-10-28 20:45 UTC] 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]

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-10-29 12:20 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2018-10-29 12:20 UTC] 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-12-10 16:51 UTC] ab@php.net
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.
 [2021-07-07 14:01 UTC] cmb@php.net
-Status: Verified +Status: Wont fix -Assigned To: +Assigned To: cmb
 [2021-07-07 14:01 UTC] cmb@php.net
> Otherwise we might be striving to satisfy an edge case while
> making the normal usage some slower.

Agreed.  Closing as WONTFIX.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 12:01:31 2024 UTC