2010-11-28 20:01:32 +00:00
|
|
|
From e014ef2cf988a232a702292c82cd577719d08d8c Mon Sep 17 00:00:00 2001
|
2010-11-22 22:15:06 +00:00
|
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
|
|
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 +-
|
2010-11-28 20:01:32 +00:00
|
|
|
src/files.c | 46 +++++++++++++++++++++++++++++++++++-----------
|
|
|
|
4 files changed, 40 insertions(+), 13 deletions(-)
|
2010-11-22 22:15:06 +00:00
|
|
|
|
|
|
|
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
|
2010-11-28 20:01:32 +00:00
|
|
|
index 656a684..889c4a8 100644
|
2010-11-22 22:15:06 +00:00
|
|
|
--- 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
|
2010-11-28 20:01:32 +00:00
|
|
|
@@ -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
|
2010-11-22 22:15:06 +00:00
|
|
|
|
2010-11-28 20:01:32 +00:00
|
|
|
+ /* Set backup's file metadata. */
|
2010-11-22 22:15:06 +00:00
|
|
|
+ if (utime_wrap(backup_fd, backupname, &filetime) == -1
|
|
|
|
+ && !ISSET(INSECURE_BACKUP)) {
|
2010-11-28 20:01:32 +00:00
|
|
|
+ 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);
|
|
|
|
}
|
|
|
|
|
2010-11-22 22:15:06 +00:00
|
|
|
--
|
|
|
|
1.7.3.2
|
|
|
|
|