Eric Blake <ebb9 <at> byu.net> writes: > Also, does utimensat(AT_FDCWD,"file",NULL,0) work, and it is just the > AT_SYMLINK_NOFOLLOW variant that fails with ENOSYS? If so, I see at least > one problem in lib/utimens.c - it shares a static variable between > lutimens and fdutimens, which means that if lutimens detects > AT_SYMLINK_NOFOLLOW failure, then fdutimens fails to even try utimensat in > the future.
This gnulib patch is necessary if you answer affirmatively to the above question; If I'm correct, it will fix the touch/trailing-slash and gnulib side of things, but we would still need a patch to coreutils testsuite to ignore ENOSYS failure in touch/no-dereference. >From 60e9adacc94170106b45352ee230d9db179287c1 Mon Sep 17 00:00:00 2001 From: Eric Blake <[email protected]> Date: Tue, 24 Nov 2009 10:00:18 -0700 Subject: [PATCH 1/2] utimes: fix configure grammar 'Checking determine whether...' doesn't read well. * m4/utimes.m4 (gl_FUNC_UTIMES): Delete spurious word. Signed-off-by: Eric Blake <[email protected]> --- ChangeLog | 5 +++++ m4/utimes.m4 | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9c4e1e..b76e351 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-11-24 Eric Blake <[email protected]> + + utimes: fix configure grammar + * m4/utimes.m4 (gl_FUNC_UTIMES): Delete spurious word. + 2009-11-24 Bruno Haible <[email protected]> duplocale: Fix logic bug. diff --git a/m4/utimes.m4 b/m4/utimes.m4 index 5b010ac..239a0db 100644 --- a/m4/utimes.m4 +++ b/m4/utimes.m4 @@ -1,4 +1,5 @@ # Detect some bugs in glibc's implementation of utimes. +# serial 2 dnl Copyright (C) 2003, 2004, 2005, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -19,8 +20,8 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_UTIMES], [ - AC_CACHE_CHECK([determine whether the utimes function works], - gl_cv_func_working_utimes, + AC_CACHE_CHECK([whether the utimes function works], + [gl_cv_func_working_utimes], [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <sys/types.h> -- 1.6.4.2 >From 007579b937c4c9422919c7f68761dd9aa75699a5 Mon Sep 17 00:00:00 2001 From: Eric Blake <[email protected]> Date: Tue, 24 Nov 2009 10:07:57 -0700 Subject: [PATCH 2/2] utimens: work around older Linux failure with symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lib/utimens.c (lutimensat_works_really): New variable. (fdutimens, lutimens): Use it to manage kernels that support nanosecond times on files, but not on symlinks. Reported by Ondřej Vašík. Signed-off-by: Eric Blake <[email protected]> --- ChangeLog | 6 ++++++ lib/utimens.c | 14 +++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b76e351..1fd4506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-11-24 Eric Blake <[email protected]> + utimens: work around older Linux failure with symlinks + * lib/utimens.c (lutimensat_works_really): New variable. + (fdutimens, lutimens): Use it to manage kernels that support + nanosecond times on files, but not on symlinks. + Reported by Ondřej Vašík. + utimes: fix configure grammar * m4/utimes.m4 (gl_FUNC_UTIMES): Delete spurious word. diff --git a/lib/utimens.c b/lib/utimens.c index eb63487..61221fd 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -54,10 +54,12 @@ struct utimbuf #undef utimensat #if HAVE_UTIMENSAT || HAVE_FUTIMENS -/* Cache variable for whether syscall works; used to avoid calling the - syscall if we know it will just fail with ENOSYS. 0 = unknown, 1 = - yes, -1 = no. */ +/* Cache variables for whether the utimensat syscall works; used to + avoid calling the syscall if we know it will just fail with ENOSYS. + There are some Linux kernel versions where a flag of 0 passes, but + not AT_SYMLINK_NOFOLLOW. 0 = unknown, 1 = yes, -1 = no. */ static int utimensat_works_really; +static int lutimensat_works_really; #endif /* HAVE_UTIMENSAT || HAVE_UTIMENSAT */ /* Solaris 9 mistakenly succeeds when given a non-directory with a @@ -242,6 +244,7 @@ fdutimens (char const *file, int fd, struct timespec const timespec[2]) # endif /* HAVE_FUTIMENS */ } utimensat_works_really = -1; + lutimensat_works_really = -1; #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ /* The platform lacks an interface to set file timestamps with @@ -381,7 +384,7 @@ lutimens (char const *file, struct timespec const timespec [2]) worry about bogus return values. */ #if HAVE_UTIMENSAT - if (0 <= utimensat_works_really) + if (0 <= lutimensat_works_really) { int result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); # ifdef __linux__ @@ -398,10 +401,11 @@ lutimens (char const *file, struct timespec const timespec [2]) if (result == 0 || errno != ENOSYS) { utimensat_works_really = 1; + lutimensat_works_really = 1; return result; } } - utimensat_works_really = -1; + lutimensat_works_really = -1; #endif /* HAVE_UTIMENSAT */ /* The platform lacks an interface to set file timestamps with -- 1.6.4.2
