Bug #77077 [Ver]: rmdir() should return FALSE if directory locked by dir()

From: 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

« previous php.bugs (#218370) next »