From abe1dd308e1f37bb9b06a85da82e066135b86ff9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:13:13 +0800 Subject: vim-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 vim/vim#7273) https://github.com/vim/vim/commit/f883508e36c209d60388b944e04e22a3fcf603cf --- src/nvim/memline.c | 26 +++++++++++++++++++++--- src/nvim/testdir/test_swap.vim | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 1f601f0668..8b5aef3be1 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1138,7 +1138,14 @@ void ml_recover(bool checkext) } else { msg(_("Recovery completed. Buffer contents equals file contents.")); } - msg_puts(_("\nYou may want to delete the .swp file now.\n\n")); + msg_puts(_("\nYou may want to delete the .swp file now.")); + if (os_proc_running((int)char_to_long(b0p->b0_pid))) { + // Warn there could be an active Vim on the same file, the user may + // want to kill it. + msg_puts(_("\nNote: process STILL RUNNING: ")); + msg_outnum(char_to_long(b0p->b0_pid)); + } + msg_puts("\n\n"); cmdline_row = msg_row; } redraw_curbuf_later(UPD_NOT_VALID); @@ -1533,14 +1540,27 @@ static bool swapfile_unchanged(char *fname) ret = false; } + // Host name must be known and must equal the current host name, otherwise + // comparing pid is meaningless. + if (*(b0.b0_hname) == NUL) { + ret = false; + } else { + char hostname[B0_HNAME_SIZE]; + os_get_hostname(hostname, B0_HNAME_SIZE); + hostname[B0_HNAME_SIZE - 1] = NUL; + if (STRICMP(b0.b0_hname, hostname) != 0) { + ret = false; + } + } + // process must be known and not running. long pid = char_to_long(b0.b0_pid); if (pid == 0L || os_proc_running((int)pid)) { ret = false; } - // TODO(bram): Should we check if the swap file was created on the current - // system? And the current user? + // We do not check the user, it should be irrelevant for whether the swap + // file is still useful. close(fd); return ret; diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 34d1d585ce..7941f78ced 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -421,6 +421,52 @@ func Test_swap_symlink() call delete('Xswapdir', 'rf') endfunc +func Test_swap_auto_delete() + " Create a valid swapfile by editing a file with a special extension. + split Xtest.scr + call setline(1, ['one', 'two', 'three']) + write " file is written, not modified + write " write again to make sure the swapfile is created + " read the swapfile as a Blob + let swapfile_name = swapname('%') + let swapfile_bytes = readfile(swapfile_name, 'B') + + " Forget about the file, recreate the swap file, then edit it again. The + " swap file should be automatically deleted. + bwipe! + " change the process ID to avoid the "still running" warning + let swapfile_bytes[24] = 0x99 + call writefile(swapfile_bytes, swapfile_name) + edit Xtest.scr + " will end up using the same swap file after deleting the existing one + call assert_equal(swapfile_name, swapname('%')) + bwipe! + + " create the swap file again, but change the host name so that it won't be + " deleted + autocmd! SwapExists + augroup test_swap_recover_ext + autocmd! + autocmd SwapExists * let v:swapchoice = 'e' + augroup END + + " change the host name + let swapfile_bytes[28 + 40] = 0x89 + call writefile(swapfile_bytes, swapfile_name) + edit Xtest.scr + call assert_equal(1, filereadable(swapfile_name)) + " will use another same swap file name + call assert_notequal(swapfile_name, swapname('%')) + bwipe! + + call delete('Xtest.scr') + call delete(swapfile_name) + augroup test_swap_recover_ext + autocmd! + augroup END + augroup! test_swap_recover_ext +endfunc + func Test_no_swap_file() call assert_equal("\nNo swap file", execute('swapname')) endfunc -- cgit From f97d88a58a2d3e010d9de75815fb89b9cc7b8a3c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:20:54 +0800 Subject: vim-patch:8.2.2016: swap file test is a little flaky Problem: Swap file test is a little flaky. Solution: Don't set a byte to a fixed value, increment it. https://github.com/vim/vim/commit/c6ca9f3a29bfd6f5269749036f79f63ce6289692 Co-authored-by: Bram Moolenaar --- src/nvim/testdir/test_swap.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 7941f78ced..4ab2e0df10 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -435,7 +435,7 @@ func Test_swap_auto_delete() " swap file should be automatically deleted. bwipe! " change the process ID to avoid the "still running" warning - let swapfile_bytes[24] = 0x99 + let swapfile_bytes[24] = swapfile_bytes[24] + 1 call writefile(swapfile_bytes, swapfile_name) edit Xtest.scr " will end up using the same swap file after deleting the existing one @@ -451,7 +451,7 @@ func Test_swap_auto_delete() augroup END " change the host name - let swapfile_bytes[28 + 40] = 0x89 + let swapfile_bytes[28 + 40] = swapfile_bytes[28 + 40] + 2 call writefile(swapfile_bytes, swapfile_name) edit Xtest.scr call assert_equal(1, filereadable(swapfile_name)) -- cgit From 1b95eaf84bdc5189b435fe98b365b5f120d99c2d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:23:38 +0800 Subject: vim-patch:8.2.2019: swap file test fails on MS-Windows Problem: Swap file test fails on MS-Windows. Solution: Add four to the process ID. (Ken Takata, closes vim/vim#7333) https://github.com/vim/vim/commit/80d868ec25094615f2531a1e01ed1e729366c3bc --- src/nvim/testdir/test_swap.vim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 4ab2e0df10..22a4a17c39 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -434,8 +434,9 @@ func Test_swap_auto_delete() " Forget about the file, recreate the swap file, then edit it again. The " swap file should be automatically deleted. bwipe! - " change the process ID to avoid the "still running" warning - let swapfile_bytes[24] = swapfile_bytes[24] + 1 + " Change the process ID to avoid the "still running" warning. Must add four + " for MS-Windows to see it as a different one. + let swapfile_bytes[24] = swapfile_bytes[24] + 4 call writefile(swapfile_bytes, swapfile_name) edit Xtest.scr " will end up using the same swap file after deleting the existing one -- cgit From 8cf38c2fd9408f7de9d9ff1e4db6fc90aba554cf Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:21:53 +0800 Subject: vim-patch:8.2.2026: Coverity warns for possibly using not NUL terminated string Problem: Coverity warns for possibly using not NUL terminated string. Solution: Put a NUL in b0_hname just in case. https://github.com/vim/vim/commit/e79cdb69a4905ccf766494265d4c6f8701d10c39 Co-authored-by: Bram Moolenaar --- src/nvim/memline.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 8b5aef3be1..02a7e1f697 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1548,6 +1548,7 @@ static bool swapfile_unchanged(char *fname) char hostname[B0_HNAME_SIZE]; os_get_hostname(hostname, B0_HNAME_SIZE); hostname[B0_HNAME_SIZE - 1] = NUL; + b0.b0_hname[B0_HNAME_SIZE - 1] = NUL; // in case of corruption if (STRICMP(b0.b0_hname, hostname) != 0) { ret = false; } -- cgit From 1fe526184f155bbda5d0d3037d683fd935b57c35 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:24:50 +0800 Subject: vim-patch:8.2.2044: MS-Windows: swap file test sometimes fails Problem: MS-Windows: swap file test sometimes fails. Solution: Use a more reliable way to change the process ID. When "timeout" fails use "ping" to wait up to ten minutes. (Ken Takata, closes vim/vim#7365) https://github.com/vim/vim/commit/5ee0981fb5259f94900ab25207caddf1fa61010d --- src/nvim/testdir/test_swap.vim | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 22a4a17c39..958e4f814f 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -421,6 +421,39 @@ func Test_swap_symlink() call delete('Xswapdir', 'rf') endfunc +func s:get_unused_pid(base) + if has('job') + " Execute 'echo' as a temporary job, and return its pid as an unused pid. + if has('win32') + let cmd = 'cmd /c echo' + else + let cmd = 'echo' + endif + let j = job_start(cmd) + while job_status(j) ==# 'run' + sleep 10m + endwhile + if job_status(j) ==# 'dead' + return job_info(j).process + endif + endif + " Must add four for MS-Windows to see it as a different one. + return a:base + 4 +endfunc + +func s:blob_to_pid(b) + return a:b[3] * 16777216 + a:b[2] * 65536 + a:b[1] * 256 + a:b[0] +endfunc + +func s:pid_to_blob(i) + let b = 0z + let b[0] = and(a:i, 0xff) + let b[1] = and(a:i / 256, 0xff) + let b[2] = and(a:i / 65536, 0xff) + let b[3] = and(a:i / 16777216, 0xff) + return b +endfunc + func Test_swap_auto_delete() " Create a valid swapfile by editing a file with a special extension. split Xtest.scr @@ -434,9 +467,9 @@ func Test_swap_auto_delete() " Forget about the file, recreate the swap file, then edit it again. The " swap file should be automatically deleted. bwipe! - " Change the process ID to avoid the "still running" warning. Must add four - " for MS-Windows to see it as a different one. - let swapfile_bytes[24] = swapfile_bytes[24] + 4 + " Change the process ID to avoid the "still running" warning. + let swapfile_bytes[24:27] = s:pid_to_blob(s:get_unused_pid( + \ s:blob_to_pid(swapfile_bytes[24:27]))) call writefile(swapfile_bytes, swapfile_name) edit Xtest.scr " will end up using the same swap file after deleting the existing one -- cgit From a8489308ab00f51bff197f29e76276b16ad0d985 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:41:07 +0800 Subject: vim-patch:8.2.3041: detecting if the process of a swap file is running fails Problem: Detecting if the process of a swap file is running fails if the process is owned by another user. Solution: Check for the ESRCH error. (closes vim/vim#8436) https://github.com/vim/vim/commit/44dea9da4b2a21dd1e03f2bd94b4f2679d4613e5 Co-authored-by: Bram Moolenaar --- src/nvim/os/process.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c index d9273e69da..f4d95e141b 100644 --- a/src/nvim/os/process.c +++ b/src/nvim/os/process.c @@ -264,5 +264,16 @@ Dictionary os_proc_info(int pid) /// Return true if process `pid` is running. bool os_proc_running(int pid) { - return uv_kill(pid, 0) == 0; + int err = uv_kill(pid, 0); + // If there is no error the process must be running. + if (err == 0) { + return true; + } + // If the error is ESRCH then the process is not running. + if (err == UV_ESRCH) { + return false; + } + // If the process is running and owned by another user we get EPERM. With + // other errors the process might be running, assuming it is then. + return true; } -- cgit From 78998bc6c6dcd6945e39f427520f6851707eb344 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 17 Nov 2022 18:44:13 +0800 Subject: vim-patch:8.2.3042: swap file test fails Problem: Swap file test fails. Solution: Check for a very high process ID instead of one, which should be running. https://github.com/vim/vim/commit/6738fd2000f0bea4d40f4a8651e0e1f4b0503bb3 Co-authored-by: Bram Moolenaar --- src/nvim/testdir/test_swap.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 958e4f814f..284579b084 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -203,8 +203,8 @@ func Test_swapfile_delete() " This test won't work as root because root can successfully run kill(1, 0) if !IsRoot() " Write the swapfile with a modified PID, now it will be automatically - " deleted. Process one should never be Vim. - let swapfile_bytes[24:27] = 0z01000000 + " deleted. Process 0x3fffffff most likely does not exist. + let swapfile_bytes[24:27] = 0zffffff3f call writefile(swapfile_bytes, swapfile_name) let s:swapname = '' split XswapfileText -- cgit