22// See http://rust-lang.org/COPYRIGHT.
33
44use libc;
5- use { Errno , Result } ;
5+ use { Errno , Error , Result } ;
66use std:: mem;
77use std:: ptr;
88
9- pub use libc:: {
9+ // Currently there is only one definition of c_int in libc, as well as only one
10+ // type for signal constants.
11+ // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately
12+ // this is not (yet) possible.
13+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
14+ #[ repr( i32 ) ]
15+ pub enum Signal {
16+ SIGHUP = libc:: SIGHUP ,
17+ SIGINT = libc:: SIGINT ,
18+ SIGQUIT = libc:: SIGQUIT ,
19+ SIGILL = libc:: SIGILL ,
20+ SIGTRAP = libc:: SIGTRAP ,
21+ SIGABRT = libc:: SIGABRT ,
22+ SIGBUS = libc:: SIGBUS ,
23+ SIGFPE = libc:: SIGFPE ,
24+ SIGKILL = libc:: SIGKILL ,
25+ SIGUSR1 = libc:: SIGUSR1 ,
26+ SIGSEGV = libc:: SIGSEGV ,
27+ SIGUSR2 = libc:: SIGUSR2 ,
28+ SIGPIPE = libc:: SIGPIPE ,
29+ SIGALRM = libc:: SIGALRM ,
30+ SIGTERM = libc:: SIGTERM ,
31+ #[ cfg( not( target_os = "macos" ) ) ]
32+ SIGSTKFLT = libc:: SIGSTKFLT ,
33+ SIGCHLD = libc:: SIGCHLD ,
34+ SIGCONT = libc:: SIGCONT ,
35+ SIGSTOP = libc:: SIGSTOP ,
36+ SIGTSTP = libc:: SIGTSTP ,
37+ SIGTTIN = libc:: SIGTTIN ,
38+ SIGTTOU = libc:: SIGTTOU ,
39+ SIGURG = libc:: SIGURG ,
40+ SIGXCPU = libc:: SIGXCPU ,
41+ SIGXFSZ = libc:: SIGXFSZ ,
42+ SIGVTALRM = libc:: SIGVTALRM ,
43+ SIGPROF = libc:: SIGPROF ,
44+ SIGWINCH = libc:: SIGWINCH ,
45+ SIGIO = libc:: SIGIO ,
46+ #[ cfg( not( target_os = "macos" ) ) ]
47+ SIGPWR = libc:: SIGPWR ,
48+ SIGSYS = libc:: SIGSYS ,
49+ #[ cfg( target_os = "macos" ) ]
50+ SIGEMT = libc:: SIGEMT ,
51+ #[ cfg( target_os = "macos" ) ]
52+ SIGINFO = libc:: SIGEMT ,
53+ }
54+
55+ pub use self :: Signal :: * ;
56+
57+ #[ cfg( not( target_os = "macos" ) ) ]
58+ const SIGNALS : [ Signal ; 31 ] = [
1059 SIGHUP ,
1160 SIGINT ,
1261 SIGQUIT ,
@@ -22,6 +71,7 @@ pub use libc::{
2271 SIGPIPE ,
2372 SIGALRM ,
2473 SIGTERM ,
74+ SIGSTKFLT ,
2575 SIGCHLD ,
2676 SIGCONT ,
2777 SIGSTOP ,
@@ -35,26 +85,83 @@ pub use libc::{
3585 SIGPROF ,
3686 SIGWINCH ,
3787 SIGIO ,
38- SIGSYS ,
39- } ;
40-
88+ SIGPWR ,
89+ SIGSYS ] ;
4190#[ cfg( target_os = "macos" ) ]
42- pub use libc:: {
91+ const SIGNALS : [ Signal ; 31 ] = [
92+ SIGHUP ,
93+ SIGINT ,
94+ SIGQUIT ,
95+ SIGILL ,
96+ SIGTRAP ,
97+ SIGABRT ,
98+ SIGBUS ,
99+ SIGFPE ,
100+ SIGKILL ,
101+ SIGUSR1 ,
102+ SIGSEGV ,
103+ SIGUSR2 ,
104+ SIGPIPE ,
105+ SIGALRM ,
106+ SIGTERM ,
107+ SIGCHLD ,
108+ SIGCONT ,
109+ SIGSTOP ,
110+ SIGTSTP ,
111+ SIGTTIN ,
112+ SIGTTOU ,
113+ SIGURG ,
114+ SIGXCPU ,
115+ SIGXFSZ ,
116+ SIGVTALRM ,
117+ SIGPROF ,
118+ SIGWINCH ,
119+ SIGIO ,
120+ SIGSYS ,
43121 SIGEMT ,
44- SIGINFO ,
45- } ;
46-
47- #[ cfg( not( target_os = "macos" ) ) ]
48- pub use libc:: {
49- SIGPWR ,
50- SIGSTKFLT ,
51- SIGIOT , // Alias for SIGABRT
52- SIGPOLL , // Alias for SIGIO
53- SIGUNUSED , // Alias for 31
54- } ;
122+ SIGINFO ] ;
55123
56124pub const NSIG : libc:: c_int = 32 ;
57125
126+ pub struct SignalIterator {
127+ next : usize ,
128+ }
129+
130+ impl Iterator for SignalIterator {
131+ type Item = Signal ;
132+
133+ fn next ( & mut self ) -> Option < Signal > {
134+ if self . next < SIGNALS . len ( ) {
135+ let next_signal = SIGNALS [ self . next ] ;
136+ self . next += 1 ;
137+ Some ( next_signal)
138+ } else {
139+ None
140+ }
141+ }
142+ }
143+
144+ impl Signal {
145+ pub fn iterator ( ) -> SignalIterator {
146+ SignalIterator { next : 0 }
147+ }
148+
149+ // We do not implement the From trait, because it is supposed to be infallible.
150+ // With Rust RFC 1542 comes the appropriate trait TryFrom. Once it is
151+ // implemented, we'll replace this function.
152+ #[ inline]
153+ pub fn from_c_int ( signum : libc:: c_int ) -> Result < Signal > {
154+ match 0 < signum && signum < NSIG {
155+ true => Ok ( unsafe { mem:: transmute ( signum) } ) ,
156+ false => Err ( Error :: invalid_argument ( ) ) ,
157+ }
158+ }
159+ }
160+
161+ pub const SIGIOT : Signal = SIGABRT ;
162+ pub const SIGPOLL : Signal = SIGIO ;
163+ pub const SIGUNUSED : Signal = SIGSYS ;
164+
58165bitflags ! {
59166 flags SaFlags : libc:: c_int {
60167 const SA_NOCLDSTOP = libc:: SA_NOCLDSTOP ,
@@ -80,7 +187,6 @@ pub struct SigSet {
80187 sigset : libc:: sigset_t
81188}
82189
83- pub type SigNum = libc:: c_int ;
84190
85191impl SigSet {
86192 pub fn all ( ) -> SigSet {
@@ -97,40 +203,33 @@ impl SigSet {
97203 SigSet { sigset : sigset }
98204 }
99205
100- pub fn add ( & mut self , signum : SigNum ) -> Result < ( ) > {
101- let res = unsafe { libc:: sigaddset ( & mut self . sigset as * mut libc:: sigset_t , signum) } ;
102-
103- Errno :: result ( res) . map ( drop)
206+ pub fn add ( & mut self , signal : Signal ) {
207+ unsafe { libc:: sigaddset ( & mut self . sigset as * mut libc:: sigset_t , signal as libc:: c_int ) } ;
104208 }
105209
106- pub fn clear ( & mut self ) -> Result < ( ) > {
107- let res = unsafe { libc:: sigemptyset ( & mut self . sigset as * mut libc:: sigset_t ) } ;
108-
109- Errno :: result ( res) . map ( drop)
210+ pub fn clear ( & mut self ) {
211+ unsafe { libc:: sigemptyset ( & mut self . sigset as * mut libc:: sigset_t ) } ;
110212 }
111213
112- pub fn remove ( & mut self , signum : SigNum ) -> Result < ( ) > {
113- let res = unsafe { libc:: sigdelset ( & mut self . sigset as * mut libc:: sigset_t , signum) } ;
114-
115- Errno :: result ( res) . map ( drop)
214+ pub fn remove ( & mut self , signal : Signal ) {
215+ unsafe { libc:: sigdelset ( & mut self . sigset as * mut libc:: sigset_t , signal as libc:: c_int ) } ;
116216 }
117217
118- pub fn extend ( & mut self , other : & SigSet ) -> Result < ( ) > {
119- for i in 1 ..NSIG {
120- if try!( other. contains ( i) ) {
121- try!( self . add ( i) ) ;
122- }
218+ pub fn contains ( & self , signal : Signal ) -> bool {
219+ let res = unsafe { libc:: sigismember ( & self . sigset as * const libc:: sigset_t , signal as libc:: c_int ) } ;
220+
221+ match res {
222+ 1 => true ,
223+ 0 => false ,
224+ _ => unreachable ! ( "unexpected value from sigismember" ) ,
123225 }
124- Ok ( ( ) )
125226 }
126227
127- pub fn contains ( & self , signum : SigNum ) -> Result < bool > {
128- let res = unsafe { libc:: sigismember ( & self . sigset as * const libc:: sigset_t , signum) } ;
129-
130- match try!( Errno :: result ( res) ) {
131- 1 => Ok ( true ) ,
132- 0 => Ok ( false ) ,
133- _ => unreachable ! ( "unexpected value from sigismember" ) ,
228+ pub fn extend ( & mut self , other : & SigSet ) {
229+ for signal in Signal :: iterator ( ) {
230+ if other. contains ( signal) {
231+ self . add ( signal) ;
232+ }
134233 }
135234 }
136235
@@ -165,11 +264,11 @@ impl SigSet {
165264
166265 /// Suspends execution of the calling thread until one of the signals in the
167266 /// signal mask becomes pending, and returns the accepted signal.
168- pub fn wait ( & self ) -> Result < SigNum > {
169- let mut signum: SigNum = unsafe { mem:: uninitialized ( ) } ;
267+ pub fn wait ( & self ) -> Result < Signal > {
268+ let mut signum: libc :: c_int = unsafe { mem:: uninitialized ( ) } ;
170269 let res = unsafe { libc:: sigwait ( & self . sigset as * const libc:: sigset_t , & mut signum) } ;
171270
172- Errno :: result ( res) . map ( |_| signum)
271+ Errno :: result ( res) . map ( |_| Signal :: from_c_int ( signum) . unwrap ( ) )
173272 }
174273}
175274
@@ -185,8 +284,8 @@ impl AsRef<libc::sigset_t> for SigSet {
185284pub enum SigHandler {
186285 SigDfl ,
187286 SigIgn ,
188- Handler ( extern fn ( SigNum ) ) ,
189- SigAction ( extern fn ( SigNum , * mut libc:: siginfo_t , * mut libc:: c_void ) )
287+ Handler ( extern fn ( libc :: c_int ) ) ,
288+ SigAction ( extern fn ( libc :: c_int , * mut libc:: siginfo_t , * mut libc:: c_void ) )
190289}
191290
192291pub struct SigAction {
@@ -214,11 +313,11 @@ impl SigAction {
214313 }
215314}
216315
217- pub unsafe fn sigaction ( signum : SigNum , sigaction : & SigAction ) -> Result < SigAction > {
316+ pub unsafe fn sigaction ( signal : Signal , sigaction : & SigAction ) -> Result < SigAction > {
218317 let mut oldact = mem:: uninitialized :: < libc:: sigaction > ( ) ;
219318
220319 let res =
221- libc:: sigaction ( signum , & sigaction. sigaction as * const libc:: sigaction , & mut oldact as * mut libc:: sigaction ) ;
320+ libc:: sigaction ( signal as libc :: c_int , & sigaction. sigaction as * const libc:: sigaction , & mut oldact as * mut libc:: sigaction ) ;
222321
223322 Errno :: result ( res) . map ( |_| SigAction { sigaction : oldact } )
224323}
@@ -257,14 +356,14 @@ pub fn pthread_sigmask(how: SigFlags,
257356 Errno :: result ( res) . map ( drop)
258357}
259358
260- pub fn kill ( pid : libc:: pid_t , signum : SigNum ) -> Result < ( ) > {
261- let res = unsafe { libc:: kill ( pid, signum ) } ;
359+ pub fn kill ( pid : libc:: pid_t , signal : Signal ) -> Result < ( ) > {
360+ let res = unsafe { libc:: kill ( pid, signal as libc :: c_int ) } ;
262361
263362 Errno :: result ( res) . map ( drop)
264363}
265364
266- pub fn raise ( signum : SigNum ) -> Result < ( ) > {
267- let res = unsafe { libc:: raise ( signum ) } ;
365+ pub fn raise ( signal : Signal ) -> Result < ( ) > {
366+ let res = unsafe { libc:: raise ( signal as libc :: c_int ) } ;
268367
269368 Errno :: result ( res) . map ( drop)
270369}
@@ -276,70 +375,70 @@ mod tests {
276375 #[ test]
277376 fn test_contains ( ) {
278377 let mut mask = SigSet :: empty ( ) ;
279- mask. add ( SIGUSR1 ) . unwrap ( ) ;
378+ mask. add ( SIGUSR1 ) ;
280379
281- assert_eq ! ( mask. contains( SIGUSR1 ) , Ok ( true ) ) ;
282- assert_eq ! ( mask. contains( SIGUSR2 ) , Ok ( false ) ) ;
380+ assert ! ( mask. contains( SIGUSR1 ) ) ;
381+ assert ! ( ! mask. contains( SIGUSR2 ) ) ;
283382
284383 let all = SigSet :: all ( ) ;
285- assert_eq ! ( all. contains( SIGUSR1 ) , Ok ( true ) ) ;
286- assert_eq ! ( all. contains( SIGUSR2 ) , Ok ( true ) ) ;
384+ assert ! ( all. contains( SIGUSR1 ) ) ;
385+ assert ! ( all. contains( SIGUSR2 ) ) ;
287386 }
288387
289388 #[ test]
290389 fn test_clear ( ) {
291390 let mut set = SigSet :: all ( ) ;
292- set. clear ( ) . unwrap ( ) ;
293- for i in 1 .. NSIG {
294- assert_eq ! ( set. contains( i ) , Ok ( false ) ) ;
391+ set. clear ( ) ;
392+ for signal in Signal :: iterator ( ) {
393+ assert ! ( ! set. contains( signal ) ) ;
295394 }
296395 }
297396
298397 #[ test]
299398 fn test_extend ( ) {
300399 let mut one_signal = SigSet :: empty ( ) ;
301- one_signal. add ( SIGUSR1 ) . unwrap ( ) ;
400+ one_signal. add ( SIGUSR1 ) ;
302401
303402 let mut two_signals = SigSet :: empty ( ) ;
304- two_signals. add ( SIGUSR2 ) . unwrap ( ) ;
305- two_signals. extend ( & one_signal) . unwrap ( ) ;
403+ two_signals. add ( SIGUSR2 ) ;
404+ two_signals. extend ( & one_signal) ;
306405
307- assert_eq ! ( two_signals. contains( SIGUSR1 ) , Ok ( true ) ) ;
308- assert_eq ! ( two_signals. contains( SIGUSR2 ) , Ok ( true ) ) ;
406+ assert ! ( two_signals. contains( SIGUSR1 ) ) ;
407+ assert ! ( two_signals. contains( SIGUSR2 ) ) ;
309408 }
310409
311410 #[ test]
312411 fn test_thread_signal_block ( ) {
313412 let mut mask = SigSet :: empty ( ) ;
314- mask. add ( SIGUSR1 ) . unwrap ( ) ;
413+ mask. add ( SIGUSR1 ) ;
315414
316415 assert ! ( mask. thread_block( ) . is_ok( ) ) ;
317416 }
318417
319418 #[ test]
320419 fn test_thread_signal_swap ( ) {
321420 let mut mask = SigSet :: empty ( ) ;
322- mask. add ( SIGUSR1 ) . unwrap ( ) ;
421+ mask. add ( SIGUSR1 ) ;
323422 mask. thread_block ( ) . unwrap ( ) ;
324423
325- assert ! ( SigSet :: thread_get_mask( ) . unwrap( ) . contains( SIGUSR1 ) . unwrap ( ) ) ;
424+ assert ! ( SigSet :: thread_get_mask( ) . unwrap( ) . contains( SIGUSR1 ) ) ;
326425
327426 let mask2 = SigSet :: empty ( ) ;
328- mask. add ( SIGUSR2 ) . unwrap ( ) ;
427+ mask. add ( SIGUSR2 ) ;
329428
330429 let oldmask = mask2. thread_swap_mask ( SIG_SETMASK ) . unwrap ( ) ;
331430
332- assert ! ( oldmask. contains( SIGUSR1 ) . unwrap ( ) ) ;
333- assert ! ( !oldmask. contains( SIGUSR2 ) . unwrap ( ) ) ;
431+ assert ! ( oldmask. contains( SIGUSR1 ) ) ;
432+ assert ! ( !oldmask. contains( SIGUSR2 ) ) ;
334433 }
335434
336435 // TODO(#251): Re-enable after figuring out flakiness.
337436 #[ cfg( not( any( target_os = "macos" , target_os = "ios" ) ) ) ]
338437 #[ test]
339438 fn test_sigwait ( ) {
340439 let mut mask = SigSet :: empty ( ) ;
341- mask. add ( SIGUSR1 ) . unwrap ( ) ;
342- mask. add ( SIGUSR2 ) . unwrap ( ) ;
440+ mask. add ( SIGUSR1 ) ;
441+ mask. add ( SIGUSR2 ) ;
343442 mask. thread_block ( ) . unwrap ( ) ;
344443
345444 raise ( SIGUSR1 ) . unwrap ( ) ;
0 commit comments