Enable getitimer, setitimer, and sigprocmask

parent 5cb92284
Pipeline #2344 passed with stages
in 15 minutes and 44 seconds
......@@ -176,7 +176,7 @@ dependencies = [
name = "ralloc_shim"
version = "0.1.1"
dependencies = [
"redox_syscall 0.1.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.49 (registry+https://github.com/rust-lang/crates.io-index)",
"sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -213,7 +213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_syscall"
version = "0.1.45"
version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -221,7 +221,7 @@ name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.49 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -236,7 +236,7 @@ dependencies = [
"posix-regex 0.1.0",
"ralloc 1.0.0",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.49 (registry+https://github.com/rust-lang/crates.io-index)",
"sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"va_list 0.1.0",
......@@ -371,7 +371,7 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.49 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -472,7 +472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum redox_syscall 0.1.45 (registry+https://github.com/rust-lang/crates.io-index)" = "7b7aac97a11cf928b13c97f726b1bfe8542969fcbc39007ce566a888da5964a3"
"checksum redox_syscall 0.1.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f22c50afdcf3f0a31ebb6b47697f6a7c5e5a24967e842858118bce0615f0afad"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
......
......@@ -30,14 +30,9 @@ pub const SIG_SETMASK: c_int = 2;
#[repr(C)]
#[derive(Clone)]
pub struct sigaction {
// I don't actually want these to be optional. They can have more than just
// one invalid value. But because of rust's non-null optimization, this
// causes Some(sigaction) with a null sa_handler to become None. Maybe
// these should be usizes and transmuted when needed... However, then I
// couldn't let cbindgen do its job.
pub sa_handler: Option<extern "C" fn(c_int)>,
pub sa_handler: extern "C" fn(c_int),
pub sa_flags: c_ulong,
pub sa_restorer: Option<unsafe extern "C" fn()>,
pub sa_restorer: unsafe extern "C" fn(),
pub sa_mask: sigset_t,
}
......@@ -150,12 +145,12 @@ extern "C" {
#[no_mangle]
pub extern "C" fn signal(
sig: c_int,
func: Option<extern "C" fn(c_int)>,
) -> Option<extern "C" fn(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: Some(__restore_rt),
sa_restorer: __restore_rt,
sa_mask: sigset_t::default(),
};
let mut old_sa = unsafe { mem::uninitialized() };
......@@ -176,10 +171,10 @@ 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 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 {
......
......@@ -3,7 +3,7 @@
use c_str::CStr;
use header::time::timespec;
use platform::types::*;
use platform::{Pal, Sys};
use platform::{Pal, PalSignal, Sys};
pub const ITIMER_REAL: c_int = 0;
pub const ITIMER_VIRTUAL: c_int = 1;
......@@ -34,19 +34,19 @@ pub struct fd_set {
pub fds_bits: [c_long; 16usize],
}
// #[no_mangle]
// pub extern "C" fn getitimer(which: c_int, value: *mut itimerval) -> c_int {
// Sys::getitimer(which, value)
// }
#[no_mangle]
pub extern "C" fn getitimer(which: c_int, value: *mut itimerval) -> c_int {
Sys::getitimer(which, value)
}
// #[no_mangle]
// pub extern "C" fn setitimer(
// which: c_int,
// value: *const itimerval,
// ovalue: *mut itimerval,
// ) -> c_int {
// Sys::setitimer(which, value, ovalue)
// }
#[no_mangle]
pub extern "C" fn setitimer(
which: c_int,
value: *const itimerval,
ovalue: *mut itimerval,
) -> c_int {
Sys::setitimer(which, value, ovalue)
}
#[no_mangle]
pub extern "C" fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
......
......@@ -6,6 +6,7 @@ use c_str::CStr;
use header::errno;
use header::limits;
use header::stdlib::getenv;
use header::sys_time;
use header::time::timespec;
use platform;
use platform::types::*;
......@@ -50,25 +51,24 @@ pub unsafe extern "C" fn access(path: *const c_char, mode: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn alarm(seconds: c_uint) -> c_uint {
// let mut timer = sys_time::itimerval {
// it_value: sys_time::timeval {
// tv_sec: seconds as time_t,
// tv_usec: 0,
// },
// ..Default::default()
// };
// let errno_backup = unsafe { platform::errno };
// let secs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
// 0
// } else {
// timer.it_value.tv_sec as c_uint + if timer.it_value.tv_usec > 0 { 1 } else { 0 }
// };
// unsafe {
// platform::errno = errno_backup;
// }
//
// secs
0
let mut timer = sys_time::itimerval {
it_value: sys_time::timeval {
tv_sec: seconds as time_t,
tv_usec: 0,
},
..Default::default()
};
let errno_backup = unsafe { platform::errno };
let secs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
0
} else {
timer.it_value.tv_sec as c_uint + if timer.it_value.tv_usec > 0 { 1 } else { 0 }
};
unsafe {
platform::errno = errno_backup;
}
secs
}
#[no_mangle]
......@@ -582,30 +582,30 @@ pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t)
unimplemented!();
}
// #[no_mangle]
// pub extern "C" fn ualarm(value: useconds_t, interval: useconds_t) -> useconds_t {
// let mut timer = sys_time::itimerval {
// it_value: sys_time::timeval {
// tv_sec: 0,
// tv_usec: value as suseconds_t,
// },
// it_interval: sys_time::timeval {
// tv_sec: 0,
// tv_usec: interval as suseconds_t,
// },
// };
// let errno_backup = unsafe { platform::errno };
// let usecs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
// 0
// } else {
// timer.it_value.tv_sec as useconds_t * 1_000_000 + timer.it_value.tv_usec as useconds_t
// };
// unsafe {
// platform::errno = errno_backup;
// }
//
// usecs
// }
#[no_mangle]
pub extern "C" fn ualarm(value: useconds_t, interval: useconds_t) -> useconds_t {
let mut timer = sys_time::itimerval {
it_value: sys_time::timeval {
tv_sec: 0,
tv_usec: value as suseconds_t,
},
it_interval: sys_time::timeval {
tv_sec: 0,
tv_usec: interval as suseconds_t,
},
};
let errno_backup = unsafe { platform::errno };
let usecs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
0
} else {
timer.it_value.tv_sec as useconds_t * 1_000_000 + timer.it_value.tv_usec as useconds_t
};
unsafe {
platform::errno = errno_backup;
}
usecs
}
#[no_mangle]
pub unsafe extern "C" fn unlink(path: *const c_char) -> c_int {
......
......@@ -15,7 +15,7 @@ use header::sys_ioctl::{winsize, TCGETS, TCSETS, TIOCGWINSZ};
use header::sys_select::fd_set;
use header::sys_stat::stat;
use header::sys_statvfs::statvfs;
use header::sys_time::{itimerval, timeval, timezone};
use header::sys_time::{timeval, timezone};
// use header::sys_times::tms;
use header::sys_utsname::utsname;
use header::termios::termios;
......@@ -59,9 +59,6 @@ fn e(sys: usize) -> usize {
pub struct Sys;
impl Sys {
fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
e(unsafe { syscall!(GETITIMER, which, out) }) as c_int
}
// fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
// e(unsafe { syscall!(GETRUSAGE, who, r_usage) }) as c_int
......@@ -72,10 +69,6 @@ impl Sys {
e(unsafe { syscall!(IOCTL, fd, request, out) }) as c_int
}
fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int
}
// fn times(out: *mut tms) -> clock_t {
// unsafe { syscall!(TIMES, out) as clock_t }
// }
......
......@@ -4,14 +4,13 @@ use super::super::types::*;
use super::super::PalSignal;
use super::{e, Sys};
use header::signal::{sigaction, sigset_t};
use header::sys_time::itimerval;
impl Sys {
fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
e(unsafe { syscall!(RT_SIGPROCMASK, how, set, oset, mem::size_of::<sigset_t>()) }) as c_int
impl PalSignal for Sys {
fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
e(unsafe { syscall!(GETITIMER, which, out) }) as c_int
}
}
impl PalSignal for Sys {
fn kill(pid: pid_t, sig: c_int) -> c_int {
e(unsafe { syscall!(KILL, pid, sig) }) as c_int
}
......@@ -29,6 +28,10 @@ impl PalSignal for Sys {
}
}
fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int
}
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
e(syscall!(
RT_SIGACTION,
......@@ -38,4 +41,8 @@ impl PalSignal for Sys {
mem::size_of::<sigset_t>()
)) as c_int
}
fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
e(unsafe { syscall!(RT_SIGPROCMASK, how, set, oset, mem::size_of::<sigset_t>()) }) as c_int
}
}
use super::super::types::*;
use super::super::Pal;
use header::signal::sigaction;
use header::signal::{sigaction, sigset_t};
use header::sys_time::itimerval;
pub trait PalSignal: Pal {
fn getitimer(which: c_int, out: *mut itimerval) -> c_int;
fn kill(pid: pid_t, sig: c_int) -> c_int;
fn killpg(pgrp: pid_t, sig: c_int) -> c_int;
fn raise(sig: c_int) -> c_int;
fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int;
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int;
fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int;
}
use core::mem;
use syscall;
use platform::errno;
use super::super::types::*;
use super::super::{Pal, PalSignal};
use super::{e, Sys};
use header::signal::sigaction;
use header::errno::EINVAL;
use header::signal::{sigaction, sigset_t};
use header::sys_time::itimerval;
#[thread_local]
static mut SIG_HANDLER: Option<extern "C" fn(c_int)> = None;
impl PalSignal for Sys {
fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
let path = match which {
ITIMER_REAL => "itimer:1",
_ => unsafe {
errno = EINVAL;
return -1;
}
};
let fd = e(syscall::open(path, syscall::O_RDONLY | syscall::O_CLOEXEC));
if fd < 0 {
return -1;
}
let mut spec = syscall::ITimerSpec::default();
let count = e(syscall::read(fd, &mut spec));
let _ = syscall::close(fd);
if count < 0 {
return -1;
}
unsafe {
(*out).it_interval.tv_sec = spec.it_interval.tv_sec;
(*out).it_interval.tv_usec = spec.it_interval.tv_nsec/1000;
(*out).it_value.tv_sec = spec.it_value.tv_sec;
(*out).it_value.tv_usec = spec.it_value.tv_nsec/1000;
}
extern "C" fn sig_handler(sig: usize) {
if let Some(ref callback) = unsafe { SIG_HANDLER } {
callback(sig as c_int);
0
}
}
impl PalSignal for Sys {
fn kill(pid: pid_t, sig: c_int) -> c_int {
e(syscall::kill(pid as usize, sig as usize)) as c_int
}
......@@ -27,37 +55,100 @@ impl PalSignal for Sys {
Self::kill(Self::getpid(), sig)
}
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
if !oact.is_null() {
// Assumes the last sigaction() call was made by relibc and not a different one
if SIG_HANDLER.is_some() {
(*oact).sa_handler = SIG_HANDLER;
fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
let path = match which {
ITIMER_REAL => "itimer:1",
_ => unsafe {
errno = EINVAL;
return -1;
}
};
let fd = e(syscall::open(path, syscall::O_RDWR | syscall::O_CLOEXEC));
if fd < 0 {
return -1;
}
let act = if act.is_null() {
let mut spec = syscall::ITimerSpec::default();
let mut count = e(syscall::read(fd, &mut spec));
if count >= 0 {
unsafe {
if ! old.is_null() {
(*old).it_interval.tv_sec = spec.it_interval.tv_sec;
(*old).it_interval.tv_usec = spec.it_interval.tv_nsec/1000;
(*old).it_value.tv_sec = spec.it_value.tv_sec;
(*old).it_value.tv_usec = spec.it_value.tv_nsec/1000;
}
spec.it_interval.tv_sec = (*new).it_interval.tv_sec;
spec.it_interval.tv_nsec = (*new).it_interval.tv_usec * 1000;
spec.it_value.tv_sec = (*new).it_value.tv_sec;
spec.it_value.tv_nsec = (*new).it_value.tv_usec * 1000;
}
count = e(syscall::write(fd, &spec));
}
let _ = syscall::close(fd);
if count < 0 {
return -1;
}
0
}
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
let new_opt = if act.is_null() {
None
} else {
SIG_HANDLER = (*act).sa_handler;
let m = (*act).sa_mask;
Some(syscall::SigAction {
sa_handler: sig_handler,
sa_mask: [0, m as u64],
sa_handler: mem::transmute((*act).sa_handler),
sa_mask: [m as u64, 0],
sa_flags: (*act).sa_flags as usize,
})
};
let mut old = syscall::SigAction::default();
let mut old_opt = if oact.is_null() {
None
} else {
Some(syscall::SigAction::default())
};
let ret = e(syscall::sigaction(
sig as usize,
act.as_ref(),
if oact.is_null() { None } else { Some(&mut old) },
new_opt.as_ref(),
old_opt.as_mut(),
)) as c_int;
if !oact.is_null() {
if let Some(old) = old_opt {
(*oact).sa_handler = mem::transmute(old.sa_handler);
let m = old.sa_mask;
(*oact).sa_mask = m[1] as c_ulong;
(*oact).sa_mask = m[0] as c_ulong;
(*oact).sa_flags = old.sa_flags as c_ulong;
}
ret
}
//fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int;
fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
let new_opt = if set.is_null() {
None
} else {
Some([unsafe { *set as u64 }, 0])
};
let mut old_opt = if oset.is_null() {
None
} else {
Some([0, 0])
};
let ret = e(syscall::sigprocmask(
how as usize,
new_opt.as_ref(),
old_opt.as_mut(),
)) as c_int;
if let Some(old) = old_opt {
unsafe { *oset = old[0] as sigset_t };
}
ret
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment