Front page | perl.perl5.porters |
Postings from March 2016
[perl #127663] Safety for -i option
Thread Previous
|
Thread Next
From:
l.mai@web.de via RT
Date:
March 6, 2016 18:54
Subject:
[perl #127663] Safety for -i option
Message ID:
rt-4.0.18-25084-1457290461-94.127663-15-0@perl.org
On Sun Mar 06 05:58:12 2016, jkeenan wrote:
> On Sun Mar 06 02:32:46 2016, jiangyy@outlook.com wrote:
> >
> >
> >
> > Regards,
> > Yanyan Jiang 蒋炎岩
> > Institute of Computer Software,
> > Dept. of Computer Science, Nanjing University
> >
>
> From original report:
> #####
> Like sed, perl can be used with -i to change files in-place. However,
> our tool discovered that the saving procedure is not as safe as sed.
> The system call trace (from 5.22.1):
>
> open("file.txt", O_RDONLY|O_LARGEFILE) = 3
> _llseek(3, 0, [0], SEEK_CUR) = 0
> unlink("file.txt") = 0
>
> open("file.txt", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4
> read(3, ...)
> read(3, ...)
> write(4, ...) ...
> #####
>
> Can you supply us with: (a) the list of commands you invoked at the
> command-line to get these results; (b) some idea of the size of the
> file in question relative to the size of memory?
Here's my attempt:
% echo hi > tmp.txt
% strace -o strace.log perl -i -pe '' tmp.txt
Excerpt from strace.log:
open("tmp.txt", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, TCGETS, 0xbfdd070c) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
unlink("tmp.txt") = 0
open("tmp.txt", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4
ioctl(4, TCGETS, 0xbfdd070c) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(4, 0, [0], SEEK_CUR) = 0
fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fcntl64(4, F_SETFD, FD_CLOEXEC) = 0
fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fchmod(4, 0100644) = 0
read(3, "hi\n", 8192) = 3
read(3, "", 8192) = 0
write(4, "hi\n", 3) = 3
close(4) = 0
close(3) = 0
So, the file is tiny in this case (not sure why that matters?). Perl opens the input file (fd #3), unlinks it, then opens the same name again (fd #4), then streams data from fd 3 to fd 4.
If perl dies after the unlink() but before it is done writing to fd 4 and closing it, you get a truncated (or completely missing) output file.
---
via perlbug: queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=127663
Thread Previous
|
Thread Next