Mercurial > vim
diff src/memline.c @ 16453:4e9bea9b8025 v8.1.1231
patch 8.1.1231: asking about existing swap file unnecessarily
commit https://github.com/vim/vim/commit/67cf86bfff5fd5224d557d81cb146f46e33b831c
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Apr 28 22:25:38 2019 +0200
patch 8.1.1231: asking about existing swap file unnecessarily
Problem: Asking about existing swap file unnecessarily.
Solution: When it is safe, delete the swap file. Remove
HAS_SWAP_EXISTS_ACTION, it is always defined. (closes #1237)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 28 Apr 2019 22:30:06 +0200 |
parents | 7ae2396cef62 |
children | 1ae13586edf8 |
line wrap: on
line diff
--- a/src/memline.c +++ b/src/memline.c @@ -2159,9 +2159,8 @@ swapfile_info(char_u *fname) { msg_puts(_("\n process ID: ")); msg_outnum(char_to_long(b0.b0_pid)); -#if defined(UNIX) - /* EMX kill() not working correctly, it seems */ - if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0) +#if defined(UNIX) || defined(MSWIN) + if (mch_process_running((pid_t)char_to_long(b0.b0_pid))) { msg_puts(_(" (STILL RUNNING)")); # if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) @@ -2193,6 +2192,57 @@ swapfile_info(char_u *fname) return x; } +/* + * Return TRUE if the swap file looks OK and there are no changes, thus it can + * be safely deleted. + */ + static time_t +swapfile_unchanged(char_u *fname) +{ + stat_T st; + int fd; + struct block0 b0; + int ret = TRUE; +#ifdef UNIX + long pid; +#endif + + // must be able to stat the swap file + if (mch_stat((char *)fname, &st) == -1) + return FALSE; + + // must be able to read the first block + fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); + if (fd < 0) + return FALSE; + if (read_eintr(fd, &b0, sizeof(b0)) != sizeof(b0)) + { + close(fd); + return FALSE; + } + + // the ID and magic number must be correct + if (ml_check_b0_id(&b0) == FAIL|| b0_magic_wrong(&b0)) + ret = FALSE; + + // must be unchanged + if (b0.b0_dirty) + ret = FALSE; + +#if defined(UNIX) || defined(MSWIN) + // process must known and not be running + pid = char_to_long(b0.b0_pid); + if (pid == 0L || mch_process_running((pid_t)pid)) + ret = FALSE; +#endif + + // TODO: Should we check if the swap file was created on the current + // system? And the current user? + + close(fd); + return ret; +} + static int recov_file_names(char_u **names, char_u *path, int prepend_dot) { @@ -4757,9 +4807,8 @@ findswapname( if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED) && vim_strchr(p_shm, SHM_ATTENTION) == NULL) { -#if defined(HAS_SWAP_EXISTS_ACTION) int choice = 0; -#endif + stat_T st; #ifdef CREATE_DUMMY_FILE int did_use_dummy = FALSE; @@ -4779,13 +4828,25 @@ findswapname( #if (defined(UNIX) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)) process_still_running = FALSE; #endif + // It's safe to delete the swap file if all these are true: + // - the edited file exists + // - the swap file has no changes and looks OK + if (mch_stat((char *)buf->b_fname, &st) == 0 + && swapfile_unchanged(fname)) + { + choice = 4; + if (p_verbose > 0) + verb_msg(_("Found a swap file that is not useful, deleting it")); + } + #if defined(FEAT_EVAL) /* * If there is an SwapExists autocommand and we can handle * the response, trigger it. It may return 0 to ask the * user anyway. */ - if (swap_exists_action != SEA_NONE + if (choice == 0 + && swap_exists_action != SEA_NONE && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf)) choice = do_swapexists(buf, fname); @@ -4850,7 +4911,6 @@ findswapname( } #endif -#if defined(HAS_SWAP_EXISTS_ACTION) if (choice > 0) { switch (choice) @@ -4880,7 +4940,6 @@ findswapname( break; } else -#endif { msg_puts("\n"); if (msg_silent == 0)