From: chris_se at gmx dot net Operating system: Any POSIX-compatible OS PHP version: 5.2.4 PHP Bug Type: Streams related Bug description: file_put_contents' LOCK_EX flag is useless with advisory locking
Description: ------------ The LOCK_EX flag of file_put_contents suggests that the function will use an advisory lock to ensure transaction safety. This is NOT the case (except when combined with FILE_APPEND). It actually DOES request an exclusive lock on the file but only does so AFTER opening it in the 'wb' mode which will truncate the file on opening BEFORE the actual lock can be acquired. The correct behaviour would be to open the file for writing without truncating it, in C for example using int fileno = open (file, O_WRONLY | O_CREAT, 0666); (WITHOUT adding O_TRUNC!), THEN acquiring the lock using flock() and THEN truncating the file to 0 bytes length. I don't know if there's a simple possibility to integrate it with the current streams API (since there's no fopen mode that will map to either O_WRONLY | O_CREAT or O_RWDR | O_CREAT) but if it's not possible to fix it, you should at least remove the option, since it suggests something it can't provide with advisory locking. This is not a problem on Windows since Windows locks are always mandatory. Reproduce code: --------------- First script (start in in a first window using any P): <?php file_put_contents ('file.txt', 'Hello World!'); $f = fopen ('file.txt', 'r') or die ("Could not open file!\n"); flock ($f, LOCK_SH) or die ("Could not acaquire lock!\n"); echo "Sleeping for 20 seconds (please use file_put_contents script in the mean time!)\n"; sleep (20); $x .= fread ($f, 1024); fclose ($f); echo "Contents was: '" . $x . "'\n"; ?> Second script (start it in a second window in the same directory while the first one is sleeping): <?php file_put_contents ('file.txt', 'ByeBye Joe!', LOCK_EX); ?> Expected result: ---------------- The first script should output: Sleeping for 20 seconds (please use file_put_contents script in the mean time!) Contents was: 'Hello World!' Actual result: -------------- The first script outputs: Sleeping for 20 seconds (please use file_put_contents script in the mean time!) Contents was: '' -- Edit bug report at http://bugs.php.net/?id=43182&edit=1 -- Try a CVS snapshot (PHP 4.4): http://bugs.php.net/fix.php?id=43182&r=trysnapshot44 Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=43182&r=trysnapshot52 Try a CVS snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=43182&r=trysnapshot53 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=43182&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=43182&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=43182&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=43182&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=43182&r=needscript Try newer version: http://bugs.php.net/fix.php?id=43182&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=43182&r=support Expected behavior: http://bugs.php.net/fix.php?id=43182&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=43182&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=43182&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=43182&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=43182&r=php3 Daylight Savings: http://bugs.php.net/fix.php?id=43182&r=dst IIS Stability: http://bugs.php.net/fix.php?id=43182&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=43182&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=43182&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=43182&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=43182&r=mysqlcfg