@@ -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
@@ -4301,12 +4337,18 @@ mch_call_shell(
43014337
43024338 if (!pipe_error ) /* pty or pipe opened or not used */
43034339 {
4340+ SIGSET_DECL (curset )
4341+
43044342# ifdef __BEOS__
43054343 beos_cleanup_read_thread ();
43064344# endif
43074345
4308- if ((pid = fork ()) == -1 ) /* maybe we should use vfork() */
4346+ BLOCK_SIGNALS (& curset );
4347+ pid = fork (); /* maybe we should use vfork() */
4348+ if (pid == -1 )
43094349 {
4350+ UNBLOCK_SIGNALS (& curset );
4351+
43104352 MSG_PUTS (_ ("\nCannot fork\n" ));
43114353 if ((options & (SHELL_READ |SHELL_WRITE ))
43124354# ifdef FEAT_GUI
@@ -4333,6 +4375,7 @@ mch_call_shell(
43334375 else if (pid == 0 ) /* child */
43344376 {
43354377 reset_signals (); /* handle signals normally */
4378+ UNBLOCK_SIGNALS (& curset );
43364379
43374380 if (!show_shell_mess || (options & SHELL_EXPAND ))
43384381 {
@@ -4476,6 +4519,7 @@ mch_call_shell(
44764519 */
44774520 catch_signals (SIG_IGN , SIG_ERR );
44784521 catch_int_signal ();
4522+ UNBLOCK_SIGNALS (& curset );
44794523
44804524 /*
44814525 * For the GUI we redirect stdin, stdout and stderr to our window.
@@ -5091,6 +5135,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
50915135 int use_file_for_out = options -> jo_io [PART_OUT ] == JIO_FILE ;
50925136 int use_file_for_err = options -> jo_io [PART_ERR ] == JIO_FILE ;
50935137 int use_out_for_err = options -> jo_io [PART_ERR ] == JIO_OUT ;
5138+ SIGSET_DECL (curset )
50945139
50955140 if (use_out_for_err && use_null_for_out )
50965141 use_null_for_err = TRUE;
@@ -5162,20 +5207,22 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
51625207 goto failed ;
51635208 }
51645209
5210+ BLOCK_SIGNALS (& curset );
51655211 pid = fork (); /* maybe we should use vfork() */
5166- if (pid == -1 )
5212+ if (pid == -1 )
51675213 {
51685214 /* failed to fork */
5215+ UNBLOCK_SIGNALS (& curset );
51695216 goto failed ;
51705217 }
5171-
51725218 if (pid == 0 )
51735219 {
51745220 int null_fd = -1 ;
51755221 int stderr_works = TRUE;
51765222
51775223 /* child */
51785224 reset_signals (); /* handle signals normally */
5225+ UNBLOCK_SIGNALS (& curset );
51795226
51805227# ifdef HAVE_SETSID
51815228 /* Create our own process group, so that the child and all its
@@ -5256,6 +5303,8 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
52565303 }
52575304
52585305 /* parent */
5306+ UNBLOCK_SIGNALS (& curset );
5307+
52595308 job -> jv_pid = pid ;
52605309 job -> jv_status = JOB_STARTED ;
52615310 job -> jv_channel = channel ; /* ch_refcount was set above */
@@ -5379,7 +5428,6 @@ mch_detect_ended_job(job_T *job_list)
53795428 }
53805429 }
53815430 return NULL ;
5382-
53835431}
53845432
53855433 int
0 commit comments