Skip to content

Improvements and new syscalls #270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/mqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

use {Errno, Result};

use libc::{c_int, c_long, c_char, size_t, mode_t, strlen};
use libc::{c_int, c_long, c_char, size_t, mode_t};
use std::ffi::CString;
use sys::stat::Mode;
use std::ptr::null;
use std::mem::transmute;

pub use self::consts::*;

Expand Down Expand Up @@ -75,9 +77,12 @@ impl MqAttr {
}


#[inline]
pub fn mq_open(name: &CString, oflag: MQ_OFlag, mode: Mode, attr: &MqAttr) -> Result<MQd> {
let res = unsafe { ffi::mq_open(name.as_ptr(), oflag.bits(), mode.bits() as mode_t, attr as *const MqAttr) };
pub fn mq_open(name: &CString, oflag: MQ_OFlag, mode: Mode, attr: Option<&MqAttr>) -> Result<MQd> {
let attr_p = match attr {
None => null(),
Some(val) => val as *const MqAttr,
};
let res = unsafe { ffi::mq_open(name.as_ptr(), oflag.bits(), mode.bits() as mode_t, attr_p) };

Errno::result(res)
}
Expand All @@ -100,11 +105,10 @@ pub fn mq_receive(mqdes: MQd, message: &mut [u8], msq_prio: u32) -> Result<usize
Errno::result(res).map(|r| r as usize)
}

pub fn mq_send(mqdes: MQd, message: &CString, msq_prio: u32) -> Result<usize> {
let len = unsafe { strlen(message.as_ptr()) as size_t };
let res = unsafe { ffi::mq_send(mqdes, message.as_ptr(), len, msq_prio) };
pub fn mq_send(mqdes: MQd, message: &[u8], msq_prio: u32) -> Result<()> {
let res = unsafe { ffi::mq_send(mqdes, transmute(message.as_ptr()), message.len(), msq_prio) };

Errno::result(res).map(|r| r as usize)
Errno::result(res).map(drop)
}

pub fn mq_getattr(mqd: MQd) -> Result<MqAttr> {
Expand Down
4 changes: 4 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,7 @@ pub mod statfs;
target_arch = "arm")),
)]
pub mod statvfs;

#[cfg(any(target_os = "linux",
target_os = "android"))]
pub mod timerfd;
41 changes: 35 additions & 6 deletions src/sys/select.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::ptr::null_mut;
use std::ptr::{null, null_mut};
use std::os::unix::io::RawFd;
use libc::c_int;
use {Errno, Result};
use libc::{c_int, timespec};
use {Error, Errno, Result};
use sys::time::TimeVal;
use sys::signal::sigset_t;

pub const FD_SETSIZE: RawFd = 1024;

Expand All @@ -17,6 +18,7 @@ const BITS: usize = 32;

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
#[repr(C)]
#[derive(Clone)]
pub struct FdSet {
bits: [u64; FD_SETSIZE as usize / 64]
}
Expand Down Expand Up @@ -54,8 +56,9 @@ impl FdSet {
}

mod ffi {
use libc::c_int;
use libc::{c_int, timespec};
use sys::time::TimeVal;
use sys::signal::sigset_t;
use super::FdSet;

extern {
Expand All @@ -64,22 +67,48 @@ mod ffi {
writefds: *mut FdSet,
errorfds: *mut FdSet,
timeout: *mut TimeVal) -> c_int;

pub fn pselect(nfds: c_int,
readfds: *mut FdSet,
writefds: *mut FdSet,
errorfds: *mut FdSet,
timeout: *const timespec,
sigmask: *const sigset_t) -> c_int;
}
}

pub fn select(nfds: c_int,
readfds: Option<&mut FdSet>,
writefds: Option<&mut FdSet>,
errorfds: Option<&mut FdSet>,
timeout: &mut TimeVal) -> Result<c_int> {
timeout: Option<&mut TimeVal>) -> Result<c_int> {
let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let timeout = timeout as *mut TimeVal;
let timeout = timeout.map(|tv| tv as *mut TimeVal).unwrap_or(null_mut());

let res = unsafe {
ffi::select(nfds, readfds, writefds, errorfds, timeout)
};

Errno::result(res)
}

