I’m seeing odd time sequencing of files when using clearcase version 8 dynamic views, which makes me wonder about an aspect of the (gnu) touch command. Running:

[sourcecode language=”bash”]
> cat u
rm -f touchedEarlier touchedLater

perl -e "open (F, ‘> touchedEarlier’) || die"
touch touchedLater

ls –full-time touchedEarlier touchedLater
[/sourcecode]

produces:

[sourcecode language=”bash”]
> ./u
-rw-r–r– 1 peeterj pdxdb2 0 2015-02-25 11:42:05.833044000 -0500 touchedEarlier
-rw-r–r– 1 peeterj pdxdb2 0 2015-02-25 11:42:05.000000000 -0500 touchedLater
[/sourcecode]

Notice that the file that is touched by doing a perl “open” ends up with a later time, despite the fact that it was done logically earlier than the touch.

Running this command outside of a clearcase dynamic view shows zeros only in the subsecond times (also the behaviour of clearcase V7). Needless to say, this difference in file times from their creation sequence wreaks havoc on make.

I was curious how the two touch methods differed, and stracing them shows that the touch differs by including a utimesat() syscall. The perl touch is:

open(“touchedEarlier”, O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff29cd29f0) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=0, …}) = 0
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
close(3) = 0
exit_group(0) = ?

whereas the touch command has:

open(“touchedLater”, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
dup2(3, 0) = 0
close(3) = 0
dup2(0, 0) = 0
utimensat(0, NULL, NULL, 0) = 0
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?

It appears that the touch command explicitly zeros the subsecond portion of the files’ timestamp.

I also see that perl’s File::Touch module does the same thing, but uses a different mechanism. I see the following in a strace of such a Touch() call:

stat(“xxyyzz”, 0x656060)                = -1 ENOENT (No such file or directory)
open(“xxyyzz”, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff16bb3c60) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=0, …}) = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
close(3)                                = 0
utimes(“xxyyzz”, {{1424884553, 0}, {1424884553, 0}}) = 0

I am very curious why touch and perl’s File::Touch() both explicitly zero the subsecond modification time for the file (using utimensat() or utimes() syscalls)?