@@ -211,6 +211,15 @@ static RETSIGTYPE deathtrap SIGPROTOARG;
211211static void catch_int_signal (void );
212212static void set_signals (void );
213213static void catch_signals (RETSIGTYPE (* func_deadly )(), RETSIGTYPE (* func_other )());
214+ #ifdef HAVE_SIGPROCMASK
215+ # define SIGSET_DECL (set ) sigset_t set;
216+ # define BLOCK_SIGNALS (set ) block_signals(set)
217+ # define UNBLOCK_SIGNALS (set ) unblock_signals(set)
218+ #else
219+ # define SIGSET_DECL (set )
220+ # define BLOCK_SIGNALS (set ) do { /**/ } while (0 )
221+ # define UNBLOCK_SIGNALS (set ) do { /**/ } while (0 )
222+ #endif
214223static int have_wildcard (int , char_u * * );
215224static int have_dollars (int , char_u * * );
216225
@@ -1468,6 +1477,33 @@ catch_signals(
14681477 signal (signal_info [i ].sig , func_other );
14691478}
14701479
1480+ #ifdef HAVE_SIGPROCMASK
1481+ static void
1482+ block_signals (sigset_t * set )
1483+ {
1484+ sigset_t newset ;
1485+ int i ;
1486+
1487+ sigemptyset (& newset );
1488+
1489+ for (i = 0 ; signal_info [i ].sig != -1 ; i ++ )
1490+ sigaddset (& newset , signal_info [i ].sig );
1491+
1492+ # if defined(_REENTRANT ) && defined(SIGCONT )
1493+ /* SIGCONT isn't in the list, because its default action is ignore */
1494+ sigaddset (& newset , SIGCONT );
1495+ # endif
1496+
1497+ sigprocmask (SIG_BLOCK , & newset , set );
1498+ }
1499+
1500+ static void
1501+ unblock_signals (sigset_t * set )
1502+ {
1503+ sigprocmask (SIG_SETMASK , set , NULL );
1504+ }
1505+ #endif
1506+
14711507/*
14721508 * Handling of SIGHUP, SIGQUIT and SIGTERM:
14731509 * "when" == a signal: when busy, postpone and return FALSE, otherwise
@@ -4283,12 +4319,18 @@ mch_call_shell(
42834319
42844320 if (!pipe_error ) /* pty or pipe opened or not used */
42854321 {
4322+ SIGSET_DECL (curset )
4323+
42864324# ifdef __BEOS__
42874325 beos_cleanup_read_thread ();
42884326# endif
42894327
4290- if ((pid = fork ()) == -1 ) /* maybe we should use vfork() */
4328+ BLOCK_SIGNALS (& curset );
4329+ pid = fork (); /* maybe we should use vfork() */
4330+ if (pid == -1 )
42914331 {
4332+ UNBLOCK_SIGNALS (& curset );
4333+
42924334 MSG_PUTS (_ ("\nCannot fork\n" ));
42934335 if ((options & (SHELL_READ |SHELL_WRITE ))
42944336# ifdef FEAT_GUI
@@ -4315,6 +4357,7 @@ mch_call_shell(
43154357 else if (pid == 0 ) /* child */
43164358 {
43174359 reset_signals (); /* handle signals normally */
4360+ UNBLOCK_SIGNALS (& curset );
43184361
43194362 if (!show_shell_mess || (options & SHELL_EXPAND ))
43204363 {
@@ -4458,6 +4501,7 @@ mch_call_shell(
44584501 */
44594502 catch_signals (SIG_IGN , SIG_ERR );
44604503 catch_int_signal ();
4504+ UNBLOCK_SIGNALS (& curset );
44614505
44624506 /*
44634507 * For the GUI we redirect stdin, stdout and stderr to our window.
@@ -5069,6 +5113,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
50695113 int use_file_for_out = options -> jo_io [PART_OUT ] == JIO_FILE ;
50705114 int use_file_for_err = options -> jo_io [PART_ERR ] == JIO_FILE ;
50715115 int use_out_for_err = options -> jo_io [PART_ERR ] == JIO_OUT ;
5116+ SIGSET_DECL (curset )
50725117
50735118 if (use_out_for_err && use_null_for_out )
50745119 use_null_for_err = TRUE;
@@ -5140,20 +5185,22 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
51405185 goto failed ;
51415186 }
51425187
5188+ BLOCK_SIGNALS (& curset );
51435189 pid = fork (); /* maybe we should use vfork() */
5144- if (pid == -1 )
5190+ if (pid == -1 )
51455191 {
51465192 /* failed to fork */
5193+ UNBLOCK_SIGNALS (& curset );
51475194 goto failed ;
51485195 }
5149-
51505196 if (pid == 0 )
51515197 {
51525198 int null_fd = -1 ;
51535199 int stderr_works = TRUE;
51545200
51555201 /* child */
51565202 reset_signals (); /* handle signals normally */
5203+ UNBLOCK_SIGNALS (& curset );
51575204
51585205# ifdef HAVE_SETSID
51595206 /* Create our own process group, so that the child and all its
@@ -5234,6 +5281,8 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
52345281 }
52355282
52365283 /* parent */
5284+ UNBLOCK_SIGNALS (& curset );
5285+
52375286 job -> jv_pid = pid ;
52385287 job -> jv_status = JOB_STARTED ;
52395288 job -> jv_channel = channel ; /* ch_refcount was set above */
@@ -5357,7 +5406,6 @@ mch_detect_ended_job(job_T *job_list)
53575406 }
53585407 }
53595408 return NULL ;
5360-
53615409}
53625410
53635411 int
0 commit comments