123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- //! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
- use core::{mem, ptr};
- use cbitset::BitSet;
- use header::errno;
- use platform;
- use platform::types::*;
- use platform::{PalSignal, Sys};
- pub use self::sys::*;
- #[cfg(target_os = "linux")]
- #[path = "linux.rs"]
- pub mod sys;
- #[cfg(target_os = "redox")]
- #[path = "redox.rs"]
- pub mod sys;
- type SigSet = BitSet<[c_ulong; 1]>;
- const SIG_ERR: usize = !0;
- pub const SIG_BLOCK: c_int = 0;
- pub const SIG_UNBLOCK: c_int = 1;
- pub const SIG_SETMASK: c_int = 2;
- #[repr(C)]
- #[derive(Clone)]
- pub struct sigaction {
- pub sa_handler: extern "C" fn(c_int),
- pub sa_flags: c_ulong,
- pub sa_restorer: unsafe extern "C" fn(),
- pub sa_mask: sigset_t,
- }
- pub type sigset_t = c_ulong;
- #[no_mangle]
- pub extern "C" fn kill(pid: pid_t, sig: c_int) -> c_int {
- Sys::kill(pid, sig)
- }
- #[no_mangle]
- pub extern "C" fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
- Sys::killpg(pgrp, sig)
- }
- #[no_mangle]
- pub extern "C" fn pthread_sigmask(
- how: c_int,
- set: *const sigset_t,
- oldset: *mut sigset_t,
- ) -> c_int {
- // On Linux and Redox, pthread_sigmask and sigprocmask are equivalent
- if sigprocmask(how, set, oldset) == 0 {
- 0
- } else {
- //TODO: Fix race
- unsafe { platform::errno }
- }
- }
- #[no_mangle]
- pub extern "C" fn raise(sig: c_int) -> c_int {
- Sys::raise(sig)
- }
- #[no_mangle]
- pub unsafe extern "C" fn sigaction(
- sig: c_int,
- act: *const sigaction,
- oact: *mut sigaction,
- ) -> c_int {
- let mut _sigaction = None;
- let ptr = if !act.is_null() {
- _sigaction = Some((*act).clone());
- _sigaction.as_mut().unwrap().sa_flags |= SA_RESTORER as c_ulong;
- _sigaction.as_mut().unwrap() as *mut _
- } else {
- ptr::null_mut()
- };
- Sys::sigaction(sig, ptr, oact)
- }
- #[no_mangle]
- pub extern "C" fn sigaddset(set: *mut sigset_t, signo: c_int) -> c_int {
- if signo <= 0 || signo as usize > NSIG {
- unsafe {
- platform::errno = errno::EINVAL;
- }
- return -1;
- }
- if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
- set.insert(signo as usize - 1); // 0-indexed usize, please!
- }
- 0
- }
- #[no_mangle]
- pub extern "C" fn sigdelset(set: *mut sigset_t, signo: c_int) -> c_int {
- if signo <= 0 || signo as usize > NSIG {
- unsafe {
- platform::errno = errno::EINVAL;
- }
- return -1;
- }
- if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
- set.remove(signo as usize - 1); // 0-indexed usize, please!
- }
- 0
- }
- #[no_mangle]
- pub extern "C" fn sigemptyset(set: *mut sigset_t) -> c_int {
- if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
- set.clear();
- }
- 0
- }
- #[no_mangle]
- pub extern "C" fn sigfillset(set: *mut sigset_t) -> c_int {
- if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
- set.fill(.., true);
- }
- 0
- }
- // #[no_mangle]
- pub extern "C" fn sighold(sig: c_int) -> c_int {
- unimplemented!();
- }
- // #[no_mangle]
- pub extern "C" fn sigignore(sig: c_int) -> c_int {
- unimplemented!();
- }
- // #[no_mangle]
- pub extern "C" fn siginterrupt(sig: c_int, flag: c_int) -> c_int {
- unimplemented!();
- }
- #[no_mangle]
- pub extern "C" fn sigismember(set: *const sigset_t, signo: c_int) -> c_int {
- if signo <= 0 || signo as usize > NSIG {
- unsafe {
- platform::errno = errno::EINVAL;
- }
- return -1;
- }
- if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
- if set.contains(signo as usize - 1) {
- return 1;
- }
- }
- 0
- }
- extern "C" {
- // Defined in assembly inside platform/x/mod.rs
- fn __restore_rt();
- }
- #[no_mangle]
- pub extern "C" fn signal(sig: c_int, func: extern "C" fn(c_int)) -> extern "C" fn(c_int) {
- let sa = sigaction {
- sa_handler: func,
- sa_flags: SA_RESTART as c_ulong,
- sa_restorer: __restore_rt,
- sa_mask: sigset_t::default(),
- };
- let mut old_sa = unsafe { mem::uninitialized() };
- if unsafe { sigaction(sig, &sa, &mut old_sa) } < 0 {
- mem::forget(old_sa);
- return unsafe { mem::transmute(SIG_ERR) };
- }
- old_sa.sa_handler
- }
- // #[no_mangle]
- pub extern "C" fn sigpause(sig: c_int) -> c_int {
- unimplemented!();
- }
- // #[no_mangle]
- pub extern "C" fn sigpending(set: *mut sigset_t) -> c_int {
- unimplemented!();
- }
- #[no_mangle]
- pub extern "C" fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
- Sys::sigprocmask(how, set, oset)
- }
- // #[no_mangle]
- pub extern "C" fn sigrelse(sig: c_int) -> c_int {
- unimplemented!();
- }
- // #[no_mangle]
- pub extern "C" fn sigset(sig: c_int, func: fn(c_int)) -> fn(c_int) {
- unimplemented!();
- }
- // #[no_mangle]
- pub extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int {
- unimplemented!();
- }
- // #[no_mangle]
- pub extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int {
- unimplemented!();
- }
- pub const _signal_strings: [&str; 32] = [
- "Unknown signal\0",
- "Hangup\0",
- "Interrupt\0",
- "Quit\0",
- "Illegal instruction\0",
- "Trace/breakpoint trap\0",
- "Aborted\0",
- "Bus error\0",
- "Arithmetic exception\0",
- "Killed\0",
- "User defined signal 1\0",
- "Segmentation fault\0",
- "User defined signal 2\0",
- "Broken pipe\0",
- "Alarm clock\0",
- "Terminated\0",
- "Stack fault\0",
- "Child process status\0",
- "Continued\0",
- "Stopped (signal)\0",
- "Stopped\0",
- "Stopped (tty input)\0",
- "Stopped (tty output)\0",
- "Urgent I/O condition\0",
- "CPU time limit exceeded\0",
- "File size limit exceeded\0",
- "Virtual timer expired\0",
- "Profiling timer expired\0",
- "Window changed\0",
- "I/O possible\0",
- "Power failure\0",
- "Bad system call\0",
- ];
|