Mercurial > hg > octave-lojdl > gnulib-hg
changeset 12157:7fb8a2ac5948
utimens: validate futimens usage
Using gl_futimens(fd,NULL,times) as an implementation for futimens
won't work unless we reliably detect EBADF for out-of-range fd.
Also catches a Linux bug with futimens(AT_FDCWD,NULL) changing ".".
mingw <utime.h> has a bug where utime's second argument is not const.
* lib/utimens.c (gl_futimens): Require valid fd up front, using
fewer syscalls on failure later on. Avoid compiler warning on
mingw.
* modules/utimens (Depends-on): Add dup2.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Tue, 06 Oct 2009 12:23:32 -0600 |
parents | 3c7d1f073266 |
children | 899dd13e9f8b |
files | ChangeLog lib/utimens.c modules/utimens |
diffstat | 3 files changed, 23 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-10-10 Eric Blake <ebb9@byu.net> + utimens: validate futimens usage + * lib/utimens.c (gl_futimens): Require valid fd up front, using + fewer syscalls on failure later on. Avoid compiler warning on + mingw. + * modules/utimens (Depends-on): Add dup2. + utimens: add test * modules/utimens-tests: New test. * tests/test-utimens.h: New file.
--- a/lib/utimens.c +++ b/lib/utimens.c @@ -55,9 +55,22 @@ Return 0 on success, -1 (setting errno) on failure. */ int -gl_futimens (int fd _UNUSED_PARAMETER_, - char const *file, struct timespec const timespec[2]) +gl_futimens (int fd, char const *file, struct timespec const timespec[2]) { + /* Require that at least one of FD or FILE are valid. Works around + a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather + than failing. */ + if (!file) + { + if (fd < 0) + { + errno = EBADF; + return -1; + } + if (dup2 (fd, fd) != fd) + return -1; + } + /* Some Linux-based NFS clients are buggy, and mishandle time stamps of files in NFS file systems in some cases. We have no configure-time test for this, but please see @@ -163,17 +176,6 @@ #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; } @@ -182,7 +184,7 @@ #else { struct utimbuf utimbuf; - struct utimbuf const *ut; + struct utimbuf *ut; if (timespec) { utimbuf.actime = timespec[0].tv_sec;