Bug 204093

Summary: perl -i resets file ACLs and EAs
Product: [Fedora] Fedora Reporter: Josh Kelley <joshkel>
Component: perlAssignee: Jitka Plesnikova <jplesnik>
Status: ASSIGNED --- QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: medium    
Version: rawhideCC: cweyl, kasal, mcepl, perl-devel
Target Milestone: ---Keywords: FutureFeature, Reopened
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2008-11-28 17:53:14 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Josh Kelley 2006-08-25 14:54:38 UTC
Description of problem:
When perl's -i option is used to do an in-place edit of a file, it resets the
ACLs and extended attributes on that file.

Since perl -i can be a very helpful tool for scripting and system
administration, it would be nice if it preserved ACLs and EAs.

Version-Release number of selected component (if applicable):
perl-5.8.8-5

How reproducible:
always

Steps to Reproduce:
1. touch testfile
2. setfacl -m u:testuser:r testfile
3. setfattr -n user.test testfile
4. perl -pi -e 's/Something/SomethingElse/' testfile
5. getfacl testfile; getfattr testfile

Actual results:
Nothing.

Expected results:
ACLs and EAs set in steps 2 and 3 above.

Additional info:

Comment 1 Jan Pazdziora 2008-02-27 12:35:15 UTC
This should aligned be under the perl component, not perl-XML-SAX.

The behaviour is still the same with perl-5.8.8-33.fc8.x86_64.

Comment 2 Marcela Mašláňová 2008-03-12 11:57:57 UTC
Reproduced with perl-5.10.0-14.fc9.i386

Comment 3 Matěj Cepl 2008-11-28 09:48:24 UTC
When it has been reproduce by maintainer, then it is not NEW.

Comment 4 Stepan Kasal 2008-11-28 13:35:07 UTC
With -i.bkp perl first moves the file to *.bkp and then creates a new file with the same name as the original file.
When option -i is given without any argument, the original file is deleted.  But again a new file is created against the original one.

The above is documented in "man perlrun".  The fact that owner and acl flags are not preserved is a logical consequence of theis implementation.

This is also consistent with the implementation of "sed -i".

To get the results you need, there are several ways:
- backup the acls of the files and restore them after the "perl -i" run,
- copy the file before the running perl (without the -i), or
- run perl (w/out -i) first and then copy the result to the original file

To sum up, the described behavior is not a bug and is probably not going to change.

I'm sorry that you had to wait years for this obvious answer.

Comment 5 Jan Pazdziora 2008-11-28 13:59:16 UTC
The reasoning in comment #4 is not correct. The perlrun man page does not explicitly state that file permisions are preserved, yet they are:

$ echo ppp > a
$ ls -l a
-rw-rw-r-- 1 adelton adelton 4 2008-11-28 14:52 a
$ chmod 600 a
$ ls -l a
-rw------- 1 adelton adelton 4 2008-11-28 14:52 a
$ perl -i -pe 's!ppp!qqq!' a
$ ls -l a
-rw------- 1 adelton adelton 4 2008-11-28 14:52 a
$

and strace shows that perl does an explicit chmod:

open("a", O_RDONLY)                     = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2b869470) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0600, st_size=4, ...}) = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
unlink("a")                             = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2b869470) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(4, 0, SEEK_CUR)                   = 0
fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
fchmod(4, 0100600)                      = 0
read(3, "ppp\n", 4096)                  = 4
read(3, "", 4096)                       = 0
write(4, "qqq\n", 4)                    = 4
close(4)                                = 0
close(3)                                = 0
exit_group(0)                           = ?

So perl goes the extra mile to leave the resulting file in a state as close to the original. It should do so with ACLs and EAs as well.

Reopening.

Comment 6 Stepan Kasal 2008-11-28 17:53:14 UTC
(In reply to comment #5)
> The reasoning in comment #4 is not correct.

You are right.

Both perl and GNU sed do set the mode of the new file according to the original one.  If the command is executed under root, they also change the ownership according to the original file.

Moreover "perl -i" sets the suid bits according to the original (even if run under ordinary user, when the ownership of the file cannot be preserved).

GNU sed -i does not copy the suid bits.

> So perl goes the extra mile to leave the resulting file in a state as close to
> the original.

Correct.

> It should do so with ACLs and EAs as well.

IOW, you propose that perl should strive to preserve all settable attributes of all possible underlying file systems.  I'd consider such a quest very futile.

OTOH, shouldn't we consider removing the mode/owner setting code to prevent the confusion by half-done work?

It is not clear to me which of these changes (if any) is better, I cannot accept the position that the current behaviour is a bug.  Instead, I tend to consider the proposal and an enhancement request.  Feel free to submit it to perlbug.

I do not think it would be wise for Fedora to diverge from upstream in this case.

Comment 7 Chris Weyl 2008-11-28 19:13:42 UTC
(In reply to comment #5)
> So perl goes the extra mile to leave the resulting file in a state as close to
> the original. It should do so with ACLs and EAs as well.
> 
> Reopening.

This would also fit nicely with the principle of least surprise, as well.  I know other tools (e.g. tar) at least support command line options to preserve acls/extattrs; something like that in Perl would not be unreasonable.

Have you taken this to upstream, and asked for guidance?

Comment 8 Stepan Kasal 2008-12-02 17:02:06 UTC
Chris, I admit this should be taken upstream.

Shall I file this enhancement request upstream with the comment that I oopose the idea, but I need their support so that my users stop reopening the bug?

Wouldn't it be less confusing for upstream if some of the supporters of the idea would file the enhancement request instead?

Comment 9 Stepan Kasal 2008-12-05 18:01:42 UTC
OK, so I wrote the mail to perl5-porters.  The true idea in my head was: "they keep reopening that, please support me that I can finally dismiss it".
But I tried to be fair and tried to write the mail as neutral as I can.

While writing the mail, I found out that the development tree of GNU sed has recetly got the ACL support.
That sounds like a strong argument for implementing the same in perl as well.
Oh, well.

Comment 10 Stepan Kasal 2008-12-08 11:54:12 UTC
Reported here:
http://thread.gmane.org/gmane.comp.lang.perl.perl5.porters/64704
at this moment, there is one answer for and one against.

Comment 12 Fedora Admin XMLRPC Client 2013-08-12 11:42:57 UTC
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.