Thanks Eric.

What if touch follows following steps:
1. Try same steps as in "touch -c" in an attempt to update timestamp of the
file.
2. If this attempt fails due to errno indicating file was not present
(ENOENT?), then it uses the same filefd (of step 1) and openat() to create
the new file.


Why it bothers me? - Because "touch existing_file" and "touch -c
existing_file" raise different file system events.


On Mon, Jan 12, 2015 at 10:46 PM, Eric Blake <[email protected]> wrote:

> On 01/12/2015 10:09 AM, Anoop Sharma wrote:
> > touch makes open() system call even for already existing files as seen
> > below:
> >
> > # Create file abc
> > $touch abc
> >
> > # Attempt retouching it
> > $strace -e trace=open touch abc
> > open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
> > open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
> > open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE|O_CLOEXEC) =
> 3
> > *open("abc", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0666) = 3*
> > +++ exited with 0 +++
> > $
> >
> >
> > I think this behavior of touch is not in conformance with POSIX specs
> > because it specifies that for existing files only *utimensat*()
> > <
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimensat.html>
> > should
> > be called and not creat.
>
> Sorry, but this implementation conforms to POSIX.  POSIX only says the
> behavior is as-if utimensat had been used, but doesn't actually mandate
> that utimensat be the actual function called, nor that other functions
> cannot be called.  There is no way to determine whether a file exists,
> in order to determine whether to create vs. restamp it, without first
> making some other syscall; making open() as the first call then using
> futimens() is safer than making stat() as the first call followed by
> utimensat(), because there is a TOCTTOU race if you split the function
> calls in a way that someone can replace the file in between the two
> calls.  Performing futimens on an open fd results in actions equivalent
> to calling utimensat directly.
>
> Therefore, you have not found a bug.
>
> --
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>
>

Reply via email to