pub fn pselect(nfds: c_int,
readfds: Option<&mut FdSet>,
writefds: Option<&mut FdSet>,
errorfds: Option<&mut FdSet>,
timeout: Option<&timespec>,
sigmask: Option<&sigset_t>) -> Result<c_int> {
let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let timeout = timeout.map(|ts| ts as *const timespec).unwrap_or(null());
let sigmask = sigmask.map(|sm| sm as *const sigset_t).unwrap_or(null());

let res = unsafe {
ffi::pselect(nfds, readfds, writefds, errorfds, timeout, sigmask)
};

Errno::result(res)
}
21 changes: 15 additions & 6 deletions src/sys/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ mod arch {

pub type Syscall = c_long;

pub static SYSPIVOTROOT: Syscall = 155;
pub static MEMFD_CREATE: Syscall = 319;
pub const SOCKET: Syscall = 41;
pub const CONNECT: Syscall = 42;
pub const SENDMSG: Syscall = 46;
pub const RECVMSG: Syscall = 47;
pub const SYSPIVOTROOT: Syscall = 155;
pub const MEMFD_CREATE: Syscall = 319;
}

#[cfg(target_arch = "x86")]
Expand All @@ -20,8 +24,9 @@ mod arch {

pub type Syscall = c_long;

pub static SYSPIVOTROOT: Syscall = 217;
pub static MEMFD_CREATE: Syscall = 356;
pub const SOCKETCALL: Syscall = 102;
pub const SYSPIVOTROOT: Syscall = 217;
pub const MEMFD_CREATE: Syscall = 356;
}

#[cfg(target_arch = "aarch64")]
Expand All @@ -40,8 +45,12 @@ mod arch {

pub type Syscall = c_long;

pub static SYSPIVOTROOT: Syscall = 218;
pub static MEMFD_CREATE: Syscall = 385;
pub const SYSPIVOTROOT: Syscall = 218;
pub const SOCKET: Syscall = 281;
pub const CONNECT: Syscall = 283;
pub const SENDMSG: Syscall = 296;
pub const RECVMSG: Syscall = 297;
pub const MEMFD_CREATE: Syscall = 385;
}


Expand Down
71 changes: 71 additions & 0 deletions src/sys/timerfd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use Result;
use errno::Errno;
use libc::{CLOCK_REALTIME, CLOCK_MONOTONIC, c_int};
use std::os::unix::io::RawFd;
use std::ptr::null_mut;
use std::mem::uninitialized;

pub use libc::timespec;

pub enum ClockId {
Realtime = CLOCK_REALTIME as isize,
Monotonic = CLOCK_MONOTONIC as isize,
}

bitflags! {
flags TfFlag: c_int {
const TFD_NONBLOCK = 0o00004000,
const TFD_CLOEXEC = 0o02000000,
}
}

bitflags! {
flags TfTimerFlag: c_int {
const TFD_TIMER_ABSTIME = 1,
}
}

mod ffi {
use libc::{c_int, timespec};

#[repr(C)]
#[derive(Clone)]
pub struct ITimerSpec {
pub it_interval: timespec,
pub it_value: timespec,
}

extern {

pub fn timerfd_create(clockid: c_int, flags: c_int) -> c_int;

pub fn timerfd_settime(fd: c_int, flags: c_int, new_value: *const ITimerSpec, old_value: *mut ITimerSpec) -> c_int;

pub fn timerfd_gettime(fd: c_int, curr_value: *mut ITimerSpec) -> c_int;
}
}

pub use self::ffi::ITimerSpec;

pub fn timerfd_create(clockid: ClockId, flags: TfFlag) -> Result<RawFd> {
let fd = unsafe { ffi::timerfd_create(clockid as c_int, flags.bits() as c_int) };

Errno::result(fd)
}

pub fn timerfd_settime(fd: RawFd, flags: TfTimerFlag, new_value: &ITimerSpec, old_value: Option<&mut ITimerSpec>) -> Result<()> {
let res = unsafe { ffi::timerfd_settime(fd as c_int,
flags.bits() as c_int,
new_value as *const ITimerSpec,
old_value.map(|x| x as *mut ITimerSpec).unwrap_or(null_mut())
) };

Errno::result(res).map(drop)
}

