GNU bug report logs -
#31332
touch unnecessarily calls dup2
Previous Next
Reported by: John Steele Scott <toojays <at> toojays.net>
Date: Tue, 1 May 2018 15:28:02 UTC
Severity: normal
Tags: notabug
Done: Assaf Gordon <assafgordon <at> gmail.com>
Bug is archived. No further changes may be made.
Full log
Message #12 received at control <at> debbugs.gnu.org (full text, mbox):
tags 31332 notabug
close 31332
stop
On 2018-05-01 4:38 a.m., John Steele Scott wrote:
> From https://stackoverflow.com/questions/40446555/why-does-touch-call-the-dup2-syscall
>
> jscott <at> citra:/tmp$ touch --version | head -1
> touch (GNU coreutils) 8.25
> jscott <at> citra:/tmp$ strace -ttt touch foo 2>&1 | tail -9
> 1525170579.952032 open("foo", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
> 1525170579.952080 dup2(3, 0) = 0
> 1525170579.952119 close(3) = 0
> 1525170579.952156 utimensat(0, NULL, NULL, 0) = 0
> 1525170579.952209 close(0) = 0
> 1525170579.952257 close(1) = 0
> 1525170579.952294 close(2) = 0
> 1525170579.952333 exit_group(0) = ?
> 1525170579.952450 +++ exited with 0 +++
>
> My analysis from that discussion:
>
> It's a historical artifact.
>
> The open()+dup2() pattern comes from the fd_reopen() function, which is used
> by several of the programs in the coreutils code base.
>
Not exactly an "artifact" - but an indented operation.
The goal of "fd_reopen" is not just to open a file,
but to ensure the returned file descriptor (an "int") has a specific
value.
For example, standard input (STDIN) is typically file descriptor value
0. calling fd_reopen first opens the file (the kernel returns file
descriptor 3), then it ensures file descriptor 0 is associated with the
same file (and then, calling "close(3)" gets rid of the other file
descriptor).
Checking how fd_reopen is used in coreutils, it is almost always used
to ensure STDIN/STDOUT point to the desired file(s):
====
$ git grep fd_reopen
src/csplit.c: if (! STREQ (name, "-") && fd_reopen (STDIN_FILENO, name,
O_RDONLY, 0) < 0)
src/dd.c:/* Restart on EINTR from fd_reopen(). */
src/dd.c:ifd_reopen (int desired_fd, char const *file, int flag, mode_t
mode)
src/dd.c: ret = fd_reopen (desired_fd, file, flag, mode);
src/dd.c: if (ifd_reopen (STDIN_FILENO, input_file, O_RDONLY |
input_flags, 0) < 0)
src/dd.c: || ifd_reopen (STDOUT_FILENO, output_file, O_RDWR |
opts, perms) < 0)
src/dd.c: && (ifd_reopen (STDOUT_FILENO, output_file, O_WRONLY
| opts, perms)
src/nohup.c: if (fd_reopen (STDIN_FILENO, "/dev/null", O_WRONLY, 0)
< 0)
src/nohup.c: ? fd_reopen (STDOUT_FILENO, file, flags, mode)
src/nohup.c: ? fd_reopen (STDOUT_FILENO, in_home,
flags, mode)
src/split.c: && fd_reopen (STDIN_FILENO, infile, O_RDONLY, 0) < 0)
src/stty.c: if (fd_reopen (STDIN_FILENO, device_name, O_RDONLY |
O_NONBLOCK, 0) < 0)
src/touch.c: fd = fd_reopen (STDIN_FILENO, file,
===
This means the rest of the program can just operate on STDIN (or STDOUT).
As such, I'm closing this item.
Discussion can continue by replying to this thread.
-assaf
This bug report was last modified 6 years and 195 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.