]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0952: no simple way to interrupt Vim v8.2.0952
authorBram Moolenaar <Bram@vim.org>
Wed, 10 Jun 2020 18:56:58 +0000 (20:56 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 10 Jun 2020 18:56:58 +0000 (20:56 +0200)
Problem:    No simple way to interrupt Vim.
Solution:   Add the SigUSR1 autocommand, triggered by SIGUSR1. (Jacob Hayes,
            closes #1718)

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

index 4d24ed79f42364aa0b2e7a51367cd18ccdf974ee..613dd8561c0db7d1436bddb610591906b7211166 100644 (file)
@@ -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 yanked or deleted in the
                                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.  To be used for
                                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! :-)
index 937e74187ff579562726fc7e60c26ab6b5e72e4c..8e0754b6904b2bdbd93975ac33cc97aa1a082be0 100644 (file)
@@ -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},
index fcee7dda721cb750b5e1f683634961c647e97ea7..2beffa57844de34fc0cacbc07a8d24cd371be398 100644 (file)
@@ -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;
     }
 
index 27a8d681461f1f62b4b8191a771cdc2ebd03a8d0..b8fd231dfafe325a638262f1e8b8f64f50cf01d3 100644 (file)
@@ -1171,9 +1171,14 @@ EXTERN int       curscript INIT(= 0);        // index in scriptin[]
 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
index c6ba2499bdabf04d3283085e151b36c3f312f093..095e3a78e2e72b5c596b5f1f917c77e0db5e0241 100644 (file)
@@ -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
 
index b7a523e39a3933f6d70c93e3d26ed331f7b1ee1a..9ac70700577c1d47331113272fcf497cc9a17e78 100644 (file)
@@ -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
index 7b292acde0288d070eb502bc6d60f2db0f7cc070..0ed018c84963f26e3605ab8395804783a738146d 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    952,
 /**/
     951,
 /**/
index 99afe297504872d1835a49e72eb2826e5240fa18..0204aa306ebf2f28741ff49557e56daf9bcf1dd2 100644 (file)
--- 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