nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nano-devel] [PATCH 2/2] use futimens() if available, instead of utime()


From: Kamil Dudka
Subject: [Nano-devel] [PATCH 2/2] use futimens() if available, instead of utime()
Date: Wed, 3 Feb 2016 12:32:07 +0100

---
 trunk/nano/configure.ac |  2 +-
 trunk/nano/src/files.c  | 58 ++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/trunk/nano/configure.ac b/trunk/nano/configure.ac
index 2df6404..910d69c 100644
--- a/trunk/nano/configure.ac
+++ b/trunk/nano/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/trunk/nano/src/files.c b/trunk/nano/src/files.c
index cbd81bf..2bc8bb3 100644
--- a/trunk/nano/src/files.c
+++ b/trunk/nano/src/files.c
@@ -1744,6 +1744,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
@@ -1985,26 +2008,35 @@ 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)) {
-           if (prompt_failed_backupwrite(backupname))
+       /* Set backup's file metadata. */
+       if (utime_wrap(backup_fd, backupname, &filetime) == -1
+               && !ISSET(INSECURE_BACKUP)) {
+           fclose(backup_file);
+           if (prompt_failed_backupwrite(backupname)) {
+               free(backupname);
                goto skip_backup;
+           }
            statusbar(_("Error writing backup file %s: %s"), backupname,
                        strerror(errno));
            /* If we can't write to the backup, DON'T 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! */
+           free(backupname);
+           goto cleanup_and_exit;
+       }
+
+       /* Copy contents of the original file to the backup file. */
+       copy_status = copy_file(f, backup_file);
+
+       /* copy_file() closed the files, make sure 'f' is not used any more. */
+       f = NULL;
+
+       if (copy_status != 0) {
+           statusbar(_("Error reading %s: %s"), realname,
+                       strerror(errno));
+           beep();
+           free(backupname);
            goto cleanup_and_exit;
        }
 
-- 
2.5.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]