@@ -179,6 +179,107 @@ pub trait CommandExt: Sealed {
179
179
/// ```
180
180
#[ stable( feature = "process_set_process_group" , since = "1.64.0" ) ]
181
181
fn process_group ( & mut self , pgroup : i32 ) -> & mut process:: Command ;
182
+
183
+ /// Blocks the given signal for the child process at the time it is started.
184
+ ///
185
+ /// The set of blocked signals for a process is known as its signal mask.
186
+ /// Use this method to block some signals.
187
+ ///
188
+ /// This method corresponds to calling [`sigaddset`] with the given signal.
189
+ ///
190
+ /// # Notes
191
+ ///
192
+ /// Rust's current default is to not block any signals in child processes. This may change in
193
+ /// the future to inheriting the current process's signal mask.
194
+ ///
195
+ /// This method is idempotent: blocking a signal that's already blocked results in
196
+ /// success and has no effect.
197
+ ///
198
+ /// Blocking some signals like `SIGSEGV` can lead to undefined behavior in
199
+ /// the child. See the [`pthread_sigmask`] man page for more information.
200
+ ///
201
+ /// # Errors
202
+ ///
203
+ /// Returns an `InvalidInput` error if the signal is invalid.
204
+ ///
205
+ /// # Examples
206
+ ///
207
+ /// Start a process with `SIGINT` blocked:
208
+ ///
209
+ /// ```no_run
210
+ /// #![feature(process_sigmask)]
211
+ /// #
212
+ /// use std::process::Command;
213
+ /// use std::os::unix::process::CommandExt;
214
+ ///
215
+ /// Command::new("sleep")
216
+ /// .arg("10")
217
+ /// // On most platforms, SIGINT is signal 2.
218
+ /// .block_signal(2)?
219
+ /// .spawn()?;
220
+ /// #
221
+ /// # Ok::<_, Box<dyn std::error::Error>>(())
222
+ /// ```
223
+ ///
224
+ /// [`sigaddset`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html
225
+ /// [`pthread_sigmask`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html
226
+ #[ unstable( feature = "process_sigmask" , issue = "none" ) ]
227
+ fn block_signal ( & mut self , signal : i32 ) -> io:: Result < & mut process:: Command > ;
228
+
229
+ /// Unblocks the given signal for the child process at the time it is started.
230
+ ///
231
+ /// The set of blocked signals for a process is known as its signal mask.
232
+ /// Use this method to unblock a signal.
233
+ ///
234
+ /// This method corresponds to calling [`sigdelset`] with the given signal.
235
+ ///
236
+ /// # Notes
237
+ ///
238
+ /// Rust's current default is to not block any signals in child processes. This may change in
239
+ /// the future to inheriting the current process's signal mask.
240
+ ///
241
+ /// This method is idempotent: unblocking a signal that's already unblocked results in
242
+ /// success and has no effect.
243
+ ///
244
+ /// # Errors
245
+ ///
246
+ /// Returns an `InvalidInput` error if the signal is invalid.
247
+ ///
248
+ /// # Examples
249
+ ///
250
+ /// Start a process with `SIGHUP` unblocked:
251
+ ///
252
+ /// ```no_run
253
+ /// #![feature(process_sigmask)]
254
+ /// #
255
+ /// use std::process::Command;
256
+ /// use std::os::unix::process::CommandExt;
257
+ ///
258
+ /// Command::new("sleep")
259
+ /// .arg("10")
260
+ /// // On most platforms, SIGHUP is signal 1.
261
+ /// .unblock_signal(1)?
262
+ /// .spawn()?;
263
+ /// #
264
+ /// # Ok::<_, Box<dyn std::error::Error>>(())
265
+ /// ```
266
+ ///
267
+ /// [`sigdelset`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigdelset.html
268
+ /// [`pthread_sigmask`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html
269
+ #[ unstable( feature = "process_sigmask" , issue = "none" ) ]
270
+ fn unblock_signal ( & mut self , signal : i32 ) -> io:: Result < & mut process:: Command > ;
271
+
272
+ /// Returns true if a signal will be blocked in the child process at the time it is started.
273
+ ///
274
+ /// This method corresponds to calling [`sigismember`] with the given signal.
275
+ ///
276
+ /// # Errors
277
+ ///
278
+ /// Returns an `InvalidInput` error if the signal is invalid.
279
+ ///
280
+ /// [`sigismember`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigismember.html
281
+ #[ unstable( feature = "process_sigmask" , issue = "none" ) ]
282
+ fn will_block_signal ( & self , signal : i32 ) -> io:: Result < bool > ;
182
283
}
183
284
184
285
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -224,6 +325,20 @@ impl CommandExt for process::Command {
224
325
self . as_inner_mut ( ) . pgroup ( pgroup) ;
225
326
self
226
327
}
328
+
329
+ fn block_signal ( & mut self , signal : i32 ) -> io:: Result < & mut process:: Command > {
330
+ self . as_inner_mut ( ) . signal_mask ( ) ?. insert ( signal) ?;
331
+ Ok ( self )
332
+ }
333
+
334
+ fn unblock_signal ( & mut self , signal : i32 ) -> io:: Result < & mut process:: Command > {
335
+ self . as_inner_mut ( ) . signal_mask ( ) ?. remove ( signal) ?;
336
+ Ok ( self )
337
+ }
338
+
339
+ fn will_block_signal ( & self , signal : i32 ) -> io:: Result < bool > {
340
+ self . as_inner ( ) . get_signal_mask ( ) ?. contains ( signal)
341
+ }
227
342
}
228
343
229
344
/// Unix-specific extensions to [`process::ExitStatus`] and
0 commit comments