From e014ef2cf988a232a702292c82cd577719d08d8c 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() --- config.h.in | 3 +++ configure | 2 +- configure.ac | 2 +- src/files.c | 46 +++++++++++++++++++++++++++++++++++----------- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/config.h.in b/config.h.in index 8fbe824..fb0e65d 100644 --- a/config.h.in +++ b/config.h.in @@ -64,6 +64,9 @@ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT +/* Define to 1 if you have the `futimens' function. */ +#undef HAVE_FUTIMENS + /* Define to 1 if you have the `getdelim' function. */ #undef HAVE_GETDELIM diff --git a/configure b/configure index 238dbf9..f1ef55b 100755 --- a/configure +++ b/configure @@ -7484,7 +7484,7 @@ fi -for ac_func in getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen vsnprintf +for ac_func in futimens getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen vsnprintf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.ac b/configure.ac index 6388c03..255ec5d 100644 --- a/configure.ac +++ b/configure.ac @@ -415,7 +415,7 @@ fi]) dnl Checks for functions. -AC_CHECK_FUNCS(getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen vsnprintf) +AC_CHECK_FUNCS(futimens getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen vsnprintf) if test x$enable_utf8 != xno; then AC_CHECK_FUNCS(iswalnum iswblank iswpunct iswspace nl_langinfo mblen mbstowcs mbtowc wctomb wcwidth) diff --git a/src/files.c b/src/files.c index 656a684..889c4a8 100644 --- a/src/files.c +++ b/src/files.c @@ -1434,6 +1434,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 @@ -1666,6 +1689,18 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type fprintf(stderr, "Backing up %s to %s\n", realname, backupname); #endif + /* Set backup's file metadata. */ + if (utime_wrap(backup_fd, backupname, &filetime) == -1 + && !ISSET(INSECURE_BACKUP)) { + statusbar(_("Error writing backup file %s: %s"), backupname, + strerror(errno)); + /* If we can't write to the backup, DONT go on, since + whatever caused the backup file to fail (e.g. disk + full may well cause the real file write to fail, which + means we could lose both the backup and the original! */ + goto cleanup_and_exit; + } + /* Copy the file. */ copy_status = copy_file(f, backup_file); @@ -1676,17 +1711,6 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type goto cleanup_and_exit; } - /* And set its metadata. */ - if (utime(backupname, &filetime) == -1 && !ISSET(INSECURE_BACKUP)) { - statusbar(_("Error writing backup file %s: %s"), backupname, - strerror(errno)); - /* If we can't write to the backup, DONT go on, since - whatever caused the backup file to fail (e.g. disk - full may well cause the real file write to fail, which - means we could lose both the backup and the original! */ - goto cleanup_and_exit; - } - free(backupname); } -- 1.7.3.2