From 23510b930ea31f7de8005e2f0ff6cab7062b4e26 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 19 Aug 2010 15:23:06 +0200 Subject: [PATCH 3/3] use futimens() if available, instead of utime() --- config.h.in | 3 +++ configure | 2 +- configure.ac | 2 +- src/files.c | 48 ++++++++++++++++++++++++++++++++++++------------ 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/config.h.in b/config.h.in index 52e13f1..cb17b29 100644 --- a/config.h.in +++ b/config.h.in @@ -69,6 +69,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 02733c7..1805e53 100755 --- a/configure +++ b/configure @@ -7755,7 +7755,7 @@ fi -for ac_func in getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen snprintf vsnprintf +for ac_func in futimens getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen snprintf 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 66f8ee3..f4975d3 100644 --- a/configure.ac +++ b/configure.ac @@ -428,7 +428,7 @@ int main(void) dnl Checks for functions. -AC_CHECK_FUNCS(getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen snprintf vsnprintf) +AC_CHECK_FUNCS(futimens getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen snprintf 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 99cc1b8..9a1bdcc 100644 --- a/src/files.c +++ b/src/files.c @@ -1672,6 +1672,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 @@ -1913,18 +1936,9 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type 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) { - statusbar(_("Error reading %s: %s"), realname, - strerror(errno)); - beep(); - 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; statusbar(_("Error writing backup file %s: %s"), backupname, @@ -1936,6 +1950,16 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type goto cleanup_and_exit; } + /* Copy the file. */ + copy_status = copy_file(f, backup_file); + + if (copy_status != 0) { + statusbar(_("Error reading %s: %s"), realname, + strerror(errno)); + beep(); + goto cleanup_and_exit; + } + free(backupname); } -- 1.7.4