2
2
// See http://rust-lang.org/COPYRIGHT.
3
3
4
4
use libc;
5
- use { Errno , Result } ;
5
+ use { Errno , Error , Result } ;
6
6
use std:: mem;
7
7
use std:: ptr;
8
8
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 ] = [
10
59
SIGHUP ,
11
60
SIGINT ,
12
61
SIGQUIT ,
@@ -22,6 +71,7 @@ pub use libc::{
22
71
SIGPIPE ,
23
72
SIGALRM ,
24
73
SIGTERM ,
74
+ SIGSTKFLT ,
25
75
SIGCHLD ,
26
76
SIGCONT ,
27
77
SIGSTOP ,
@@ -35,26 +85,83 @@ pub use libc::{
35
85
SIGPROF ,
36
86
SIGWINCH ,
37
87
SIGIO ,
38
- SIGSYS ,
39
- } ;
40
-
88
+ SIGPWR ,
89
+ SIGSYS ] ;
41
90
#[ 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 ,
43
121
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 ] ;
55
123
56
124
pub const NSIG : libc:: c_int = 32 ;
57
125
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
+
58
165
bitflags ! {
59
166
flags SaFlags : libc:: c_int {
60
167
const SA_NOCLDSTOP = libc:: SA_NOCLDSTOP ,
@@ -80,7 +187,6 @@ pub struct SigSet {
80
187
sigset : libc:: sigset_t
81
188
}
82
189
83
- pub type SigNum = libc:: c_int ;
84
190
85
191
impl SigSet {
86
192
pub fn all ( ) -> SigSet {
@@ -97,40 +203,33 @@ impl SigSet {
97
203
SigSet { sigset : sigset }
98
204
}
99
205
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 ) } ;
104
208
}
105
209
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 ) } ;
110
212
}
111
213
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 ) } ;
116
216
}
117
217
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" ) ,
123
225
}
124
- Ok ( ( ) )
125
226
}
126
227
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
+ }
134
233
}
135
234
}
136
235
@@ -165,11 +264,11 @@ impl SigSet {
165
264
166
265
/// Suspends execution of the calling thread until one of the signals in the
167
266
/// 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 ( ) } ;
170
269
let res = unsafe { libc:: sigwait ( & self . sigset as * const libc:: sigset_t , & mut signum) } ;
171
270
172
- Errno :: result ( res) . map ( |_| signum)
271
+ Errno :: result ( res) . map ( |_| Signal :: from_c_int ( signum) . unwrap ( ) )
173
272
}
174
273
}
175
274
@@ -185,8 +284,8 @@ impl AsRef<libc::sigset_t> for SigSet {
185
284
pub enum SigHandler {
186
285
SigDfl ,
187
286
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 ) )
190
289
}
191
290
192
291
pub struct SigAction {
@@ -214,11 +313,11 @@ impl SigAction {
214
313
}
215
314
}
216
315
217
- pub unsafe fn sigaction ( signum : SigNum , sigaction : & SigAction ) -> Result < SigAction > {
316
+ pub unsafe fn sigaction ( signal : Signal , sigaction : & SigAction ) -> Result < SigAction > {
218
317
let mut oldact = mem:: uninitialized :: < libc:: sigaction > ( ) ;
219
318
220
319
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 ) ;
222
321
223
322
Errno :: result ( res) . map ( |_| SigAction { sigaction : oldact } )
224
323
}
@@ -257,14 +356,14 @@ pub fn pthread_sigmask(how: SigFlags,
257
356
Errno :: result ( res) . map ( drop)
258
357
}
259
358
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 ) } ;
262
361
263
362
Errno :: result ( res) . map ( drop)
264
363
}
265
364
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 ) } ;
268
367
269
368
Errno :: result ( res) . map ( drop)
270
369
}
@@ -276,70 +375,70 @@ mod tests {
276
375
#[ test]
277
376
fn test_contains ( ) {
278
377
let mut mask = SigSet :: empty ( ) ;
279
- mask. add ( SIGUSR1 ) . unwrap ( ) ;
378
+ mask. add ( SIGUSR1 ) ;
280
379
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 ) ) ;
283
382
284
383
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 ) ) ;
287
386
}
288
387
289
388
#[ test]
290
389
fn test_clear ( ) {
291
390
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 ) ) ;
295
394
}
296
395
}
297
396
298
397
#[ test]
299
398
fn test_extend ( ) {
300
399
let mut one_signal = SigSet :: empty ( ) ;
301
- one_signal. add ( SIGUSR1 ) . unwrap ( ) ;
400
+ one_signal. add ( SIGUSR1 ) ;
302
401
303
402
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) ;
306
405
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 ) ) ;
309
408
}
310
409
311
410
#[ test]
312
411
fn test_thread_signal_block ( ) {
313
412
let mut mask = SigSet :: empty ( ) ;
314
- mask. add ( SIGUSR1 ) . unwrap ( ) ;
413
+ mask. add ( SIGUSR1 ) ;
315
414
316
415
assert ! ( mask. thread_block( ) . is_ok( ) ) ;
317
416
}
318
417
319
418
#[ test]
320
419
fn test_thread_signal_swap ( ) {
321
420
let mut mask = SigSet :: empty ( ) ;
322
- mask. add ( SIGUSR1 ) . unwrap ( ) ;
421
+ mask. add ( SIGUSR1 ) ;
323
422
mask. thread_block ( ) . unwrap ( ) ;
324
423
325
- assert ! ( SigSet :: thread_get_mask( ) . unwrap( ) . contains( SIGUSR1 ) . unwrap ( ) ) ;
424
+ assert ! ( SigSet :: thread_get_mask( ) . unwrap( ) . contains( SIGUSR1 ) ) ;
326
425
327
426
let mask2 = SigSet :: empty ( ) ;
328
- mask. add ( SIGUSR2 ) . unwrap ( ) ;
427
+ mask. add ( SIGUSR2 ) ;
329
428
330
429
let oldmask = mask2. thread_swap_mask ( SIG_SETMASK ) . unwrap ( ) ;
331
430
332
- assert ! ( oldmask. contains( SIGUSR1 ) . unwrap ( ) ) ;
333
- assert ! ( !oldmask. contains( SIGUSR2 ) . unwrap ( ) ) ;
431
+ assert ! ( oldmask. contains( SIGUSR1 ) ) ;
432
+ assert ! ( !oldmask. contains( SIGUSR2 ) ) ;
334
433
}
335
434
336
435
// TODO(#251): Re-enable after figuring out flakiness.
337
436
#[ cfg( not( any( target_os = "macos" , target_os = "ios" ) ) ) ]
338
437
#[ test]
339
438
fn test_sigwait ( ) {
340
439
let mut mask = SigSet :: empty ( ) ;
341
- mask. add ( SIGUSR1 ) . unwrap ( ) ;
342
- mask. add ( SIGUSR2 ) . unwrap ( ) ;
440
+ mask. add ( SIGUSR1 ) ;
441
+ mask. add ( SIGUSR2 ) ;
343
442
mask. thread_block ( ) . unwrap ( ) ;
344
443
345
444
raise ( SIGUSR1 ) . unwrap ( ) ;
0 commit comments