# HG changeset patch # User Bram Moolenaar # Date 1591815604 -7200 # Node ID e76b83c07bd8e77cae5ea28565946d55beff19cc # Parent a3f74832de9b19fb1446ce7ce453f5ce0974c9bc patch 8.2.0952: no simple way to interrupt Vim Commit: https://github.com/vim/vim/commit/be5ee8686a50acf07b823bd293f9c765e533d213 Author: Bram Moolenaar Date: Wed Jun 10 20:56:58 2020 +0200 patch 8.2.0952: no simple way to interrupt Vim Problem: No simple way to interrupt Vim. Solution: Add the SigUSR1 autocommand, triggered by SIGUSR1. (Jacob Hayes, closes #1718) diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -380,6 +380,7 @@ Name triggered by ~ info |User| to be used in combination with ":doautocmd" +|SigUSR1| after the SIGUSR1 signal has been detected The alphabetical list of autocommand events: *autocmd-events-abc* @@ -1158,6 +1159,7 @@ TextYankPost After text has been yanke It is not allowed to change the buffer text, see |textlock|. {only when compiled with the +eval feature} + *User* User Never executed automatically. To be used for autocommands that are only executed with @@ -1166,6 +1168,15 @@ User Never executed automatically. T used while there are no matching autocommands, you will get an error. If you don't want that, define a dummy autocommand yourself. + + *SigUSR1* +SigUSR1 After the SIGUSR1 signal has been detected. + Could be used if other ways of notifying Vim + are not feasible. E.g. to check for the + result of a build that takes a long time, or + when a motion sensor is triggered. + {only on Unix} + *UserGettingBored* UserGettingBored When the user presses the same key 42 times. Just kidding! :-) diff --git a/src/autocmd.c b/src/autocmd.c --- a/src/autocmd.c +++ b/src/autocmd.c @@ -161,6 +161,7 @@ static struct event_name {"SessionLoadPost", EVENT_SESSIONLOADPOST}, {"ShellCmdPost", EVENT_SHELLCMDPOST}, {"ShellFilterPost", EVENT_SHELLFILTERPOST}, + {"SigUSR1", EVENT_SIGUSR1}, {"SourceCmd", EVENT_SOURCECMD}, {"SourcePre", EVENT_SOURCEPRE}, {"SourcePost", EVENT_SOURCEPOST}, diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -2204,6 +2204,13 @@ parse_queued_messages(void) if (has_sound_callback_in_queue()) invoke_sound_callback(); # endif +#ifdef SIGUSR1 + if (got_sigusr1) + { + apply_autocmds(EVENT_SIGUSR1, NULL, NULL, FALSE, curbuf); + got_sigusr1 = FALSE; + } +#endif break; } diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -1171,9 +1171,14 @@ EXTERN int curscript INIT(= 0); // i EXTERN FILE *scriptout INIT(= NULL); // stream to write script to EXTERN int read_cmd_fd INIT(= 0); // fd to read commands from -// volatile because it is used in signal handler catch_sigint(). -EXTERN volatile sig_atomic_t got_int INIT(= FALSE); // set to TRUE when interrupt - // signal occurred +// Set to TRUE when an interrupt signal occurred. +// Volatile because it is used in signal handler catch_sigint(). +EXTERN volatile sig_atomic_t got_int INIT(= FALSE); + +// Set to TRUE when SIGUSR1 signal was detected. +// Volatile because it is used in signal handler catch_sigint(). +EXTERN volatile sig_atomic_t got_sigusr1 INIT(= FALSE); + #ifdef USE_TERM_CONSOLE EXTERN int term_console INIT(= FALSE); // set to TRUE when console used #endif diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -164,6 +164,9 @@ static RETSIGTYPE sig_winch SIGPROTOARG; #if defined(SIGINT) static RETSIGTYPE catch_sigint SIGPROTOARG; #endif +#if defined(SIGUSR1) +static RETSIGTYPE catch_sigusr1 SIGPROTOARG; +#endif #if defined(SIGPWR) static RETSIGTYPE catch_sigpwr SIGPROTOARG; #endif @@ -297,7 +300,7 @@ static struct signalinfo {SIGXFSZ, "XFSZ", TRUE}, #endif #ifdef SIGUSR1 - {SIGUSR1, "USR1", TRUE}, + {SIGUSR1, "USR1", FALSE}, #endif #if defined(SIGUSR2) && !defined(FEAT_SYSMOUSE) // Used for sysmouse handling @@ -837,6 +840,17 @@ catch_sigint SIGDEFARG(sigarg) } #endif +#if defined(SIGUSR1) + static RETSIGTYPE +catch_sigusr1 SIGDEFARG(sigarg) +{ + // this is not required on all systems, but it doesn't hurt anybody + signal(SIGUSR1, (RETSIGTYPE (*)())catch_sigusr1); + got_sigusr1 = TRUE; + SIGRETURN; +} +#endif + #if defined(SIGPWR) static RETSIGTYPE catch_sigpwr SIGDEFARG(sigarg) @@ -1323,10 +1337,10 @@ set_signals(void) #if defined(SIGCONT) signal(SIGCONT, sigcont_handler); #endif +#ifdef SIGPIPE /* * We want to ignore breaking of PIPEs. */ -#ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif @@ -1334,6 +1348,13 @@ set_signals(void) catch_int_signal(); #endif +#ifdef SIGUSR1 + /* + * Call user's handler on SIGUSR1 + */ + signal(SIGUSR1, (RETSIGTYPE (*)())catch_sigusr1); +#endif + /* * Ignore alarm signals (Perl's alarm() generates it). */ @@ -1341,11 +1362,11 @@ set_signals(void) signal(SIGALRM, SIG_IGN); #endif +#ifdef SIGPWR /* * Catch SIGPWR (power failure?) to preserve the swap files, so that no * work will be lost. */ -#ifdef SIGPWR signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr); #endif diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -2509,4 +2509,17 @@ func Test_autocmd_deep_nesting() autocmd! BufEnter Xfile endfunc +" Tests for SigUSR1 autocmd event, which is only available on posix systems. +func Test_autocmd_sigusr1() + CheckUnix + + let g:sigusr1_passed = 0 + au SigUSR1 * let g:sigusr1_passed = 1 + call system('/bin/kill -s usr1 ' . getpid()) + call WaitForAssert({-> assert_true(g:sigusr1_passed)}) + + au! SigUSR1 + unlet g:sigusr1_passed +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 952, +/**/ 951, /**/ 950, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -1316,6 +1316,7 @@ enum auto_event EVENT_SESSIONLOADPOST, // after loading a session file EVENT_SHELLCMDPOST, // after ":!cmd" EVENT_SHELLFILTERPOST, // after ":1,2!cmd", ":w !cmd", ":r !cmd". + EVENT_SIGUSR1, // after the SIGUSR1 signal EVENT_SOURCECMD, // sourcing a Vim script using command EVENT_SOURCEPRE, // before sourcing a Vim script EVENT_SOURCEPOST, // after sourcing a Vim script