Function nc::rt_sigaction

source ·
pub unsafe fn rt_sigaction(
    sig: i32,
    act: &sigaction_t,
    old_act: &mut sigaction_t,
    sigsetsize: size_t
) -> Result<(), Errno>
Expand description

Examine and change a signal action.

§example

use std::mem::size_of;

fn handle_sigterm(sig: i32) {
    assert_eq!(sig, nc::SIGTERM);
}

let sa = nc::sigaction_t {
    sa_handler: handle_sigterm as nc::sighandler_t,
    sa_mask: (nc::SA_RESTART | nc::SA_SIGINFO | nc::SA_ONSTACK).into(),
    ..nc::sigaction_t::default()
};
let mut old_sa = nc::sigaction_t::default();
let ret = unsafe { nc::rt_sigaction(nc::SIGTERM, &sa, &mut old_sa, size_of::<nc::sigset_t>()) };
let ret = unsafe { nc::kill(nc::getpid(), nc::SIGTERM) };
assert!(ret.is_ok());
Examples found in repository?
examples/alarm.rs (line 21)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fn main() {
    let sa = nc::sigaction_t {
        sa_handler: handle_alarm as nc::sighandler_t,
        sa_flags: nc::SA_RESTART,
        ..nc::sigaction_t::default()
    };
    println!("sa.sa_mask size: {}", size_of_val(&sa));
    let mut old_sa = nc::sigaction_t::default();
    let ret = unsafe { nc::rt_sigaction(nc::SIGALRM, &sa, &mut old_sa, size_of::<nc::sigset_t>()) };
    assert!(ret.is_ok());

    let seconds = 1;
    let remaining = nc::util::alarm(seconds);

    let mask = nc::sigset_t::default();
    let ret = unsafe { nc::rt_sigsuspend(&mask, size_of::<nc::sigset_t>()) };
    assert!(ret.is_err());
    assert_eq!(ret, Err(nc::EINTR));

    assert_eq!(remaining.unwrap(), 0);
}
More examples
Hide additional examples
examples/timer.rs (line 16)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() {
    use core::mem::size_of;

    fn handle_alarm(signum: i32) {
        assert_eq!(signum, nc::SIGALRM);
        let msg = "Hello alarm";
        let _ = unsafe { nc::write(2, msg.as_ptr() as usize, msg.len()) };
    }

    let sa = nc::sigaction_t {
        sa_handler: handle_alarm as nc::sighandler_t,
        sa_flags: 0,
        ..nc::sigaction_t::default()
    };
    let mut old_sa = nc::sigaction_t::default();
    let ret = unsafe { nc::rt_sigaction(nc::SIGALRM, &sa, &mut old_sa, size_of::<nc::sigset_t>()) };
    assert!(ret.is_ok());

    // Single shot timer, actived after 1 second.
    let itv = nc::itimerval_t {
        it_value: nc::timeval_t {
            tv_sec: 1,
            tv_usec: 0,
        },
        it_interval: nc::timeval_t {
            tv_sec: 0,
            tv_usec: 0,
        },
    };
    let mut prev_itv = nc::itimerval_t::default();
    let ret = unsafe { nc::setitimer(nc::ITIMER_REAL, &itv, &mut prev_itv) };
    assert!(ret.is_ok());

    let ret = unsafe { nc::getitimer(nc::ITIMER_REAL, &mut prev_itv) };
    assert!(ret.is_ok());
    assert!(prev_itv.it_value.tv_sec <= itv.it_value.tv_sec);

    let mask = nc::sigset_t::default();
    let ret = unsafe { nc::rt_sigsuspend(&mask, size_of::<nc::sigset_t>()) };
    assert!(ret.is_err());

    let ret = unsafe { nc::getitimer(nc::ITIMER_REAL, &mut prev_itv) };
    assert!(ret.is_ok());
    assert_eq!(prev_itv.it_value.tv_sec, 0);
    assert_eq!(prev_itv.it_value.tv_usec, 0);
}
examples/mprotect.rs (lines 21-26)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
fn main() {
    // Register SIGSEGV handler.
    let sa = nc::sigaction_t {
        sa_handler: handle_segfault as nc::sighandler_t,
        sa_flags: nc::SA_SIGINFO,
        ..nc::sigaction_t::default()
    };
    let mut old_sa = nc::sigaction_t::default();
    let ret = unsafe {
        nc::rt_sigaction(
            nc::SIGSEGV,
            &sa,
            &mut old_sa,
            mem::size_of::<nc::sigset_t>(),
        )
    };
    assert!(ret.is_ok());

    // Initialize an anonymous mapping with 4 pages.
    let map_length = 4 * nc::PAGE_SIZE;
    #[cfg(target_arch = "arm")]
    let addr = unsafe {
        nc::mmap2(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };

    #[cfg(not(target_arch = "arm"))]
    let addr = unsafe {
        nc::mmap(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };
    assert!(addr.is_ok());
    let addr = addr.unwrap();

    // Set the third page readonly. And we will run into SIGSEGV when updating it.
    let ret = unsafe { nc::mprotect(addr + 2 * nc::PAGE_SIZE, nc::PAGE_SIZE, nc::PROT_READ) };
    assert!(ret.is_ok());

    for p in addr..(addr + map_length) {
        unsafe {
            *(p as *mut u8) = 42;
        }
    }

    let ret = unsafe { nc::munmap(addr, map_length) };
    assert!(ret.is_ok());
    unsafe { nc::exit(0) };
}