X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnu%2Futimensat.c;h=de7d595e365afe1f0ebdfa9c86388ff70ac92edd;hb=daa269958ad8d50ef8154ccb65e58acaf7a6dd99;hp=29889eb294ff41f98c3c6e83b2a5f1551cf40ab9;hpb=1a44d77d50f4fb37c0410eed04b82303624ea2ec;p=debian%2Ftar diff --git a/gnu/utimensat.c b/gnu/utimensat.c index 29889eb2..de7d595e 100644 --- a/gnu/utimensat.c +++ b/gnu/utimensat.c @@ -1,7 +1,7 @@ /* -*- buffer-read-only: t -*- vi: set ro: */ /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ /* Set the access and modification time of a file relative to directory fd. - Copyright (C) 2009-2011 Free Software Foundation, Inc. + Copyright (C) 2009-2013 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 @@ -50,22 +50,29 @@ int rpl_utimensat (int fd, char const *file, struct timespec const times[2], int flag) { +# if defined __linux__ || defined __sun + struct timespec ts[2]; +# endif + /* See comments in utimens.c for details. */ static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */ if (0 <= utimensat_works_really) { int result; -# ifdef __linux__ +# if defined __linux__ || defined __sun struct stat st; - struct timespec ts[2]; /* 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 UTIME_NOW. Work around it with a preparatory [l]stat prior to calling utimensat; fortunately, there is not much timing impact due to the extra syscall even on file systems where - UTIME_OMIT would have worked. FIXME: Simplify this in 2012, - when file system bugs are no longer common. */ + UTIME_OMIT would have worked. + + The same bug occurs in Solaris 11.1 (Apr 2013). + + FIXME: Simplify this for Linux in 2016 and for Solaris in + 2024, when file system bugs are no longer common. */ if (times && (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT)) { @@ -83,7 +90,22 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], ts[1] = times[1]; times = ts; } -# endif /* __linux__ */ +# ifdef __hppa__ + /* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec + values. */ + else if (times + && ((times[0].tv_nsec != UTIME_NOW + && (times[0].tv_nsec < 0 + || times[0].tv_nsec >= 1000000000)) + || (times[1].tv_nsec != UTIME_NOW + && (times[1].tv_nsec < 0 + || times[1].tv_nsec >= 1000000000)))) + { + errno = EINVAL; + return -1; + } +# endif +# endif result = utimensat (fd, file, times, flag); /* Linux kernel 2.6.25 has a bug where it returns EINVAL for UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which