Edit report at http://bugs.php.net/bug.php?id=53076&edit=1
ID: 53076 Updated by: cataphr...@php.net Reported by: admin at saltwaterc dot net Summary: file_put_contents doesn't release the LOCK_EX -Status: Open +Status: Feedback Type: Bug Package: Scripting Engine problem Operating System: Irrelevant PHP Version: 5.3.3 Block user comment: N New Comment: I can't reproduce this. I get the output "bar". File locks are released when the file are closed. Additionally, your 'actual result' section shows an unlock: ... write(3, "bar", 3) = 3 flock(3, LOCK_UN) = 0 <<<<<--- Am I missing something? Previous Comments: ------------------------------------------------------------------------ [2010-10-15 17:16:19] admin at saltwaterc dot net Test script: --------------- <?php file_put_contents('foo', 'bar', LOCK_EX); $fh = fopen('foo', 'rb'); // there, I messed up the first time flock($fh, LOCK_SH); $file_contents = stream_get_contents($fh); flock($fh, LOCK_UN); fclose($fh); echo $file_contents.PHP_EOL; ------------------------------------------------------------------------ [2010-10-15 17:12:59] admin at saltwaterc dot net Description: ------------ The name is pretty self explanatory. When the file_put_content function is used along with the LOCK_EX flag, the file descriptor / file handle doesn't get unlocked. Most of the time this won't be an issue, but depending on the underlying file system, it could lead to severe application crash. Such example is the GlusterFS version packaged for the Ubuntu 10.04 which would block the PHP process in uninterruptible sleep. I know that most of the time this situation won't affect real life scenarios, but it already took down a virtual host from our production cluster, based onto the above setup. Test script: --------------- <?php file_put_contents('foo', 'bar', LOCK_EX); $fh = fopen($file, 'rb'); flock($fh, LOCK_SH); $file_contents = stream_get_contents($fh); flock($fh, LOCK_UN); fclose($fh); echo $file_contents.PHP_EOL; Expected result: ---------------- output: bar strace: getcwd("/media/glusterfs01/gluster-bug", 4096) = 31 lstat("/media/glusterfs01/gluster-bug/foo", {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 open("/media/glusterfs01/gluster-bug/foo", O_WRONLY|O_CREAT, 0666) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 flock(3, LOCK_EX) = 0 ftruncate(3, 0) = 0 write(3, "bar", 3) = 3 flock(3, LOCK_UN) = 0 close(3) = 0 getcwd("/media/glusterfs01/gluster-bug", 4096) = 31 open("/media/glusterfs01/gluster-bug/foo", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 flock(3, LOCK_SH) = 0 fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 read(3, "bar", 8192) = 3 read(3, "", 8192) = 0 read(3, "", 8192) = 0 flock(3, LOCK_UN) = 0 close(3) = 0 Actual result: -------------- output: none strace: getcwd("/media/glusterfs01/gluster-bug", 4096) = 31 lstat("/media/glusterfs01/gluster-bug/foo", {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 open("/media/glusterfs01/gluster-bug/foo", O_WRONLY|O_CREAT, 0666) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 flock(3, LOCK_EX) = 0 ftruncate(3, 0) = 0 write(3, "bar", 3) = 3 flock(3, LOCK_UN) = 0 close(3) = 0 getcwd("/media/glusterfs01/gluster-bug", 4096) = 31 open("/media/glusterfs01/gluster-bug/foo", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 flock(3, LOCK_SH And then it blocks here ... ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=53076&edit=1