Skip to content

Commit f883508

Browse files
committed
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Problem: It is easy to make mistakes when cleaning up swap files after the system crashed. Solution: Warn for the process still running after recovery. Do not automatically delete a swap file created on another system. (David Fries, closes #7273)
1 parent ea69685 commit f883508

3 files changed

Lines changed: 77 additions & 3 deletions

File tree

src/memline.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,7 +1690,17 @@ ml_recover(int checkext)
16901690
}
16911691
else
16921692
msg(_("Recovery completed. Buffer contents equals file contents."));
1693-
msg_puts(_("\nYou may want to delete the .swp file now.\n\n"));
1693+
msg_puts(_("\nYou may want to delete the .swp file now."));
1694+
#if defined(UNIX) || defined(MSWIN)
1695+
if (mch_process_running(char_to_long(b0p->b0_pid)))
1696+
{
1697+
// Warn there could be an active Vim on the same file, the user may
1698+
// want to kill it.
1699+
msg_puts(_("\nNote: process STILL RUNNING: "));
1700+
msg_outnum(char_to_long(b0p->b0_pid));
1701+
}
1702+
#endif
1703+
msg_puts("\n\n");
16941704
cmdline_row = msg_row;
16951705
}
16961706
#ifdef FEAT_CRYPT
@@ -2230,14 +2240,30 @@ swapfile_unchanged(char_u *fname)
22302240
ret = FALSE;
22312241

22322242
#if defined(UNIX) || defined(MSWIN)
2243+
// Host name must be known and must equal the current host name, otherwise
2244+
// comparing pid is meaningless.
2245+
if (*(b0.b0_hname) == NUL)
2246+
{
2247+
ret = FALSE;
2248+
}
2249+
else
2250+
{
2251+
char_u hostname[B0_HNAME_SIZE];
2252+
2253+
mch_get_host_name(hostname, B0_HNAME_SIZE);
2254+
hostname[B0_HNAME_SIZE - 1] = NUL;
2255+
if (STRICMP(b0.b0_hname, hostname) != 0)
2256+
ret = FALSE;
2257+
}
2258+
22332259
// process must be known and not be running
22342260
pid = char_to_long(b0.b0_pid);
22352261
if (pid == 0L || mch_process_running(pid))
22362262
ret = FALSE;
22372263
#endif
22382264

2239-
// TODO: Should we check if the swap file was created on the current
2240-
// system? And the current user?
2265+
// We do not check the user, it should be irrelevant for whether the swap
2266+
// file is still useful.
22412267

22422268
close(fd);
22432269
return ret;

src/testdir/test_swap.vim

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,50 @@ func Test_swap_symlink()
403403
call delete('Xswapdir', 'rf')
404404
endfunc
405405

406+
func Test_swap_auto_delete()
407+
" Create a valid swapfile by editing a file with a special extension.
408+
split Xtest.scr
409+
call setline(1, ['one', 'two', 'three'])
410+
write " file is written, not modified
411+
write " write again to make sure the swapfile is created
412+
" read the swapfile as a Blob
413+
let swapfile_name = swapname('%')
414+
let swapfile_bytes = readfile(swapfile_name, 'B')
415+
416+
" Forget about the file, recreate the swap file, then edit it again. The
417+
" swap file should be automatically deleted.
418+
bwipe!
419+
" change the process ID to avoid the "still running" warning
420+
let swapfile_bytes[24] = 0x99
421+
call writefile(swapfile_bytes, swapfile_name)
422+
edit Xtest.scr
423+
" will end up using the same swap file after deleting the existing one
424+
call assert_equal(swapfile_name, swapname('%'))
425+
bwipe!
426+
427+
" create the swap file again, but change the host name so that it won't be
428+
" deleted
429+
autocmd! SwapExists
430+
augroup test_swap_recover_ext
431+
autocmd!
432+
autocmd SwapExists * let v:swapchoice = 'e'
433+
augroup END
434+
435+
" change the host name
436+
let swapfile_bytes[28 + 40] = 0x89
437+
call writefile(swapfile_bytes, swapfile_name)
438+
edit Xtest.scr
439+
call assert_equal(1, filereadable(swapfile_name))
440+
" will use another same swap file name
441+
call assert_notequal(swapfile_name, swapname('%'))
442+
bwipe!
443+
444+
call delete('Xtest.scr')
445+
call delete(swapfile_name)
446+
augroup test_swap_recover_ext
447+
autocmd!
448+
augroup END
449+
augroup! test_swap_recover_ext
450+
endfunc
451+
406452
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
1970,
753755
/**/
754756
1969,
755757
/**/

0 commit comments

Comments
 (0)