-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Open
Description
Description
The following code:
<?php
// file: bug.php
$content = file_get_contents(__FILE__);
file_put_contents('newfile.php', $content."\n//");
var_dump(rename('newfile.php', __FILE__));
Resulted in this output:
PHP Warning: rename(newfile.php,C:\Users\John\projects\test\bug.php): Access is denied (code: 5) in C:\Users\John\projects\test\bug.php on line 6
Warning: rename(newfile.php,C:\Users\John\projects\test\bug.php): Access is denied (code: 5) in C:\Users\John\projects\test\bug.php on line 6
bool(false)
But I expected this output instead:
bool(true)
This code mimics how Composer self updates (https://getcomposer.org/doc/03-cli.md#self-update-selfupdate-) and has obviously worked for many years, but is broken on Windows PHP 8.1: composer/composer#10444
Note that on Composer 2 we now use copy
on Windows (to get around potential permission issues in UAC protected locations) and this still works on PHP 8.1, but Composer 1 uses rename
(as do all non-Windows platforms on all Composer versions).
Fortunately, this appears to be a Windows only thing, as per this demo: https://github.com/johnstevenson/php-rename-bug/actions/runs/1669358275
PHP Version
PHP 8.1.0
Operating System
Windows 10
mvorisek
Activity
cmb69 commentedon Jan 7, 2022
The regression is apparently caused by c732ab4. I shall have a look.
johnstevenson commentedon Jan 8, 2022
Hey thanks. It seems like the file is locked, because cmd.exe
move
also fails when we call it as part of our UAC elevation stuff.cmb69 commentedon Jan 8, 2022
The file is not locked in a strict sense, but the handle is kept open after compilation, and that prevents the file to be renamed on Windows.
johnstevenson commentedon Jan 8, 2022
Ah, so presumably the file has not been opened with
FILE_SHARE_DELETE
access.cmb69 commentedon Jan 8, 2022
The file is opened in
FILE_SHARE_DELETE
mode, but apparently, moving an opened source file is possible, while moving to an opened destination file is not:I think we either need to close the script file right after compilation, or accept that this is just not supported on Windows. I'd prefer to do the former, unless there is a good reason to keep the script file open.
johnstevenson commentedon Jan 8, 2022
Thanks for the demo. That makes sense (I should have thought about it a bit more).
Let's hope there isn't. I appreciate your time and involvement in this. Moving to Github issues has made PHP bugs a lot more interesting and compelling - for me anyway.
Fix phpGH-7910: rename fails on Windows if the target is being executed
9 remaining items
Voltra commentedon Feb 7, 2023
This also happens (sometimes) when files are being cached using Symfony or Laravel's default cache and filesystem adapters
(Happens on 7.4.26 too, from Wamp 3.2.6)
Voltra commentedon Mar 10, 2023
In the meantime, here's the rector config I use to circumvent the issue:
And I add the
monkey_patch.php
in theautoload.files
array in my composer.jsonlufog commentedon Mar 11, 2024
Does this relate to the fact that in PHP 8 (8.1.27, 8.2.16, 8.3.3), on Windows, unlink() cannot delete a currently running script? Since PHP 7 (7.4.33) doesn't have this problem, I guess it's a regression?
nicolas-grekas commentedon Jul 5, 2024
Is this issue still relevant? Didn't @cmb69 fix it in c7f24d9?
nicolas-grekas commentedon Jul 5, 2024
Ah, yes, #9351 is still opened as draft. Would be could is someone could take over!
Voltra commentedon Jul 5, 2024
I'm not sure if I could reproduce it as it was very "random" as to when the problem would occur, and I don't currently have access to the repo that had the issue
gggeek commentedon Jul 26, 2024
@nicolas-grekas I dont have MS build tooling installed any more, but I can help testing #9351 as long as there are prebuilt binaries I can download...
lufog commentedon Jul 26, 2024
The problem is reproducible in 100% of cases when updating GravCMS on Windows with PHP 8+ (on PHP 7 everything is fine).
Voltra commentedon Jul 26, 2024
That's interesting as my use case was Symfony's entity classes (or something related) cache and getting to hit the bug mid-request (i.e. when the file would be open/read prior to being replaced) was complex
johnstevenson commentedon Jul 27, 2024
See #7910 (comment)
Voltra commentedon Aug 14, 2024
Using my current WAMP setup, here are the PHP versions that suffer from the bug:
Here are the versions that don't: