Reputation: 950
I have one php process locking a file with flock. I then start another process that deletes the file.
On windows, I get the correct behaviour where the locked file is not able to be deleted, however on ubuntu (both wsl and a full Ubuntu installation) I am always able to delete the file.
I have read other similar questions but they all seem to tested wrong. I am pretty sure I am testing this correctly.
UPDATED: More thorough testing. After reading Why is unlink successful on an open file? and the delete Queue in the file system I needed to also test read and write.
Testing method.
php test/flock_file_locking_with_splfileobject.php
👈 locks the file and waits for 30 seconds
php test/flock_file_locking_with_splfileobject.php read
php test/flock_file_locking_with_splfileobject.php write
php test/flock_file_locking_with_splfileobject.php delete
Here's the contents of test/flock_file_locking_with_splfileobject.php
See comments in the code describing the output I get.
<?php
$me = array_shift($argv);
$command = array_shift($argv);
$fileName = 'cats';
switch ($command) {
case 'delete':
//attempt to delete the file
if (!unlink($fileName)) {
echo "Failed to delete file!";
exit(1);
}
echo "File was deleted:";
var_dump(file_exists($fileName) === false);
//on linux I get File was deleted:bool(true)
//on windows I get 'PHP Warning: unlink(cats): Resource temporarily unavailable'
break;
case 'write':
$written = file_put_contents($fileName, 'some datah!');
echo "Written bytes:";
var_dump($written);
//on Linux I get 'Read: string(21) "file should be locked"'
// OR 'Read: string(11) "some datah!"' if I run the write command first.
//on windows i get Warning: file_put_contents(): Only 0 of 11 bytes written, possibly out of free disk space
break;
case 'read':
$read = file_get_contents($fileName);
echo "Read: ";
var_dump($read);
// on Linux i get 'Written bytes:int(11)'
// on windows I get no error but I get no data 'Read: string(0) ""'
break;
default:
$file = new \SplFileObject($fileName, 'a+');//file gets created by a+
if (! $file->flock(LOCK_EX)) {
echo "Unable to lock the file.\n";
exit(1);
}
$file->fwrite('file should be locked');
echo "File should now be locked, try running the delete/write/read commands in another terminal.",
"I'll wait 30 seconds and try to write to the file...\n";
sleep(30);
if (! $file->fwrite('file is now unlocked')) {
echo "Unable to write to file.\n";
exit(1);
}
//in either system this file write succeeds regardless of whats going on.
break;
}
echo "\n";
Windows behaves as it should but on Linux, my 2nd process can do anything it likes to the file while the first process apparently gets a successful file lock.
Obviously, can't trust flock on production if it only works on windows. Is there any way to actually get an exclusive file lock?
Any ideas?
Upvotes: 0
Views: 181