X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Futimens.c;h=1489df05caeb0752acdf92a4cafef59aa56ae51f;hb=a897449aaae8e6c051f3b9daaf984de5c5e092f3;hp=b60ec879a3a158c6820c42789bb43582e85ad926;hpb=52bcc4fca9336df9167ed2f5d0aeaeaf874302c2;p=gnulib.git diff --git a/lib/utimens.c b/lib/utimens.c index b60ec879a..1489df05c 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -1,4 +1,6 @@ -/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +/* Set file access and modification times. + + Copyright (C) 2003, 2004, 2005, 2006 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 @@ -26,6 +28,7 @@ #include #include +#include #if HAVE_UTIME_H # include @@ -51,8 +54,10 @@ struct utimbuf # endif #endif -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ +# define __attribute__(x) +# endif #endif #ifndef ATTRIBUTE_UNUSED @@ -90,40 +95,57 @@ futimens (int fd ATTRIBUTE_UNUSED, else t = NULL; + + if (fd < 0) + { # if HAVE_FUTIMESAT - return fd < 0 ? futimesat (AT_FDCWD, file, t) : futimesat (fd, NULL, t); -# elif HAVE_FUTIMES - if (0 <= fd) + return futimesat (AT_FDCWD, file, t); +# endif + } + else { + /* If futimesat or futimes fails here, don't try to speed things + up by returning right away. glibc can incorrectly fail with + errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0 + in high security mode doesn't allow ordinary users to read + /proc/self, so glibc incorrectly fails with errno == EACCES. + If errno == EIO, EPERM, or EROFS, it's probably safe to fail + right away, but these cases are rare enough that they're not + worth optimizing, and who knows what other messed-up systems + are out there? So play it safe and fall back on the code + below. */ +# if HAVE_FUTIMESAT + if (futimesat (fd, NULL, t) == 0) + return 0; +# elif HAVE_FUTIMES if (futimes (fd, t) == 0) return 0; - - /* On GNU/Linux without the futimes syscall and without /proc - mounted, glibc futimes fails with errno == ENOENT. Fall back - on utimes if we get a weird error number like that. */ - switch (errno) - { - case EACCES: - case EIO: - case EPERM: - case EROFS: - return -1; - } - } # endif + } #endif -#if ! HAVE_FUTIMES_AT - if (!file) { +#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) errno = ENOSYS; +#endif + + /* Prefer EBADF to ENOSYS if both error numbers apply. */ + if (errno == ENOSYS) + { + int fd2 = dup (fd); + int dup_errno = errno; + if (0 <= fd2) + close (fd2); + errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS); + } + return -1; } -# if HAVE_WORKING_UTIMES +#if HAVE_WORKING_UTIMES return utimes (file, t); -# else +#else { struct utimbuf utimbuf; struct utimbuf const *ut; @@ -138,8 +160,6 @@ futimens (int fd ATTRIBUTE_UNUSED, return utime (file, ut); } -# endif - #endif }