summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2006-04-15 07:39:46 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2006-04-15 07:39:46 +0000
commit39448a239a550a59cddd58f2856eb991b089d467 (patch)
tree059b6cdf3fc4dee3b2d7a26e5ef6b017b9ff667d /lib
parentca094485f9be3f6702367d9561e711fee946461d (diff)
downloadcoreutils-39448a239a550a59cddd58f2856eb991b089d467.tar.xz
(futimens): glibc futimesat messes up if /proc isn't mounted.
Diffstat (limited to 'lib')
-rw-r--r--lib/ChangeLog5
-rw-r--r--lib/utimens.c52
2 files changed, 34 insertions, 23 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 8962affd6..265e278ac 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2006-04-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ * utimens.c (futimens): glibc futimesat messes up if /proc
+ isn't mounted. Problem reported by Kir Kolyshkin.
+
2006-04-14 Jim Meyering <jim@meyering.net>
Remove unreachable code and plug leaks in code that handles degenerate
diff --git a/lib/utimens.c b/lib/utimens.c
index 8d8bef468..11f04d1ad 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
@@ -91,34 +93,40 @@ 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;
-
- /* Don't worry about trying to speed things up by returning right
- away here. glibc futimes 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 futimes incorrectly fails with errno == EACCES. If futimes
- fails with 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. */
- }
# endif
+ }
#endif
-#if ! HAVE_FUTIMESAT
-
if (!file)
{
-# if ! (HAVE_WORKING_UTIMES && HAVE_FUTIMES)
+#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
errno = ENOSYS;
-# endif
+#endif
/* Prefer EBADF to ENOSYS if both error numbers apply. */
if (errno == ENOSYS)
@@ -133,9 +141,9 @@ futimens (int fd ATTRIBUTE_UNUSED,
return -1;
}
-# if HAVE_WORKING_UTIMES
+#if HAVE_WORKING_UTIMES
return utimes (file, t);
-# else
+#else
{
struct utimbuf utimbuf;
struct utimbuf const *ut;
@@ -150,8 +158,6 @@ futimens (int fd ATTRIBUTE_UNUSED,
return utime (file, ut);
}
-# endif
-
#endif
}