ID: 43182 Updated by: [EMAIL PROTECTED] Reported By: chris_se at gmx dot net -Status: Open +Status: Wont fix Bug Type: Streams related Operating System: Any POSIX-compatible OS PHP Version: 5.2.4 New Comment:
On *nix systems O_CREAT and O_EXCL are mutually exclusive and will prevent creation of a file if one already exists. Therefore lock needs to be created separately or you need to create another file on the same disk and then use atomic rename. Previous Comments: ------------------------------------------------------------------------ [2007-11-03 16:45:01] chris_se at gmx dot net 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 this bug report at http://bugs.php.net/?id=43182&edit=1