changeset 20800:e76b83c07bd8 v8.2.0952

patch 8.2.0952: no simple way to interrupt Vim Commit: https://github.com/vim/vim/commit/be5ee8686a50acf07b823bd293f9c765e533d213 Author: Bram Moolenaar <Bram@vim.org> 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)
author Bram Moolenaar <Bram@vim.org>
date Wed, 10 Jun 2020 21:00:04 +0200
parents a3f74832de9b
children f69512e0cedc
files runtime/doc/autocmd.txt src/autocmd.c src/getchar.c src/globals.h src/os_unix.c src/testdir/test_autocmd.vim src/version.c src/vim.h
diffstat 8 files changed, 67 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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! :-)
--- 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},
--- 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;
     }
 
--- 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
--- 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
 
--- 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
--- 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,
--- 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