Subject: touch unnecessarily calls dup2

From: John Steele Scott <[email-masked]>
Date: Tue, 1 May 2018 20:08:50 +0930

>From https://stackoverflow.com/questions/40446555/why-does-touch-call-the-dup2-syscall

jscott@citra:/tmp$ touch --version | head -1
touch (GNU coreutils) 8.25
jscott@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.

    Prior to coreutils commit e373bb1, fd_reopen() did not do open()+dup2(), but
    closed the desired file descriptor before opening a new one. This was the
    case when touch started using this function at coreutils commit 478bd89. Per
    that commit message, the intent was to reduce the number of file descriptors
    touch would have open.

In the scheme of things the extra call to dup2() is not a big deal. We've lived
with it for 10 years. On my laptop it would take 25,000 invocations of touch
before those unnecessary dup2() calls add up to a second. But touch is called a
lot, on systems all over the world. So maybe you guys care about this?

Cheers,

John