0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

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)
This commit is contained in:
Bram Moolenaar
2020-06-10 20:56:58 +02:00
parent 6ba24d8763
commit be5ee8686a
8 changed files with 67 additions and 6 deletions

View File

@@ -380,6 +380,7 @@ Name triggered by ~
info info
|User| to be used in combination with ":doautocmd" |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* The alphabetical list of autocommand events: *autocmd-events-abc*
@@ -1158,6 +1159,7 @@ TextYankPost After text has been yanked or deleted in the
It is not allowed to change the buffer text, It is not allowed to change the buffer text,
see |textlock|. see |textlock|.
{only when compiled with the +eval feature} {only when compiled with the +eval feature}
*User* *User*
User Never executed automatically. To be used for User Never executed automatically. To be used for
autocommands that are only executed with autocommands that are only executed with
@@ -1166,6 +1168,15 @@ User Never executed automatically. To be used for
used while there are no matching autocommands, used while there are no matching autocommands,
you will get an error. If you don't want you will get an error. If you don't want
that, define a dummy autocommand yourself. 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*
UserGettingBored When the user presses the same key 42 times. UserGettingBored When the user presses the same key 42 times.
Just kidding! :-) Just kidding! :-)

View File

@@ -161,6 +161,7 @@ static struct event_name
{"SessionLoadPost", EVENT_SESSIONLOADPOST}, {"SessionLoadPost", EVENT_SESSIONLOADPOST},
{"ShellCmdPost", EVENT_SHELLCMDPOST}, {"ShellCmdPost", EVENT_SHELLCMDPOST},
{"ShellFilterPost", EVENT_SHELLFILTERPOST}, {"ShellFilterPost", EVENT_SHELLFILTERPOST},
{"SigUSR1", EVENT_SIGUSR1},
{"SourceCmd", EVENT_SOURCECMD}, {"SourceCmd", EVENT_SOURCECMD},
{"SourcePre", EVENT_SOURCEPRE}, {"SourcePre", EVENT_SOURCEPRE},
{"SourcePost", EVENT_SOURCEPOST}, {"SourcePost", EVENT_SOURCEPOST},

View File

@@ -2203,6 +2203,13 @@ parse_queued_messages(void)
# ifdef FEAT_SOUND_CANBERRA # ifdef FEAT_SOUND_CANBERRA
if (has_sound_callback_in_queue()) if (has_sound_callback_in_queue())
invoke_sound_callback(); invoke_sound_callback();
# endif
#ifdef SIGUSR1
if (got_sigusr1)
{
apply_autocmds(EVENT_SIGUSR1, NULL, NULL, FALSE, curbuf);
got_sigusr1 = FALSE;
}
#endif #endif
break; break;
} }

View File

@@ -1171,9 +1171,14 @@ EXTERN int curscript INIT(= 0); // index in scriptin[]
EXTERN FILE *scriptout INIT(= NULL); // stream to write script to EXTERN FILE *scriptout INIT(= NULL); // stream to write script to
EXTERN int read_cmd_fd INIT(= 0); // fd to read commands from EXTERN int read_cmd_fd INIT(= 0); // fd to read commands from
// volatile because it is used in signal handler catch_sigint(). // Set to TRUE when an interrupt signal occurred.
EXTERN volatile sig_atomic_t got_int INIT(= FALSE); // set to TRUE when interrupt // Volatile because it is used in signal handler catch_sigint().
// signal occurred 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 #ifdef USE_TERM_CONSOLE
EXTERN int term_console INIT(= FALSE); // set to TRUE when console used EXTERN int term_console INIT(= FALSE); // set to TRUE when console used
#endif #endif

View File

@@ -164,6 +164,9 @@ static RETSIGTYPE sig_winch SIGPROTOARG;
#if defined(SIGINT) #if defined(SIGINT)
static RETSIGTYPE catch_sigint SIGPROTOARG; static RETSIGTYPE catch_sigint SIGPROTOARG;
#endif #endif
#if defined(SIGUSR1)
static RETSIGTYPE catch_sigusr1 SIGPROTOARG;
#endif
#if defined(SIGPWR) #if defined(SIGPWR)
static RETSIGTYPE catch_sigpwr SIGPROTOARG; static RETSIGTYPE catch_sigpwr SIGPROTOARG;
#endif #endif
@@ -297,7 +300,7 @@ static struct signalinfo
{SIGXFSZ, "XFSZ", TRUE}, {SIGXFSZ, "XFSZ", TRUE},
#endif #endif
#ifdef SIGUSR1 #ifdef SIGUSR1
{SIGUSR1, "USR1", TRUE}, {SIGUSR1, "USR1", FALSE},
#endif #endif
#if defined(SIGUSR2) && !defined(FEAT_SYSMOUSE) #if defined(SIGUSR2) && !defined(FEAT_SYSMOUSE)
// Used for sysmouse handling // Used for sysmouse handling
@@ -837,6 +840,17 @@ catch_sigint SIGDEFARG(sigarg)
} }
#endif #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) #if defined(SIGPWR)
static RETSIGTYPE static RETSIGTYPE
catch_sigpwr SIGDEFARG(sigarg) catch_sigpwr SIGDEFARG(sigarg)
@@ -1323,10 +1337,10 @@ set_signals(void)
#if defined(SIGCONT) #if defined(SIGCONT)
signal(SIGCONT, sigcont_handler); signal(SIGCONT, sigcont_handler);
#endif #endif
#ifdef SIGPIPE
/* /*
* We want to ignore breaking of PIPEs. * We want to ignore breaking of PIPEs.
*/ */
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
#endif #endif
@@ -1334,6 +1348,13 @@ set_signals(void)
catch_int_signal(); catch_int_signal();
#endif #endif
#ifdef SIGUSR1
/*
* Call user's handler on SIGUSR1
*/
signal(SIGUSR1, (RETSIGTYPE (*)())catch_sigusr1);
#endif
/* /*
* Ignore alarm signals (Perl's alarm() generates it). * Ignore alarm signals (Perl's alarm() generates it).
*/ */
@@ -1341,11 +1362,11 @@ set_signals(void)
signal(SIGALRM, SIG_IGN); signal(SIGALRM, SIG_IGN);
#endif #endif
#ifdef SIGPWR
/* /*
* Catch SIGPWR (power failure?) to preserve the swap files, so that no * Catch SIGPWR (power failure?) to preserve the swap files, so that no
* work will be lost. * work will be lost.
*/ */
#ifdef SIGPWR
signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr); signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr);
#endif #endif

View File

@@ -2509,4 +2509,17 @@ func Test_autocmd_deep_nesting()
autocmd! BufEnter Xfile autocmd! BufEnter Xfile
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
952,
/**/ /**/
951, 951,
/**/ /**/

View File

@@ -1316,6 +1316,7 @@ enum auto_event
EVENT_SESSIONLOADPOST, // after loading a session file EVENT_SESSIONLOADPOST, // after loading a session file
EVENT_SHELLCMDPOST, // after ":!cmd" EVENT_SHELLCMDPOST, // after ":!cmd"
EVENT_SHELLFILTERPOST, // after ":1,2!cmd", ":w !cmd", ":r !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_SOURCECMD, // sourcing a Vim script using command
EVENT_SOURCEPRE, // before sourcing a Vim script EVENT_SOURCEPRE, // before sourcing a Vim script
EVENT_SOURCEPOST, // after sourcing a Vim script EVENT_SOURCEPOST, // after sourcing a Vim script