Bug 1650041
Summary: | Perl 5.28.0 in-place edit broken | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | wyonen <m.schwartz> |
Component: | perl | Assignee: | Jitka Plesnikova <jplesnik> |
Status: | CLOSED ERRATA | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
Severity: | high | Docs Contact: | |
Priority: | unspecified | ||
Version: | 29 | CC: | caillon+fedoraproject, iarnell, jplesnik, kasal, mbarnes, mmaslano, m.schwartz, perl-devel, ppisar, psabata, rhughes, sandmann, tcallawa |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | Unspecified | ||
OS: | Unspecified | ||
URL: | https://rt.perl.org/Public/Bug/Display.html?id=133659 | ||
Whiteboard: | |||
Fixed In Version: | perl-5.28.1-427.fc30 | Doc Type: | If docs needed, set a value |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2018-12-10 23:19:57 UTC | Type: | Bug |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
wyonen
2018-11-15 09:03:11 UTC
This looks like a glitch when more secure file replacement was added into perl code. $ cat test 1 $ strace perl -i -e '$/=undef; $a=<>; $a=~s/1/2/; print $a' test openat(AT_FDCWD, "test", O_RDONLY|O_CLOEXEC) = 3 ioctl(3, TCGETS, 0x7ffeb193f510) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 fstat(3, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0 umask(0177) = 002 getpid() = 1192 openat(AT_FDCWD, "XXH6qplJ", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0600) = 4 fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC) umask(002) = 0177 fcntl(4, F_SETFD, FD_CLOEXEC) = 0 ioctl(4, TCGETS, 0x7ffeb193f5a0) = -1 ENOTTY (Inappropriate ioctl for device) lseek(4, 0, SEEK_CUR) = 0 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 getpid() = 1192 openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 5 fstat(5, {st_mode=S_IFDIR|S_ISVTX|0777, st_size=180, ...}) = 0 brk(NULL) = 0x55f03b859000 brk(0x55f03b87b000) = 0x55f03b87b000 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 fchmod(4, 0100664) = 0 fstat(3, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0 read(3, "1\n", 8192) = 2 read(3, "", 8192) = 0 [...] write(4, "2\n", 2) = 2 close(3) = 0 getpid() = 1192 close(4) = 0 unlinkat(5, "XXH6qplJ", 0) = 0 [...] close(5) = 0 exit_group(0) = ? It unlinks the output file instead of renaming it to the original input file name as it happens when editing per-line: $ strace perl -i -p -e 's/1/2/' test [...] openat(AT_FDCWD, "test", O_RDONLY|O_CLOEXEC) = 3 ioctl(3, TCGETS, 0x7fff259cc550) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 fstat(3, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0 umask(0177) = 002 getpid() = 1196 openat(AT_FDCWD, "XXJAnFeW", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0600) = 4 fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC) umask(002) = 0177 fcntl(4, F_SETFD, FD_CLOEXEC) = 0 ioctl(4, TCGETS, 0x7fff259cc5e0) = -1 ENOTTY (Inappropriate ioctl for device) lseek(4, 0, SEEK_CUR) = 0 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 getpid() = 1196 openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 5 fstat(5, {st_mode=S_IFDIR|S_ISVTX|0777, st_size=180, ...}) = 0 brk(NULL) = 0x5559d5c60000 brk(0x5559d5c82000) = 0x5559d5c82000 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 fchmod(4, 0100664) = 0 read(3, "1\n", 8192) = 2 read(3, "", 8192) = 0 write(4, "2\n", 2) = 2 close(4) = 0 getpid() = 1196 renameat(5, "XXJAnFeW", 5, "test") = 0 close(5) = 0 close(3) = 0 [...] exit_group(0) = ? Playing with developmental Perl tree, this works: $ ./perl -Ilib -i -e '$/=undef; while ($_=<>) {s/1/2/; print}' /tmp/test This does not work: $ ./perl -Ilib -i -e '$/=undef; $_=<>; {s/1/2/; print}' /tmp/test It seems there is a special handling for "while(<>)" that triggers the final rename. I will forward this bug report to Perl 5 Porters. Thanks, Petr! Perl 5 porters recommend calling "close ARGVOUT" explicitly as a workaround because the file replacement is triggered by closing the file handle (that normally happens by consecutive "<>" call that's called only once in your code): $ ./perl -i -e 'local $/; my $s=<>; $s=~s/FAILED/OK/; print $s; close ARGVOUT' Thanks again for the analysis and both workarounds! perl-5.28.1-427.fc29 has been submitted as an update to Fedora 29. https://bodhi.fedoraproject.org/updates/FEDORA-2018-55eef04b2c perl-5.28.1-427.fc29 has been pushed to the Fedora 29 testing repository. If problems still persist, please make note of it in this bug report. See https://fedoraproject.org/wiki/QA:Updates_Testing for instructions on how to install test updates. You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-55eef04b2c An update associated with this bug has been pushed to stable. |