Edit report at https://bugs.php.net/bug.php?id=81404&edit=1
ID: 81404
Updated by: cmb@php.net
Reported by: rdueck at mcmillan-mcgee dot com
Summary: rename() does not keep extended file attributes
Status: Open
-Type: Bug
+Type: Feature/Change Request
-Package: *General Issues
+Package: Filesystem function related
Operating System: Debian 10, Linux 4.19.0-17-amd64
PHP Version: 7.4.23
Block user comment: N
Private report: N
New Comment:
> I added an inode check and confirmed that both rename() and 'mv'
> are being performed as copy-and-delete when run from apache.
Thanks for checking. In this case this is more like a feature
request to me (and something that should be documented).
Previous Comments:
------------------------------------------------------------------------
[2021-08-31 20:00:16] rdueck at mcmillan-mcgee dot com
I added an inode check and confirmed that both rename() and 'mv' are being performed as
copy-and-delete when run from apache. 'mv' preserves extended attributes when copying, but
rename() does not.
Test script:
<?php
// Requires xattr:
// pecl install xattr
// then add 'extension=xattr.so' to php.ini
// ASSUME: current directory is not /tmp
$a = tempnam('/tmp','my');
$b = basename($a);
for ($i=0; $i<2; $i++) {
file_put_contents($a,'TestData');
$inode_a = stat($a)['ino'];
xattr_set($a,'owner','me');
switch($i){
case 0: rename($a,$b); $fn='rename'; break;
case 1: mv $a $b; $fn='mv'; break;
}
$inode_b = stat($b)['ino'];
$owner = xattr_get($b,'owner');
echo "$fn ".($owner=='me'?'SUCCEEDED':'FAILED').",
internal operation: ".($inode_a==$inode_b?'move':'copy')."\n";
}
------------------------------------------------------------------------
[2021-08-31 17:40:00] rdueck at mcmillan-mcgee dot com
I tried the test script from the command-line as the www-data user, and rename() still works
correctly.
I've also corrected the PHP version; I have not tested PHP 8.0.
------------------------------------------------------------------------
[2021-08-31 17:17:31] cmb@php.net
For files, PHP's rename tries to rename(2), but if that fails for
whatever reason, it actually copies the file, and removes the
original. The latter would indeed ignore extended file attributes.
I'm not sure though, whether this is the reason in your case.
------------------------------------------------------------------------
[2021-08-31 17:05:18] rdueck at mcmillan-mcgee dot com
Description:
------------
When running from Apache2 using apache-mod-php, rename() strips extended attributes. The same code
works from the command line, and the system 'mv' command works in both cases.
move_uploaded_file() has the same problem as rename().
Test script:
---------------
<?php
// Requires xattr:
// pecl install xattr
// then add 'extension=xattr.so' to php.ini
// ASSUME: current directory is not /tmp
$a = tempnam('/tmp','my');
$b = basename($a);
for ($i=0; $i<2; $i++) {
file_put_contents($a,'TestData');
xattr_set($a,'owner','me');
switch($i){
case 0: rename($a,$b); $fn='rename'; break;
case 1: mv $a $b; $fn='mv'; break;
}
$owner = xattr_get($b,'owner');
echo "$fn
".($owner=='me'?'SUCCEEDED':'FAILED')."\n";
}
Expected result:
----------------
rename SUCCEEDED
mv SUCCEEDED
Actual result:
--------------
rename FAILED
mv SUCCEEDED
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81404&edit=1