diff options
author | dbivolaru <dbivolaru@jacobs-alumni.de> | 2021-12-29 19:41:47 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-12-29 19:41:47 +0000 |
commit | ab16ad33ba10dd12ff6660fa57b88f1a30ddd8ba (patch) | |
tree | 85f14e9648cb4131f50599c792afb620e6ef43b6 /src/os_unix.c | |
parent | 94fb8274ca8c93a10102d41c8bcc848f75cb7334 (diff) | |
download | vim-git-ab16ad33ba10dd12ff6660fa57b88f1a30ddd8ba.tar.gz |
patch 8.2.3941: SIGTSTP is not handledv8.2.3941
Problem: SIGTSTP is not handled.
Solution: Handle SIGTSTP like pressing CTRL-Z. (closes #9422)
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 77f35db95..e24c09f4a 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -157,6 +157,11 @@ static void handle_resize(void); #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,6 +202,8 @@ static int save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***fil // 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,6 +858,24 @@ sig_winch SIGDEFARG(sigarg) } #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,7 +1183,6 @@ after_sigcont(void) #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 @@ -1353,7 +1377,7 @@ set_signals(void) #ifdef SIGTSTP // See mch_init() for the conditions under which we ignore SIGTSTP. - signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : SIG_DFL); + signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : (RETSIGTYPE (*)())sig_tstp); #endif #if defined(SIGCONT) signal(SIGCONT, sigcont_handler); @@ -6386,6 +6410,15 @@ select_eintr: # 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,7 +7209,7 @@ gpm_open(void) // 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); + signal(SIGTSTP, restricted ? SIG_IGN : (RETSIGTYPE (*)())sig_tstp); # endif return 1; // succeed } |