diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-11-17 19:57:16 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-11-17 20:34:33 +0800 |
commit | ec5c1c35c2b2477d79c20594a6fe64fe1d18ed36 (patch) | |
tree | 2f3e5845d805f006ab914f86f22b3c5b9ce6817b | |
parent | 0a4c5cd2b2b7d98dc0930c474a347dee9f09bfad (diff) | |
download | rneovim-ec5c1c35c2b2477d79c20594a6fe64fe1d18ed36.tar.gz rneovim-ec5c1c35c2b2477d79c20594a6fe64fe1d18ed36.tar.bz2 rneovim-ec5c1c35c2b2477d79c20594a6fe64fe1d18ed36.zip |
vim-patch:8.2.2586: process id may be invalid
Problem: Process id may be invalid.
Solution: Use sysinfo.uptime to check for recent reboot. (suggested by Hugo
van der Sanden, closes vim/vim#7947)
https://github.com/vim/vim/commit/f52f0606ed9ea19bcfc3a8343af9958f2d99eaf7
test_override() is N/A.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r-- | src/nvim/memline.c | 26 | ||||
-rw-r--r-- | src/nvim/testdir/test_recover.vim | 79 |
2 files changed, 91 insertions, 14 deletions
diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 02a7e1f697..955074e1f2 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -72,7 +72,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" -#include "nvim/os/fs_defs.h" +#include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/process.h" @@ -698,6 +698,23 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf) } } +/// Return true if the process with number "b0p->b0_pid" is still running. +/// "swap_fname" is the name of the swap file, if it's from before a reboot then +/// the result is false; +static bool swapfile_process_running(const ZERO_BL *b0p, const char *swap_fname) +{ + FileInfo st; + double uptime; + // If the system rebooted after when the swap file was written then the + // process can't be running now. + if (os_fileinfo(swap_fname, &st) + && uv_uptime(&uptime) == 0 + && (Timestamp)st.stat.st_mtim.tv_sec < os_time() - (Timestamp)uptime) { + return false; + } + return os_proc_running((int)char_to_long(b0p->b0_pid)); +} + /// Try to recover curbuf from the .swp file. /// /// @param checkext if true, check the extension and detect whether it is a @@ -1139,7 +1156,7 @@ void ml_recover(bool checkext) msg(_("Recovery completed. Buffer contents equals file contents.")); } msg_puts(_("\nYou may want to delete the .swp file now.")); - if (os_proc_running((int)char_to_long(b0p->b0_pid))) { + if (swapfile_process_running(b0p, fname_used)) { // Warn there could be an active Vim on the same file, the user may // want to kill it. msg_puts(_("\nNote: process STILL RUNNING: ")); @@ -1485,7 +1502,7 @@ static time_t swapfile_info(char_u *fname) if (char_to_long(b0.b0_pid) != 0L) { msg_puts(_("\n process ID: ")); msg_outnum(char_to_long(b0.b0_pid)); - if (os_proc_running((int)char_to_long(b0.b0_pid))) { + if (swapfile_process_running(&b0, (const char *)fname)) { msg_puts(_(" (STILL RUNNING)")); process_still_running = true; } @@ -1555,8 +1572,7 @@ static bool swapfile_unchanged(char *fname) } // process must be known and not running. - long pid = char_to_long(b0.b0_pid); - if (pid == 0L || os_proc_running((int)pid)) { + if (char_to_long(b0.b0_pid) == 0L || swapfile_process_running(&b0, fname)) { ret = false; } diff --git a/src/nvim/testdir/test_recover.vim b/src/nvim/testdir/test_recover.vim index fc073cacd2..c3bdde0d71 100644 --- a/src/nvim/testdir/test_recover.vim +++ b/src/nvim/testdir/test_recover.vim @@ -1,5 +1,7 @@ " Test :recover +source check.vim + func Test_recover_root_dir() " This used to access invalid memory. split Xtest @@ -23,6 +25,21 @@ func Test_recover_root_dir() set dir& endfunc +" Make a copy of the current swap file to "Xswap". +" Return the name of the swap file. +func CopySwapfile() + preserve + " get the name of the swap file + let swname = split(execute("swapname"))[0] + let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '') + " make a copy of the swap file in Xswap + set binary + exe 'sp ' . swname + w! Xswap + set nobinary + return swname +endfunc + " Inserts 10000 lines with text to fill the swap file with two levels of pointer " blocks. Then recovers from the swap file and checks all text is restored. " @@ -40,15 +57,9 @@ func Test_swap_file() let i += 1 endwhile $delete - preserve - " get the name of the swap file - let swname = split(execute("swapname"))[0] - let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '') - " make a copy of the swap file in Xswap - set binary - exe 'sp ' . swname - w! Xswap - set nobinary + + let swname = CopySwapfile() + new only! bwipe! Xtest @@ -69,3 +80,53 @@ func Test_swap_file() set undolevels& enew! | only endfunc + +func Test_nocatch_process_still_running() + " assume Unix means sysinfo.uptime can be used + CheckUnix + CheckNotGui + + " don't intercept existing swap file here + au! SwapExists + + " Edit a file and grab its swapfile. + edit Xswaptest + call setline(1, ['a', 'b', 'c']) + let swname = CopySwapfile() + + " Forget we edited this file + new + only! + bwipe! Xswaptest + + call rename('Xswap', swname) + call feedkeys('e', 'tL') + redir => editOutput + edit Xswaptest + redir END + call assert_match('E325: ATTENTION', editOutput) + call assert_match('file name: .*Xswaptest', editOutput) + call assert_match('process ID: \d* (STILL RUNNING)', editOutput) + + " Forget we edited this file + new + only! + bwipe! Xswaptest + + " pretend we rebooted + call test_override("uptime", 0) + sleep 1 + + call rename('Xswap', swname) + call feedkeys('e', 'tL') + redir => editOutput + edit Xswaptest + redir END + call assert_match('E325: ATTENTION', editOutput) + call assert_notmatch('(STILL RUNNING)', editOutput) + + call test_override("ALL", 0) + call delete(swname) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab |