Skip to content

Commit be5ee86

Browse files
committed
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)
1 parent 6ba24d8 commit be5ee86

File tree

8 files changed

+67
-6
lines changed

8 files changed

+67
-6
lines changed

runtime/doc/autocmd.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ Name triggered by ~
380380
info
381381

382382
|User| to be used in combination with ":doautocmd"
383+
|SigUSR1| after the SIGUSR1 signal has been detected
383384

384385

385386
The alphabetical list of autocommand events: *autocmd-events-abc*
@@ -1158,6 +1159,7 @@ TextYankPost After text has been yanked or deleted in the
11581159
It is not allowed to change the buffer text,
11591160
see |textlock|.
11601161
{only when compiled with the +eval feature}
1162+
11611163
*User*
11621164
User Never executed automatically. To be used for
11631165
autocommands that are only executed with
@@ -1166,6 +1168,15 @@ User Never executed automatically. To be used for
11661168
used while there are no matching autocommands,
11671169
you will get an error. If you don't want
11681170
that, define a dummy autocommand yourself.
1171+
1172+
*SigUSR1*
1173+
SigUSR1 After the SIGUSR1 signal has been detected.
1174+
Could be used if other ways of notifying Vim
1175+
are not feasible. E.g. to check for the
1176+
result of a build that takes a long time, or
1177+
when a motion sensor is triggered.
1178+
{only on Unix}
1179+
11691180
*UserGettingBored*
11701181
UserGettingBored When the user presses the same key 42 times.
11711182
Just kidding! :-)

src/autocmd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ static struct event_name
161161
{"SessionLoadPost", EVENT_SESSIONLOADPOST},
162162
{"ShellCmdPost", EVENT_SHELLCMDPOST},
163163
{"ShellFilterPost", EVENT_SHELLFILTERPOST},
164+
{"SigUSR1", EVENT_SIGUSR1},
164165
{"SourceCmd", EVENT_SOURCECMD},
165166
{"SourcePre", EVENT_SOURCEPRE},
166167
{"SourcePost", EVENT_SOURCEPOST},

src/getchar.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,6 +2204,13 @@ parse_queued_messages(void)
22042204
if (has_sound_callback_in_queue())
22052205
invoke_sound_callback();
22062206
# endif
2207+
#ifdef SIGUSR1
2208+
if (got_sigusr1)
2209+
{
2210+
apply_autocmds(EVENT_SIGUSR1, NULL, NULL, FALSE, curbuf);
2211+
got_sigusr1 = FALSE;
2212+
}
2213+
#endif
22072214
break;
22082215
}
22092216

src/globals.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,9 +1171,14 @@ EXTERN int curscript INIT(= 0); // index in scriptin[]
11711171
EXTERN FILE *scriptout INIT(= NULL); // stream to write script to
11721172
EXTERN int read_cmd_fd INIT(= 0); // fd to read commands from
11731173

1174-
// volatile because it is used in signal handler catch_sigint().
1175-
EXTERN volatile sig_atomic_t got_int INIT(= FALSE); // set to TRUE when interrupt
1176-
// signal occurred
1174+
// Set to TRUE when an interrupt signal occurred.
1175+
// Volatile because it is used in signal handler catch_sigint().
1176+
EXTERN volatile sig_atomic_t got_int INIT(= FALSE);
1177+
1178+
// Set to TRUE when SIGUSR1 signal was detected.
1179+
// Volatile because it is used in signal handler catch_sigint().
1180+
EXTERN volatile sig_atomic_t got_sigusr1 INIT(= FALSE);
1181+
11771182
#ifdef USE_TERM_CONSOLE
11781183
EXTERN int term_console INIT(= FALSE); // set to TRUE when console used
11791184
#endif

