files: check for a changed disk file also for 'savefile' and --tempfile
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 <botaviorel@gmail.com> Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>master
parent
80ed2568fc
commit
217cfbf362
47
src/files.c
47
src/files.c
|
@ -2017,9 +2017,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
|
* 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
|
* 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. */
|
* 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;
|
bool result = FALSE;
|
||||||
kind_of_writing_type method = OVERWRITE;
|
kind_of_writing_type method = OVERWRITE;
|
||||||
char *given;
|
char *given;
|
||||||
|
@ -2033,12 +2033,6 @@ int do_writeout(bool exiting)
|
||||||
/* Display newlines in filenames as ^J. */
|
/* Display newlines in filenames as ^J. */
|
||||||
as_an_at = FALSE;
|
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,
|
given = mallocstrcpy(NULL,
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
(openfile->mark_set && !exiting) ? "" :
|
(openfile->mark_set && !exiting) ? "" :
|
||||||
|
@ -2073,6 +2067,11 @@ int do_writeout(bool exiting)
|
||||||
|
|
||||||
present_path = mallocstrcpy(present_path, "./");
|
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,
|
/* If we're using restricted mode, and the filename isn't blank,
|
||||||
* disable tab completion. */
|
* disable tab completion. */
|
||||||
i = do_prompt(!ISSET(RESTRICTED) || openfile->filename[0] == '\0',
|
i = do_prompt(!ISSET(RESTRICTED) || openfile->filename[0] == '\0',
|
||||||
|
@ -2087,6 +2086,7 @@ int do_writeout(bool exiting)
|
||||||
"", ""
|
"", ""
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
statusbar(_("Cancelled"));
|
statusbar(_("Cancelled"));
|
||||||
|
@ -2216,12 +2216,29 @@ int do_writeout(bool exiting)
|
||||||
(openfile->current_stat->st_mtime < st.st_mtime ||
|
(openfile->current_stat->st_mtime < st.st_mtime ||
|
||||||
openfile->current_stat->st_dev != st.st_dev ||
|
openfile->current_stat->st_dev != st.st_dev ||
|
||||||
openfile->current_stat->st_ino != st.st_ino)) {
|
openfile->current_stat->st_ino != st.st_ino)) {
|
||||||
|
int response;
|
||||||
|
|
||||||
warn_and_shortly_pause(_("File on disk has changed"));
|
warn_and_shortly_pause(_("File on disk has changed"));
|
||||||
|
|
||||||
if (do_yesno_prompt(FALSE, _("File was modified since "
|
response = do_yesno_prompt(FALSE, _("File was modified "
|
||||||
"you opened it; continue saving? ")) < 1)
|
"since you opened it; continue saving? "));
|
||||||
continue;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2250,7 +2267,7 @@ int do_writeout(bool exiting)
|
||||||
void do_writeout_void(void)
|
void do_writeout_void(void)
|
||||||
{
|
{
|
||||||
/* If the user chose to discard the buffer, close it. */
|
/* If the user chose to discard the buffer, close it. */
|
||||||
if (do_writeout(FALSE) == 2)
|
if (do_writeout(FALSE, TRUE) == 2)
|
||||||
close_and_go();
|
close_and_go();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2258,10 +2275,8 @@ void do_writeout_void(void)
|
||||||
/* If it has a name, write the current file to disk without prompting. */
|
/* If it has a name, write the current file to disk without prompting. */
|
||||||
void do_savefile(void)
|
void do_savefile(void)
|
||||||
{
|
{
|
||||||
if (openfile->filename[0] != '\0')
|
if (do_writeout(FALSE, FALSE) == 2)
|
||||||
write_file(openfile->filename, NULL, FALSE, OVERWRITE, FALSE);
|
close_and_go();
|
||||||
else
|
|
||||||
do_writeout_void();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ void do_exit(void)
|
||||||
|
|
||||||
/* If the user chose not to save, or if the user chose to save and
|
/* If the user chose not to save, or if the user chose to save and
|
||||||
* the save succeeded, we're ready to exit. */
|
* 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();
|
close_and_go();
|
||||||
else if (i != 1)
|
else if (i != 1)
|
||||||
statusbar(_("Cancelled"));
|
statusbar(_("Cancelled"));
|
||||||
|
|
|
@ -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,
|
bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||||
kind_of_writing_type method);
|
kind_of_writing_type method);
|
||||||
#endif
|
#endif
|
||||||
int do_writeout(bool exiting);
|
int do_writeout(bool exiting, bool withprompt);
|
||||||
void do_writeout_void(void);
|
void do_writeout_void(void);
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
void do_savefile(void);
|
void do_savefile(void);
|
||||||
|
|
|
@ -3084,7 +3084,7 @@ void do_linter(void)
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
statusbar(_("Cancelled"));
|
statusbar(_("Cancelled"));
|
||||||
return;
|
return;
|
||||||
} else if (i == 1 && (do_writeout(FALSE) != TRUE))
|
} else if (i == 1 && (do_writeout(FALSE, FALSE) != 1))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue