From 23510b930ea31f7de8005e2f0ff6cab7062b4e26 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 19 Aug 2010 15:23:06 +0200 Subject: [PATCH 2/2] use futimens() if available, instead of utime() --- configure.ac | 1 + src/files.c | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 66f8ee3..f4975d3 100644 --- a/configure.ac +++ b/configure.ac @@ -468,6 +468,7 @@ int main(void) dnl Checks for functions. +AC_CHECK_FUNCS(futimens) if test "x$enable_utf8" != xno; then AC_CHECK_FUNCS(iswalnum iswpunct mblen mbstowcs mbtowc wctomb) diff --git a/src/files.c b/src/files.c index 99cc1b8..9a1bdcc 100644 --- a/src/files.c +++ b/src/files.c @@ -1570,6 +1570,29 @@ int copy_file(FILE *inn, FILE *out) return retval; } +#ifdef HAVE_FUTIMENS +/* set atime/mtime by file descriptor */ +int utime_wrap(int fd, const char *filename, struct utimbuf *ut) +{ + struct timespec times[2]; + (void) filename; + + times[0].tv_sec = ut->actime; + times[1].tv_sec = ut->modtime; + times[0].tv_nsec = 0L; + times[1].tv_nsec = 0L; + + return futimens(fd, times); +} +#else +/* set atime/mtime by file name */ +int utime_wrap(int fd, const char *filename, struct utimbuf *ut) +{ + (void) fd; + return utime(filename, ut); +} +#endif + /* Write a file out to disk. If f_open isn't NULL, we assume that it is * a stream associated with the file, and we don't try to open it * ourselves. If tmp is TRUE, we set the umask to disallow anyone else @@ -1789,17 +1812,9 @@ bool write_file(const char *name, FILE *f_open, bool tmp, fprintf(stderr, "Backing up %s to %s\n", realname, backupname); #endif - /* Copy the file. */ - copy_status = copy_file(f, backup_file); - - if (copy_status != 0) { - statusline(ALERT, _("Error reading %s: %s"), realname, - strerror(errno)); - goto cleanup_and_exit; - } - - /* And set its metadata. */ - if (utime(backupname, &filetime) == -1 && !ISSET(INSECURE_BACKUP)) { + /* Set backup's file metadata. */ + if (utime_wrap(backup_fd, backupname, &filetime) == -1 + && !ISSET(INSECURE_BACKUP)) { if (prompt_failed_backupwrite(backupname)) goto skip_backup; statusline(HUSH, _("Error writing backup file %s: %s"), @@ -1811,6 +1826,15 @@ bool write_file(const char *name, FILE *f_open, bool tmp, goto cleanup_and_exit; } + /* Copy the file. */ + copy_status = copy_file(f, backup_file); + + if (copy_status != 0) { + statusline(ALERT, _("Error reading %s: %s"), realname, + strerror(errno)); + goto cleanup_and_exit; + } + free(backupname); } -- 1.7.4