From: Paul Eggert Date: Wed, 1 May 2013 05:32:23 +0000 (-0700) Subject: utimens, utimensat: work around Solaris UTIME_OMIT bug X-Git-Tag: v0.1~153 X-Git-Url: http://erislabs.net/gitweb/?p=gnulib.git;a=commitdiff_plain;h=4bbfd284981dbc46d8a8c2116242aa7d5694b6af utimens, utimensat: work around Solaris UTIME_OMIT bug Solaris 11.1 and Solaris 10 have the same UTIME_OMIT bug that Linux kernel 2.6.32 does. Work around it in the same way. * doc/posix-functions/futimens.texi (futimens): * doc/posix-functions/utimensat.texi (utimensat): Document the bug. * lib/utimens.c (fdutimens, lutimens): * lib/utimensat.c (rpl_utimensat): Work around the bug. --- diff --git a/ChangeLog b/ChangeLog index b2f035415..e8f47e8b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2013-04-30 Paul Eggert + utimens, utimensat: work around Solaris UTIME_OMIT bug + Solaris 11.1 and Solaris 10 have the same UTIME_OMIT bug that + Linux kernel 2.6.32 does. Work around it in the same way. + * doc/posix-functions/futimens.texi (futimens): + * doc/posix-functions/utimensat.texi (utimensat): Document the bug. + * lib/utimens.c (fdutimens, lutimens): + * lib/utimensat.c (rpl_utimensat): Work around the bug. + gettext: now it's your responsibility to add -I$(top_builddir)/intl Formerly, it was your responsibility to do this for all Makefile.ams other than Gnulib's. Now it's your responsibility to do it for diff --git a/doc/posix-functions/futimens.texi b/doc/posix-functions/futimens.texi index e870b2b14..ab8882382 100644 --- a/doc/posix-functions/futimens.texi +++ b/doc/posix-functions/futimens.texi @@ -27,7 +27,7 @@ Linux kernel 2.6.25. @item When using @code{UTIME_OMIT} for the modification time, but specifying an access time, some systems fail to update the change time: -Linux kernel 2.6.32. +Linux kernel 2.6.32, Solaris 11.1. @item Passing @code{AT_FDCWD} as the fd argument does not properly fail with @code{EBADF} on some systems: diff --git a/doc/posix-functions/utimensat.texi b/doc/posix-functions/utimensat.texi index 776f5a593..bea138f46 100644 --- a/doc/posix-functions/utimensat.texi +++ b/doc/posix-functions/utimensat.texi @@ -33,7 +33,7 @@ Linux kernel 2.6.25. @item When using @code{UTIME_OMIT} for the modification time, but specifying an access time, some systems fail to update the change time: -Linux kernel 2.6.32. +Linux kernel 2.6.32, Solaris 11.1. @item Out-of-range values of @code{tv_nsec} do not lead to a failure on some platforms: diff --git a/lib/utimens.c b/lib/utimens.c index 87123605b..013843d6d 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -216,15 +216,19 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) if (0 <= utimensat_works_really) { int result; -# if __linux__ +# if __linux__ || __sun /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, but work if both times are either explicitly specified or UTIME_NOW. Work around it with a preparatory [f]stat prior to calling futimens/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. */ + where 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 (adjustment_needed == 2) { if (fd < 0 ? stat (file, &st) : fstat (fd, &st)) @@ -236,7 +240,7 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) /* Note that st is good, in case utimensat gives ENOSYS. */ adjustment_needed++; } -# endif /* __linux__ */ +# endif # if HAVE_UTIMENSAT if (fd < 0) { @@ -445,15 +449,19 @@ lutimens (char const *file, struct timespec const timespec[2]) if (0 <= lutimensat_works_really) { int result; -# if __linux__ +# if __linux__ || __sun /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, but work if both times are either explicitly specified or UTIME_NOW. Work around it with a preparatory lstat 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 (adjustment_needed == 2) { if (lstat (file, &st)) @@ -465,7 +473,7 @@ lutimens (char const *file, struct timespec const timespec[2]) /* Note that st is good, in case utimensat gives ENOSYS. */ adjustment_needed++; } -# endif /* __linux__ */ +# endif result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); # ifdef __linux__ /* Work around a kernel bug: diff --git a/lib/utimensat.c b/lib/utimensat.c index 01104002a..0c52b24e0 100644 --- a/lib/utimensat.c +++ b/lib/utimensat.c @@ -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)) { @@ -99,7 +103,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], 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