X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Futimens.c;h=bdb5a25ae61856a490232eaedbd1cbfa41091a94;hb=9f46144c41dd826d3bba1456f3f73497c570e87d;hp=cc0d1e8f2097963ec148ad1327fd6bbaf57bebad;hpb=0e3e69f9f9b31a7d8516bb9699471db6a43bd3c8;p=gnulib.git diff --git a/lib/utimens.c b/lib/utimens.c index cc0d1e8f2..bdb5a25ae 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -1,6 +1,6 @@ /* Set file access and modification times. - Copyright (C) 2003-2009 Free Software Foundation, Inc. + Copyright (C) 2003-2010 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 the @@ -169,6 +169,7 @@ fdutimens (char const *file, int fd, struct timespec const timespec[2]) struct timespec adjusted_timespec[2]; struct timespec *ts = timespec ? adjusted_timespec : NULL; int adjustment_needed = 0; + struct stat st; if (ts) { @@ -220,7 +221,6 @@ fdutimens (char const *file, int fd, struct timespec const timespec[2]) { int result; # if __linux__ - 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, but work if both times are either explicitly specified or @@ -237,6 +237,8 @@ fdutimens (char const *file, int fd, struct timespec const timespec[2]) ts[0] = get_stat_atime (&st); else if (ts[1].tv_nsec == UTIME_OMIT) ts[1] = get_stat_mtime (&st); + /* Note that st is good, in case utimensat gives ENOSYS. */ + adjustment_needed++; } # endif /* __linux__ */ # if HAVE_UTIMENSAT @@ -262,19 +264,20 @@ fdutimens (char const *file, int fd, struct timespec const timespec[2]) } # endif /* HAVE_UTIMENSAT */ # if HAVE_FUTIMENS - { - result = futimens (fd, ts); + if (0 <= fd) + { + result = futimens (fd, ts); # ifdef __linux__ - /* Work around the same bug as above. */ - if (0 < result) - errno = ENOSYS; + /* Work around the same bug as above. */ + if (0 < result) + errno = ENOSYS; # endif /* __linux__ */ - if (result == 0 || errno != ENOSYS) - { - utimensat_works_really = 1; - return result; - } - } + if (result == 0 || errno != ENOSYS) + { + utimensat_works_really = 1; + return result; + } + } # endif /* HAVE_FUTIMENS */ } utimensat_works_really = -1; @@ -287,8 +290,8 @@ fdutimens (char const *file, int fd, struct timespec const timespec[2]) if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0)) { - struct stat st; - if (fd < 0 ? stat (file, &st) : fstat (fd, &st)) + if (adjustment_needed != 3 + && (fd < 0 ? stat (file, &st) : fstat (fd, &st))) return -1; if (ts && update_timespec (&st, &ts)) return 0; @@ -422,7 +425,6 @@ lutimens (char const *file, struct timespec const timespec[2]) { int result; # if __linux__ - 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, but work if both times are either explicitly specified or @@ -439,6 +441,8 @@ lutimens (char const *file, struct timespec const timespec[2]) ts[0] = get_stat_atime (&st); else if (ts[1].tv_nsec == UTIME_OMIT) ts[1] = get_stat_mtime (&st); + /* Note that st is good, in case utimensat gives ENOSYS. */ + adjustment_needed++; } # endif /* __linux__ */ result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); @@ -469,7 +473,7 @@ lutimens (char const *file, struct timespec const timespec[2]) if (adjustment_needed || REPLACE_FUNC_STAT_FILE) { - if (lstat (file, &st)) + if (adjustment_needed != 3 && lstat (file, &st)) return -1; if (ts && update_timespec (&st, &ts)) return 0;