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:: SIGINFO , 
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