]>
Commit | Line | Data |
---|---|---|
8ba64de9 AM |
1 | --- coreutils-6.12/lib/utimens.c 2008-05-29 09:21:57.000000000 -0400 |
2 | +++ coreutils/lib/utimens.c 2008-06-07 11:36:50.000000000 -0400 | |
3 | @@ -96,20 +96,42 @@ | |
4 | #endif | |
5 | ||
6 | /* POSIX 200x added two interfaces to set file timestamps with | |
7 | - nanosecond resolution. */ | |
8 | + nanosecond resolution. We provide a fallback for ENOSYS (for | |
9 | + example, compiling against Linux 2.6.25 kernel headers and glibc | |
10 | + 2.7, but running on Linux 2.6.18 kernel). */ | |
11 | #if HAVE_UTIMENSAT | |
12 | if (fd < 0) | |
13 | - return utimensat (AT_FDCWD, file, timespec, 0); | |
14 | + { | |
15 | + int result = utimensat (AT_FDCWD, file, timespec, 0); | |
16 | +#ifdef __linux__ | |
17 | + /* Work around what might be a kernel bug: | |
18 | + http://bugzilla.redhat.com/442352 | |
19 | + http://bugzilla.redhat.com/449910 | |
20 | + It appears that utimensat can mistakenly return 280 rather | |
21 | + than 0 to indicate success. | |
22 | + FIXME: remove in 2010 or whenever the offending kernels | |
23 | + are no longer in common use. */ | |
24 | + if (0 < result) | |
25 | + result = 0; | |
26 | +#endif | |
27 | + | |
28 | + if (result == 0 || errno != ENOSYS) | |
29 | + return result; | |
30 | + } | |
31 | #endif | |
32 | #if HAVE_FUTIMENS | |
33 | - return futimens (fd, timespec); | |
34 | -#else | |
35 | + { | |
36 | + int result = futimens (fd, timespec); | |
37 | + if (result == 0 || errno != ENOSYS) | |
38 | + return result; | |
39 | + } | |
40 | +#endif | |
41 | ||
42 | /* The platform lacks an interface to set file timestamps with | |
43 | nanosecond resolution, so do the best we can, discarding any | |
44 | fractional part of the timestamp. */ | |
45 | { | |
46 | -# if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES | |
47 | +#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES | |
48 | struct timeval timeval[2]; | |
49 | struct timeval const *t; | |
50 | if (timespec) | |
51 | @@ -125,9 +147,9 @@ | |
52 | ||
53 | if (fd < 0) | |
54 | { | |
55 | -# if HAVE_FUTIMESAT | |
56 | +# if HAVE_FUTIMESAT | |
57 | return futimesat (AT_FDCWD, file, t); | |
58 | -# endif | |
59 | +# endif | |
60 | } | |
61 | else | |
62 | { | |
63 | @@ -141,21 +163,21 @@ | |
64 | worth optimizing, and who knows what other messed-up systems | |
65 | are out there? So play it safe and fall back on the code | |
66 | below. */ | |
67 | -# if HAVE_FUTIMESAT | |
68 | +# if HAVE_FUTIMESAT | |
69 | if (futimesat (fd, NULL, t) == 0) | |
70 | return 0; | |
71 | -# elif HAVE_FUTIMES | |
72 | +# elif HAVE_FUTIMES | |
73 | if (futimes (fd, t) == 0) | |
74 | return 0; | |
75 | -# endif | |
76 | +# endif | |
77 | } | |
78 | -# endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ | |
79 | +#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ | |
80 | ||
81 | if (!file) | |
82 | { | |
83 | -# if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) | |
84 | +#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) | |
85 | errno = ENOSYS; | |
86 | -# endif | |
87 | +#endif | |
88 | ||
89 | /* Prefer EBADF to ENOSYS if both error numbers apply. */ | |
90 | if (errno == ENOSYS) | |
91 | @@ -170,9 +192,9 @@ | |
92 | return -1; | |
93 | } | |
94 | ||
95 | -# if HAVE_WORKING_UTIMES | |
96 | +#if HAVE_WORKING_UTIMES | |
97 | return utimes (file, t); | |
98 | -# else | |
99 | +#else | |
100 | { | |
101 | struct utimbuf utimbuf; | |
102 | struct utimbuf const *ut; | |
103 | @@ -187,9 +209,8 @@ | |
104 | ||
105 | return utime (file, ut); | |
106 | } | |
107 | -# endif /* !HAVE_WORKING_UTIMES */ | |
108 | +#endif /* !HAVE_WORKING_UTIMES */ | |
109 | } | |
110 | -#endif /* !HAVE_FUTIMENS */ | |
111 | } | |
112 | ||
113 | /* Set the access and modification time stamps of FILE to be |