X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Futimensat.c;h=f3a665190e119bb7d7af9be18d94821d5ab6e59a;hb=8866a241ddbf4a459347b7147e325f539e4c07fe;hp=caeeb5f03c07e1857c26eaf26ac3a4cd9a27eafa;hpb=1602f0afed21be664fcf5c42d59db07cc22c56d6;p=gnulib.git diff --git a/lib/utimensat.c b/lib/utimensat.c index caeeb5f03..f3a665190 100644 --- a/lib/utimensat.c +++ b/lib/utimensat.c @@ -1,5 +1,5 @@ /* Set the access and modification time of a file relative to directory fd. - Copyright (C) 2009-2012 Free Software Foundation, Inc. + Copyright (C) 2009-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,7 +48,7 @@ int rpl_utimensat (int fd, char const *file, struct timespec const times[2], int flag) { -# ifdef __linux__ +# if defined __linux__ || defined __sun struct timespec ts[2]; # endif @@ -57,7 +57,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], if (0 <= utimensat_works_really) { int result; -# ifdef __linux__ +# if defined __linux__ || defined __sun struct stat st; /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, @@ -65,8 +65,12 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], UTIME_NOW. Work around it with a preparatory [l]stat prior to calling utimensat; fortunately, there is not much timing impact due to the extra syscall even on file systems where - UTIME_OMIT would have worked. FIXME: Simplify this in 2012, - when file system bugs are no longer common. */ + UTIME_OMIT would have worked. + + The same bug occurs in Solaris 11.1 (Apr 2013). + + FIXME: Simplify this for Linux in 2016 and for Solaris in + 2024, when file system bugs are no longer common. */ if (times && (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT)) { @@ -89,17 +93,17 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], values. */ else if (times && ((times[0].tv_nsec != UTIME_NOW - && (times[0].tv_nsec < 0 - || times[0].tv_nsec >= 1000000000)) + && ! (0 <= times[0].tv_nsec + && times[0].tv_nsec < TIMESPEC_RESOLUTION)) || (times[1].tv_nsec != UTIME_NOW - && (times[1].tv_nsec < 0 - || times[1].tv_nsec >= 1000000000)))) + && ! (0 <= times[1].tv_nsec + && times[1].tv_nsec < TIMESPEC_RESOLUTION)))) { errno = EINVAL; return -1; } # endif -# endif /* __linux__ */ +# endif result = utimensat (fd, file, times, flag); /* Linux kernel 2.6.25 has a bug where it returns EINVAL for UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which