pub fn timerfd_gettime(fd: RawFd) -> Result<ITimerSpec> {
let mut spec = unsafe { uninitialized() };
let res = unsafe { ffi::timerfd_gettime(fd as c_int, &mut spec as *mut ITimerSpec) };

Errno::result(res).map(|_| spec)
}
19 changes: 17 additions & 2 deletions src/sys/wait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const WSTOPPED: WaitPidFlag = WUNTRACED;
pub enum WaitStatus {
Exited(pid_t, i8),
Signaled(pid_t, signal::SigNum, bool),
Stopped(pid_t, signal::SigNum),
Stopped(pid_t, signal::SigNum, c_int),
Continued(pid_t),
StillAlive
}
Expand All @@ -51,6 +51,7 @@ pub enum WaitStatus {
target_os = "android"))]
mod status {
use sys::signal;
use libc::c_int;

pub fn exited(status: i32) -> bool {
(status & 0x7F) == 0
Expand Down Expand Up @@ -80,6 +81,10 @@ mod status {
((status & 0xFF00) >> 8) as signal::SigNum
}

pub fn stop_additional(status: i32) -> c_int {
(status >> 16) as c_int
}

pub fn continued(status: i32) -> bool {
status == 0xFFFF
}
Expand All @@ -89,6 +94,7 @@ mod status {
target_os = "ios"))]
mod status {
use sys::signal;
use libc::c_int;

const WCOREFLAG: i32 = 0x80;
const WSTOPPED: i32 = 0x7f;
Expand All @@ -105,6 +111,10 @@ mod status {
(status >> 8) as signal::SigNum
}

pub fn stop_additional(status: i32) -> c_int {
0
}

pub fn continued(status: i32) -> bool {
wstatus(status) == WSTOPPED && stop_signal(status) == 0x13
}
Expand Down Expand Up @@ -136,6 +146,7 @@ mod status {
target_os = "netbsd"))]
mod status {
use sys::signal;
use libc::c_int;

const WCOREFLAG: i32 = 0x80;
const WSTOPPED: i32 = 0x7f;
Expand All @@ -152,6 +163,10 @@ mod status {
(status >> 8) as signal::SigNum
}

pub fn stop_additional(status: i32) -> c_int {
0
}

pub fn signaled(status: i32) -> bool {
wstatus(status) != WSTOPPED && wstatus(status) != 0 && status != 0x13
}
Expand Down Expand Up @@ -183,7 +198,7 @@ fn decode(pid : pid_t, status: i32) -> WaitStatus {
} else if status::signaled(status) {
WaitStatus::Signaled(pid, status::term_signal(status), status::dumped_core(status))
} else if status::stopped(status) {
WaitStatus::Stopped(pid, status::stop_signal(status))
WaitStatus::Stopped(pid, status::stop_signal(status), status::stop_additional(status))
} else {
assert!(status::continued(status));
WaitStatus::Continued(pid)
Expand Down
27 changes: 25 additions & 2 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use self::linux::*;

mod ffi {
use libc::{c_char, c_int, size_t};
pub use libc::{fork, close, read, write, pipe, ftruncate, unlink, setpgid, getegid, geteuid, getgid, getpid, getppid, getuid};
pub use libc::{fork, close, read, write, pipe, ftruncate, unlink, setpgid, getegid, geteuid, getgid, getpid, getppid, getuid, setuid, setgid, chown};

#[allow(improper_ctypes)]
extern {
Expand All @@ -28,7 +28,7 @@ mod ffi {

// Execute PATH with arguments ARGV and environment from `environ'.
// doc: http://man7.org/linux/man-pages/man3/execv.3.html
pub fn execv (path: *const c_char, argv: *const *const c_char) -> c_int;
pub fn execv(path: *const c_char, argv: *const *const c_char) -> c_int;

// execute program
// doc: http://man7.org/linux/man-pages/man2/execve.2.html
Expand Down Expand Up @@ -157,6 +157,15 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
Errno::result(res).map(drop)
}

#[inline]
pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
unsafe { ffi::chown(cstr.as_ptr(), owner.unwrap_or(uid_t::max_value()), group.unwrap_or(gid_t::max_value())) }
}));

Errno::result(res).map(drop)
}

fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
use std::ptr;
use libc::c_char;
Expand Down Expand Up @@ -369,6 +378,20 @@ pub fn getegid() -> gid_t {
unsafe { ffi::getegid() }
}

#[inline]
pub fn setuid(uid: uid_t) -> Result<()> {
let res = unsafe { ffi::setuid(uid) };

Errno::result(res).map(drop)
}

#[inline]
pub fn setgid(gid: gid_t) -> Result<()> {
let res = unsafe { ffi::setgid(gid) };

Errno::result(res).map(drop)
}

#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux {
use sys::syscall::{syscall, SYSPIVOTROOT};
Expand Down