Detect nonstandard or missing nanosecond-precision stat timestamps

Reported-by: maarten-k <maarten.kooyman@surfsara.nl>
This commit is contained in:
Eric Biggers 2016-09-23 21:56:19 -07:00
parent 76dcdec6f0
commit 64dc75786d
2 changed files with 34 additions and 6 deletions

View File

@ -11,24 +11,52 @@ echo "#define CONFIG_H"
tmpfile="$(mktemp -t libdeflate_config.XXXXXXXX)" tmpfile="$(mktemp -t libdeflate_config.XXXXXXXX)"
trap "rm -f \"$tmpfile\"" EXIT trap "rm -f \"$tmpfile\"" EXIT
program_compiles() {
echo "$1" > "$tmpfile"
$CC $PROG_CFLAGS -x c "$tmpfile" -o /dev/null > /dev/null 2>&1
}
check_function() { check_function() {
funcname="$1" funcname="$1"
macro="HAVE_$(echo $funcname | tr a-z A-Z)" macro="HAVE_$(echo $funcname | tr a-z A-Z)"
echo "int main() { $funcname(); }" > "$tmpfile"
echo echo
echo "/* Is the $funcname() function available? */" echo "/* Is the $funcname() function available? */"
if $CC $CFLAGS -x c $tmpfile -o /dev/null > /dev/null 2>&1; then if program_compiles "int main() { $funcname(); }"; then
echo "#define $macro 1" echo "#define $macro 1"
else else
echo "/* $macro is not set */" echo "/* $macro is not set */"
fi fi
} }
have_stat_field() {
program_compiles "#include <sys/types.h>
#include <sys/stat.h>
int main() { struct stat st; st.$1; }"
}
check_stat_nanosecond_precision() {
echo
echo "/* Does stat() provide nanosecond-precision timestamps? */"
if have_stat_field st_atim; then
echo "#define HAVE_STAT_NANOSECOND_PRECISION 1"
elif have_stat_field st_atimespec; then
# Nonstandard field names used by OS X and older BSDs
echo "#define HAVE_STAT_NANOSECOND_PRECISION 1"
echo "#define st_atim st_atimespec"
echo "#define st_mtim st_mtimespec"
echo "#define st_ctim st_ctimespec"
else
echo "/* HAVE_STAT_NANOSECOND_PRECISION is not set */"
fi
}
check_function clock_gettime check_function clock_gettime
check_function futimens check_function futimens
check_function futimes check_function futimes
check_function posix_fadvise check_function posix_fadvise
check_function posix_madvise check_function posix_madvise
check_stat_nanosecond_precision
echo echo
echo "#endif /* CONFIG_H */" echo "#endif /* CONFIG_H */"

View File

@ -257,23 +257,23 @@ restore_timestamps(struct file_stream *out, const tchar *newpath,
const struct stat *stbuf) const struct stat *stbuf)
{ {
int ret; int ret;
#if defined(HAVE_FUTIMENS) #if defined(HAVE_FUTIMENS) && defined(HAVE_STAT_NANOSECOND_PRECISION)
struct timespec times[2] = { struct timespec times[2] = {
stbuf->st_atim, stbuf->st_mtim, stbuf->st_atim, stbuf->st_mtim,
}; };
ret = futimens(out->fd, times); ret = futimens(out->fd, times);
#elif defined(HAVE_FUTIMES) #elif defined(HAVE_FUTIMES) && defined(HAVE_STAT_NANOSECOND_PRECISION)
struct timeval times[2] = { struct timeval times[2] = {
{ stbuf->st_atim.tv_sec, stbuf->st_atim.tv_nsec / 1000, }, { stbuf->st_atim.tv_sec, stbuf->st_atim.tv_nsec / 1000, },
{ stbuf->st_mtim.tv_sec, stbuf->st_mtim.tv_nsec / 1000, }, { stbuf->st_mtim.tv_sec, stbuf->st_mtim.tv_nsec / 1000, },
}; };
ret = futimes(out->fd, times); ret = futimes(out->fd, times);
#else /* HAVE_FUTIMES */ #else
struct tutimbuf times = { struct tutimbuf times = {
stbuf->st_atime, stbuf->st_mtime, stbuf->st_atime, stbuf->st_mtime,
}; };
ret = tutime(newpath, &times); ret = tutime(newpath, &times);
#endif /* !HAVE_FUTIMES */ #endif
if (ret != 0) if (ret != 0)
msg_errno("%"TS": unable to preserve timestamps", out->name); msg_errno("%"TS": unable to preserve timestamps", out->name);
} }