Patch 8.2.3941

8 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 29, 2021, 2:42:22 PM12/29/21
to vim...@googlegroups.com

Patch 8.2.3941
Problem: SIGTSTP is not handled.
Solution: Handle SIGTSTP like pressing CTRL-Z. (closes #9422)
Files: runtime/doc/autocmd.txt, src/ex_docmd.c, src/os_unix.c,
src/proto/ex_docmd.pro, src/testdir/test_signals.vim


*** ../vim-8.2.3940/runtime/doc/autocmd.txt 2021-11-13 12:38:45.534835910 +0000
--- runtime/doc/autocmd.txt 2021-12-29 19:38:03.626742672 +0000
***************
*** 1275,1282 ****
:autocmd VimResume * checktime
< *VimSuspend*
VimSuspend When the Vim instance is suspended. Only when
! CTRL-Z was typed inside Vim, not when the
! SIGSTOP or SIGTSTP signal was sent to Vim.
*WinClosed*
WinClosed After closing a window. The pattern is
matched against the |window-ID|. Both
--- 1279,1286 ----
:autocmd VimResume * checktime
< *VimSuspend*
VimSuspend When the Vim instance is suspended. Only when
! CTRL-Z was typed inside Vim, or when the SIGTSTP
! signal was sent to Vim, but not for SIGSTOP.
*WinClosed*
WinClosed After closing a window. The pattern is
matched against the |window-ID|. Both
*** ../vim-8.2.3940/src/ex_docmd.c 2021-12-29 14:39:04.634256171 +0000
--- src/ex_docmd.c 2021-12-29 19:38:03.626742672 +0000
***************
*** 109,115 ****
# define ex_pedit ex_ni
#endif
static void ex_hide(exarg_T *eap);
- static void ex_stop(exarg_T *eap);
static void ex_exit(exarg_T *eap);
static void ex_print(exarg_T *eap);
#ifdef FEAT_BYTEOFF
--- 109,114 ----
***************
*** 6200,6206 ****
/*
* ":stop" and ":suspend": Suspend Vim.
*/
! static void
ex_stop(exarg_T *eap)
{
/*
--- 6199,6205 ----
/*
* ":stop" and ":suspend": Suspend Vim.
*/
! void
ex_stop(exarg_T *eap)
{
/*
*** ../vim-8.2.3940/src/os_unix.c 2021-12-27 17:21:38.016449116 +0000
--- src/os_unix.c 2021-12-29 19:38:03.626742672 +0000
***************
*** 157,162 ****
--- 157,167 ----
#if defined(SIGWINCH)
static RETSIGTYPE sig_winch SIGPROTOARG;
#endif
+ #if defined(SIGTSTP)
+ static RETSIGTYPE sig_tstp SIGPROTOARG;
+ // volatile because it is used in signal handler sig_tstp() and sigcont_handler().
+ static volatile sig_atomic_t in_mch_suspend = FALSE;
+ #endif
#if defined(SIGINT)
static RETSIGTYPE catch_sigint SIGPROTOARG;
#endif
***************
*** 197,202 ****
--- 202,209 ----

// volatile because it is used in signal handler sig_winch().
static volatile sig_atomic_t do_resize = FALSE;
+ // volatile because it is used in signal handler sig_tstp().
+ static volatile sig_atomic_t got_tstp = FALSE;
static char_u *extra_shell_arg = NULL;
static int show_shell_mess = TRUE;
// volatile because it is used in signal handler deathtrap().
***************
*** 851,856 ****
--- 858,881 ----
}
#endif

+ #if defined(SIGTSTP)
+ static RETSIGTYPE
+ sig_tstp SIGDEFARG(sigarg)
+ {
+ // Second time we get called we actually need to suspend
+ if (in_mch_suspend)
+ {
+ signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : SIG_DFL);
+ raise(sigarg);
+ }
+
+ // this is not required on all systems, but it doesn't hurt anybody
+ signal(SIGTSTP, (RETSIGTYPE (*)())sig_tstp);
+ got_tstp = TRUE;
+ SIGRETURN;
+ }
+ #endif
+
#if defined(SIGINT)
static RETSIGTYPE
catch_sigint SIGDEFARG(sigarg)
***************
*** 1158,1164 ****

#if defined(SIGCONT)
static RETSIGTYPE sigcont_handler SIGPROTOARG;
- static volatile sig_atomic_t in_mch_suspend = FALSE;

/*
* With multi-threading, suspending might not work immediately. Catch the
--- 1183,1188 ----
***************
*** 1353,1359 ****

#ifdef SIGTSTP
// See mch_init() for the conditions under which we ignore SIGTSTP.
! signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : SIG_DFL);
#endif
#if defined(SIGCONT)
signal(SIGCONT, sigcont_handler);
--- 1377,1383 ----

#ifdef SIGTSTP
// See mch_init() for the conditions under which we ignore SIGTSTP.
! signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : (RETSIGTYPE (*)())sig_tstp);
#endif
#if defined(SIGCONT)
signal(SIGCONT, sigcont_handler);
***************
*** 6386,6391 ****
--- 6410,6424 ----
# ifdef EINTR
if (ret == -1 && errno == EINTR)
{
+ // Check whether the EINTR is caused by SIGTSTP
+ if (got_tstp && !in_mch_suspend)
+ {
+ exarg_T ea;
+ ea.forceit = TRUE;
+ ex_stop(&ea);
+ got_tstp = FALSE;
+ }
+
// Check whether window has been resized, EINTR may be caused by
// SIGWINCH.
if (do_resize)
***************
*** 7176,7182 ****
// we are going to suspend or starting an external process
// so we shouldn't have problem with this
# ifdef SIGTSTP
! signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
# endif
return 1; // succeed
}
--- 7209,7215 ----
// we are going to suspend or starting an external process
// so we shouldn't have problem with this
# ifdef SIGTSTP
! signal(SIGTSTP, restricted ? SIG_IGN : (RETSIGTYPE (*)())sig_tstp);
# endif
return 1; // succeed
}
*** ../vim-8.2.3940/src/proto/ex_docmd.pro 2021-12-01 15:22:53.106902067 +0000
--- src/proto/ex_docmd.pro 2021-12-29 19:38:03.630742665 +0000
***************
*** 40,45 ****
--- 40,46 ----
void ex_quit(exarg_T *eap);
void tabpage_close(int forceit);
void tabpage_close_other(tabpage_T *tp, int forceit);
+ void ex_stop(exarg_T *eap);
void handle_drop(int filec, char_u **filev, int split, void (*callback)(void *), void *cookie);
void handle_any_postponed_drop(void);
void ex_splitview(exarg_T *eap);
*** ../vim-8.2.3940/src/testdir/test_signals.vim 2021-01-02 15:53:08.294010035 +0000
--- src/testdir/test_signals.vim 2021-12-29 19:38:03.630742665 +0000
***************
*** 105,110 ****
--- 105,162 ----
call StopVimInTerminal(buf)
endfunc

+ " Test signal TSTP. Handler sets got_tstp.
+ func Test_signal_TSTP()
+ CheckRunVimInTerminal
+ if !HasSignal('TSTP')
+ throw 'Skipped: TSTP signal not supported'
+ endif
+
+ " Skip the test when running with valgrind as signal TSTP is not received
+ " somehow by Vim when running with valgrind.
+ let cmd = GetVimCommand()
+ if cmd =~ 'valgrind'
+ throw 'Skipped: cannot test signal TSTP with valgrind'
+ endif
+
+ " If test fails once, it can leave temporary files and trying to rerun
+ " the test would then fail again if they are not deleted first.
+ call delete('.Xsig_TERM.swp')
+ call delete('XsetupAucmd')
+ call delete('XautoOut')
+ let lines =<< trim END
+ au VimSuspend * call writefile(["VimSuspend triggered"], "XautoOut", "as")
+ au VimResume * call writefile(["VimResume triggered"], "XautoOut", "as")
+ END
+ call writefile(lines, 'XsetupAucmd')
+
+ let buf = RunVimInTerminal('-S XsetupAucmd Xsig_TERM', {'rows': 6})
+ let pid_vim = term_getjob(buf)->job_info().process
+
+ call term_sendkeys(buf, ":call setline(1, 'foo')\n")
+ call WaitForAssert({-> assert_equal('foo', term_getline(buf, 1))})
+
+ call assert_false(filereadable('Xsig_TERM'))
+
+ " After TSTP the file is not saved (same function as ^Z)
+ exe 'silent !kill -s TSTP ' .. pid_vim
+ call WaitForAssert({-> assert_true(filereadable('.Xsig_TERM.swp'))})
+
+ " We resume after the suspend
+ exe 'silent !kill -s CONT ' .. pid_vim
+ exe 'silent !sleep 0.006'
+
+ call StopVimInTerminal(buf)
+
+ let result = readfile('XautoOut')
+ call assert_equal(["VimSuspend triggered", "VimResume triggered"], result)
+
+ %bwipe!
+ call delete('.Xsig_TERM.swp')
+ call delete('XsetupAucmd')
+ call delete('XautoOut')
+ endfunc
+
" Test a deadly signal.
"
" There are several deadly signals: SISEGV, SIBUS, SIGTERM...
*** ../vim-8.2.3940/src/version.c 2021-12-29 19:22:19.136139687 +0000
--- src/version.c 2021-12-29 19:39:27.458612212 +0000
***************
*** 751,752 ****
--- 751,754 ----
{ /* Add new patch number below this line */
+ /**/
+ 3941,
/**/

--
hundred-and-one symptoms of being an internet addict:
146. You experience ACTUAL physical withdrawal symptoms when away
from your 'puter and the net.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages