Missing fractional seconds in struct stat
I’m new to Alpine Linux so it’s likely I’m doing something wrong. For context, I’m running Alpine in Docker on Ubuntu:
docker run —cap-add SYS_PTRACE -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -e TERM=$TERM -it —rm alpine /bin/sh
Once prompt appeared, I typed the following commands:
touch /tmp/test
stat /tmp/test
Output:
File: /tmp/test
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 7ah/122d Inode: 2909137 Links: 1
Access: (0644/-rw-r—r—) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-06-07 12:14:02.000000000
Modify: 2019-06-07 12:14:02.000000000
Change: 2019-06-07 12:14:02.000000000
The unexpected thing in the output is that all timestamps have zero fractional seconds. I used strace to get details.
apk add strace
strace -v stat /tmp/test 2>&1 | grep lstat
The output indicates that fractional seconds are there (*_nsec fields).
lstat(“/tmp/test”, {st_dev=makedev(0, 122), st_ino=2909137, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=1559909642 /* 2019-06-07T12:14:02.906502175+0000 /, st_atime_nsec=906502175, st_mtime=1559909642 / 2019-06-07T12:14:02.906502175+0000 /, st_mtime_nsec=906502175, st_ctime=1559909642 / 2019-06-07T12:14:02.906502175+0000 */, st_ctime_nsec=906502175}) = 0
Then I compiled my own little program that calls lstat() and prints mtime.
apk add gcc musl-dev
cat >/tmp/mystat.c <<END
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
struct stat stat = {};
if (lstat(“/tmp/test”, &stat)) return 1;
printf(“%d\n”, (int)stat.st_mtim.tv_nsec);
}
END
gcc -o /tmp/mystat /tmp/mystat.c
/tmp/mystat
Output:
906502175
Note that it matches st_mtime_nsec in the output of strace.
I then installed coreutils and ran stat again.
apk add coreutils
stat /tmp/test
This time the output contains fractional seconds.
File: /tmp/test
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 7ah/122d Inode: 2909137 Links: 1
Access: (0644/-rw-r—r—) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-06-07 12:14:02.906502175 +0000
Modify: 2019-06-07 12:14:02.906502175 +0000
Change: 2019-06-07 12:14:02.906502175 +0000
Birth: -
Unfortunately, the reason reason I started poking stat in the first place is that git malfunctions and installing coreutils doesn’t fix it.
apk add git
mkdir /tmp/repo
cd /tmp/repo
git init
touch x
git add x
git ls-files —debug — x
The output of the last command:
x
ctime: 1559910752:0
mtime: 1559910752:0
dev: 122 ino: 3043460
uid: 0 gid: 0
size: 0 flags: 0
Once again all timestamps have zero fractional seconds. If I build git myself, it behaves as expected.
apk add autoconf zlib-dev libintl make binutils
cd /tmp
git clone —depth=1 https://github.com/git/git.git
cd git
make configure
./configure
make -j 20 git
cd /tmp/repo
touch y
/tmp/git/git add y
git ls-files —debug — x y
The output of the last command shows that the file added to the git index by /tmp/git/git has fractional seconds while the file added with the stock git doesn’t.
x
ctime: 1559910752:0
mtime: 1559910752:0
dev: 122 ino: 3043460
uid: 0 gid: 0
size: 0 flags: 0
y
ctime: 1559911277:273776861
mtime: 1559911277:273776861
dev: 122 ino: 3048048
uid: 0 gid: 0
size: 0 flags: 0
What am I doing wrong? How can I make git write fractional seconds to the index?
(from redmine: issue id 10542, created on 2019-06-07)