src/os_unix.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ static RETSIGTYPE sig_winch SIGPROTOARG;
164164
#if defined(SIGINT)
165165
static RETSIGTYPE catch_sigint SIGPROTOARG;
166166
#endif
167+
#if defined(SIGUSR1)
168+
static RETSIGTYPE catch_sigusr1 SIGPROTOARG;
169+
#endif
167170
#if defined(SIGPWR)
168171
static RETSIGTYPE catch_sigpwr SIGPROTOARG;
169172
#endif
@@ -297,7 +300,7 @@ static struct signalinfo
297300
{SIGXFSZ, "XFSZ", TRUE},
298301
#endif
299302
#ifdef SIGUSR1
300-
{SIGUSR1, "USR1", TRUE},
303+
{SIGUSR1, "USR1", FALSE},
301304
#endif
302305
#if defined(SIGUSR2) && !defined(FEAT_SYSMOUSE)
303306
// Used for sysmouse handling
@@ -837,6 +840,17 @@ catch_sigint SIGDEFARG(sigarg)
837840
}
838841
#endif
839842

843+
#if defined(SIGUSR1)
844+
static RETSIGTYPE
845+
catch_sigusr1 SIGDEFARG(sigarg)
846+
{
847+
// this is not required on all systems, but it doesn't hurt anybody
848+
signal(SIGUSR1, (RETSIGTYPE (*)())catch_sigusr1);
849+
got_sigusr1 = TRUE;
850+
SIGRETURN;
851+
}
852+
#endif
853+
840854
#if defined(SIGPWR)
841855
static RETSIGTYPE
842856
catch_sigpwr SIGDEFARG(sigarg)
@@ -1323,29 +1337,36 @@ set_signals(void)
13231337
#if defined(SIGCONT)
13241338
signal(SIGCONT, sigcont_handler);
13251339
#endif
1340+
#ifdef SIGPIPE
13261341
/*
13271342
* We want to ignore breaking of PIPEs.
13281343
*/
1329-
#ifdef SIGPIPE
13301344
signal(SIGPIPE, SIG_IGN);
13311345
#endif
13321346

13331347
#ifdef SIGINT
13341348
catch_int_signal();
13351349
#endif
13361350

1351+
#ifdef SIGUSR1
1352+
/*
1353+
* Call user's handler on SIGUSR1
1354+
*/
1355+
signal(SIGUSR1, (RETSIGTYPE (*)())catch_sigusr1);
1356+
#endif
1357+
13371358
/*
13381359
* Ignore alarm signals (Perl's alarm() generates it).
13391360
*/
13401361
#ifdef SIGALRM
13411362
signal(SIGALRM, SIG_IGN);
13421363
#endif
13431364

1365+
#ifdef SIGPWR
13441366
/*
13451367
* Catch SIGPWR (power failure?) to preserve the swap files, so that no
13461368
* work will be lost.
13471369
*/
1348-
#ifdef SIGPWR
13491370
signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr);
13501371
#endif
13511372

src/testdir/test_autocmd.vim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,4 +2509,17 @@ func Test_autocmd_deep_nesting()
25092509
autocmd! BufEnter Xfile
25102510
endfunc
25112511

2512+
" Tests for SigUSR1 autocmd event, which is only available on posix systems.
2513+
func Test_autocmd_sigusr1()
2514+
CheckUnix
2515+
2516+
let g:sigusr1_passed = 0
2517+
au SigUSR1 * let g:sigusr1_passed = 1
2518+
call system('/bin/kill -s usr1 ' . getpid())
2519+
call WaitForAssert({-> assert_true(g:sigusr1_passed)})
2520+
2521+
au! SigUSR1
2522+
unlet g:sigusr1_passed
2523+
endfunc
2524+
25122525
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
952,
757759
/**/
758760
951,
759761
/**/

src/vim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,7 @@ enum auto_event
13161316
EVENT_SESSIONLOADPOST, // after loading a session file
13171317
EVENT_SHELLCMDPOST, // after ":!cmd"
13181318
EVENT_SHELLFILTERPOST, // after ":1,2!cmd", ":w !cmd", ":r !cmd".
1319+
EVENT_SIGUSR1, // after the SIGUSR1 signal
13191320
EVENT_SOURCECMD, // sourcing a Vim script using command
13201321
EVENT_SOURCEPRE, // before sourcing a Vim script
13211322
EVENT_SOURCEPOST, // after sourcing a Vim script

0 commit comments

Comments
 (0)