nano-devel
[Top][All Lists]
Advanced

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

[Nano-devel] [PATCH v4] files: check for a changed disk file also for 's


From: Benno Schulenberg
Subject: [Nano-devel] [PATCH v4] files: check for a changed disk file also for 'savefile' and --tempfile
Date: Sat, 30 Sep 2017 14:41:19 +0200

From: Viorel Bota <address@hidden>

Before writing a file out, nano should check that the file on disk
hasn't been modified since it was read -- not only for the normal
"Write Out" action (^O), but also for "Save File" (future ^S) and
for "Save and Exit" (^X when --tempfile is used).

When writing fails and --tempfile is in effect, don't go on to prompt
for a file name; instead let the user decide what she wants to do.

This fixes https://savannah.gnu.org/bugs/?51040.

Signed-off-by: Viorel Bota <address@hidden>
Signed-off-by: Benno Schulenberg <address@hidden>
---
 src/files.c | 47 +++++++++++++++++++++++++++++++----------------
 src/nano.c  |  2 +-
 src/proto.h |  2 +-
 src/text.c  |  2 +-
 4 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/src/files.c b/src/files.c
index e70bbfe9..a38518f1 100644
--- a/src/files.c
+++ b/src/files.c
@@ -2015,9 +2015,9 @@ bool write_marked_file(const char *name, FILE *f_open, 
bool tmp,
  * to disk regardless of whether the mark is on, and without prompting if
  * the TEMP_FILE flag is set and the current file has a name.  Return 0
  * on error, 1 on success, and 2 when the buffer is to be discarded. */
-int do_writeout(bool exiting)
+int do_writeout(bool exiting, bool withprompt)
 {
-    int i;
+    int i = 0;
     bool result = FALSE;
     kind_of_writing_type method = OVERWRITE;
     char *given;
@@ -2031,12 +2031,6 @@ int do_writeout(bool exiting)
     /* Display newlines in filenames as ^J. */
     as_an_at = FALSE;
 
-    if (exiting && ISSET(TEMP_FILE) && openfile->filename[0] != '\0') {
-       if (write_file(openfile->filename, NULL, FALSE, OVERWRITE, FALSE))
-           return 1;
-       /* If writing the file failed, go on to prompt for a new name. */
-    }
-
     given = mallocstrcpy(NULL,
 #ifndef NANO_TINY
        (openfile->mark_set && !exiting) ? "" :
@@ -2071,6 +2065,11 @@ int do_writeout(bool exiting)
 
        present_path = mallocstrcpy(present_path, "./");
 
+       /* When we shouldn't prompt, use the existing filename. */
+       if ((!withprompt || (ISSET(TEMP_FILE) && exiting)) &&
+                               openfile->filename[0] != '\0')
+           answer = mallocstrcpy(answer, openfile->filename);
+       else {
        /* If we're using restricted mode, and the filename isn't blank,
         * disable tab completion. */
        i = do_prompt(!ISSET(RESTRICTED) || openfile->filename[0] == '\0',
@@ -2085,6 +2084,7 @@ int do_writeout(bool exiting)
                "", ""
 #endif
                );
+       }
 
        if (i < 0) {
            statusbar(_("Cancelled"));
@@ -2214,12 +2214,29 @@ int do_writeout(bool exiting)
                        (openfile->current_stat->st_mtime < st.st_mtime ||
                        openfile->current_stat->st_dev != st.st_dev ||
                        openfile->current_stat->st_ino != st.st_ino)) {
+                   int response;
 
                    warn_and_shortly_pause(_("File on disk has changed"));
 
-                   if (do_yesno_prompt(FALSE, _("File was modified since "
-                               "you opened it; continue saving? ")) < 1)
-                       continue;
+                   response = do_yesno_prompt(FALSE, _("File was modified "
+                               "since you opened it; continue saving? "));
+                   blank_statusbar();
+
+                   /* When in tool mode and not called by 'savefile',
+                    * overwrite the file right here when requested. */
+                   if (ISSET(TEMP_FILE) && withprompt) {
+                       free(given);
+                       if (response == 1)
+                           return write_file(openfile->filename,
+                                       NULL, FALSE, OVERWRITE, FALSE);
+                       else if (response == 0)
+                           return 2;
+                       else
+                           return 0;
+                   } else if (response != 1) {
+                       free(given);
+                       return 1;
+                   }
                }
 #endif
            }
@@ -2248,7 +2265,7 @@ int do_writeout(bool exiting)
 void do_writeout_void(void)
 {
     /* If the user chose to discard the buffer, close it. */
-    if (do_writeout(FALSE) == 2)
+    if (do_writeout(FALSE, TRUE) == 2)
        close_and_go();
 }
 
@@ -2256,10 +2273,8 @@ void do_writeout_void(void)
 /* If it has a name, write the current file to disk without prompting. */
 void do_savefile(void)
 {
-    if (openfile->filename[0] != '\0')
-       write_file(openfile->filename, NULL, FALSE, OVERWRITE, FALSE);
-    else
-       do_writeout_void();
+    if (do_writeout(FALSE, FALSE) == 2)
+       close_and_go();
 }
 #endif
 
diff --git a/src/nano.c b/src/nano.c
index 9c53b729..298a841e 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1081,7 +1081,7 @@ void do_exit(void)
 
     /* If the user chose not to save, or if the user chose to save and
      * the save succeeded, we're ready to exit. */
-    if (i == 0 || (i == 1 && do_writeout(TRUE)))
+    if (i == 0 || (i == 1 && do_writeout(TRUE, TRUE) > 0))
        close_and_go();
     else if (i != 1)
        statusbar(_("Cancelled"));
diff --git a/src/proto.h b/src/proto.h
index 71c12d40..5199fd53 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -307,7 +307,7 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
 bool write_marked_file(const char *name, FILE *f_open, bool tmp,
        kind_of_writing_type method);
 #endif
-int do_writeout(bool exiting);
+int do_writeout(bool exiting, bool withprompt);
 void do_writeout_void(void);
 #ifndef NANO_TINY
 void do_savefile(void);
diff --git a/src/text.c b/src/text.c
index 1cc867d4..d09d7c4f 100644
--- a/src/text.c
+++ b/src/text.c
@@ -3084,7 +3084,7 @@ void do_linter(void)
        if (i == -1) {
            statusbar(_("Cancelled"));
            return;
-       } else if (i == 1 && (do_writeout(FALSE) != TRUE))
+       } else if (i == 1 && (do_writeout(FALSE, FALSE) != 1))
            return;
     }
 
-- 
2.14.1




reply via email to

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