diff --git a/src/sched.rs b/src/sched.rs index ce34005d76..e59b8b0549 100644 --- a/src/sched.rs +++ b/src/sched.rs @@ -1,32 +1,39 @@ use std::mem; use std::os::unix::io::RawFd; -use libc::{c_int, c_uint, c_void, c_ulong, pid_t}; +use libc::{self, c_int, c_void, c_ulong, pid_t}; use {Errno, Result}; -pub type CloneFlags = c_uint; - -pub static CLONE_VM: CloneFlags = 0x00000100; -pub static CLONE_FS: CloneFlags = 0x00000200; -pub static CLONE_FILES: CloneFlags = 0x00000400; -pub static CLONE_SIGHAND: CloneFlags = 0x00000800; -pub static CLONE_PTRACE: CloneFlags = 0x00002000; -pub static CLONE_VFORK: CloneFlags = 0x00004000; -pub static CLONE_PARENT: CloneFlags = 0x00008000; -pub static CLONE_THREAD: CloneFlags = 0x00010000; -pub static CLONE_NEWNS: CloneFlags = 0x00020000; -pub static CLONE_SYSVSEM: CloneFlags = 0x00040000; -pub static CLONE_SETTLS: CloneFlags = 0x00080000; -pub static CLONE_PARENT_SETTID: CloneFlags = 0x00100000; -pub static CLONE_CHILD_CLEARTID: CloneFlags = 0x00200000; -pub static CLONE_DETACHED: CloneFlags = 0x00400000; -pub static CLONE_UNTRACED: CloneFlags = 0x00800000; -pub static CLONE_CHILD_SETTID: CloneFlags = 0x01000000; -pub static CLONE_NEWUTS: CloneFlags = 0x04000000; -pub static CLONE_NEWIPC: CloneFlags = 0x08000000; -pub static CLONE_NEWUSER: CloneFlags = 0x10000000; -pub static CLONE_NEWPID: CloneFlags = 0x20000000; -pub static CLONE_NEWNET: CloneFlags = 0x40000000; -pub static CLONE_IO: CloneFlags = 0x80000000; +// For some functions taking with a parameter of type CloneFlags, +// only a subset of these flags have an effect. +bitflags!{ + flags CloneFlags: c_int { + const CLONE_VM = libc::CLONE_VM, + const CLONE_FS = libc::CLONE_FS, + const CLONE_FILES = libc::CLONE_FILES, + const CLONE_SIGHAND = libc::CLONE_SIGHAND, + const CLONE_PTRACE = libc::CLONE_PTRACE, + const CLONE_VFORK = libc::CLONE_VFORK, + const CLONE_PARENT = libc::CLONE_PARENT, + const CLONE_THREAD = libc::CLONE_THREAD, + const CLONE_NEWNS = libc::CLONE_NEWNS, + const CLONE_SYSVSEM = libc::CLONE_SYSVSEM, + const CLONE_SETTLS = libc::CLONE_SETTLS, + const CLONE_PARENT_SETTID = libc::CLONE_PARENT_SETTID, + const CLONE_CHILD_CLEARTID = libc::CLONE_CHILD_CLEARTID, + const CLONE_DETACHED = libc::CLONE_DETACHED, + const CLONE_UNTRACED = libc::CLONE_UNTRACED, + const CLONE_CHILD_SETTID = libc::CLONE_CHILD_SETTID, + // TODO: Once, we use a version containing + // https://github.com/rust-lang-nursery/libc/pull/147 + // get rid of the casts. + const CLONE_NEWUTS = libc::CLONE_NEWUTS as c_int, + const CLONE_NEWIPC = libc::CLONE_NEWIPC as c_int, + const CLONE_NEWUSER = libc::CLONE_NEWUSER as c_int, + const CLONE_NEWPID = libc::CLONE_NEWPID as c_int, + const CLONE_NEWNET = libc::CLONE_NEWNET as c_int, + const CLONE_IO = libc::CLONE_IO as c_int, + } +} // Support a maximum CPU set of 1024 nodes #[cfg(all(target_arch = "x86_64", target_os = "linux"))] @@ -147,17 +154,17 @@ mod ffi { pub fn clone( cb: *const CloneCb, child_stack: *mut c_void, - flags: super::CloneFlags, + flags: c_int, arg: *mut super::CloneCb, ...) -> c_int; // disassociate parts of the process execution context // doc: http://man7.org/linux/man-pages/man2/unshare.2.html - pub fn unshare(flags: super::CloneFlags) -> c_int; + pub fn unshare(flags: c_int) -> c_int; // reassociate thread with a namespace // doc: http://man7.org/linux/man-pages/man2/setns.2.html - pub fn setns(fd: c_int, nstype: super::CloneFlags) -> c_int; + pub fn setns(fd: c_int, nstype: c_int) -> c_int; // Set the current CPU set that a task is allowed to run on pub fn sched_setaffinity(__pid: pid_t, __cpusetsize: size_t, __cpuset: *const CpuSet) -> c_int; @@ -182,20 +189,20 @@ pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> Result Result<()> { - let res = unsafe { ffi::unshare(flags) }; + let res = unsafe { ffi::unshare(flags.bits()) }; Errno::result(res).map(drop) } pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> { - let res = unsafe { ffi::setns(fd, nstype) }; + let res = unsafe { ffi::setns(fd, nstype.bits()) }; Errno::result(res).map(drop) } diff --git a/src/sys/mman.rs b/src/sys/mman.rs index 7537c272e7..5ec618e877 100644 --- a/src/sys/mman.rs +++ b/src/sys/mman.rs @@ -1,44 +1,48 @@ use {Errno, Error, Result, NixPath}; use fcntl::OFlag; -use libc::{c_void, size_t, off_t, mode_t}; +use libc::{self, c_void, size_t, off_t, mode_t}; use sys::stat::Mode; use std::os::unix::io::RawFd; pub use self::consts::*; +bitflags!{ + flags ProtFlags : libc::c_int { + const PROT_NONE = libc::PROT_NONE, + const PROT_READ = libc::PROT_READ, + const PROT_WRITE = libc::PROT_WRITE, + const PROT_EXEC = libc::PROT_EXEC, + #[cfg(any(target_os = "linux", target_os = "android"))] + const PROT_GROWSDOWN = libc::PROT_GROWSDOWN, + #[cfg(any(target_os = "linux", target_os = "android"))] + const PROT_GROWSUP = libc::PROT_GROWSUP, + } +} + #[cfg(any(target_os = "linux", target_os = "android"))] mod consts { - use libc::c_int; - - pub type MmapFlag = c_int; - - pub const MAP_SHARED: MmapFlag = 0x00001; - pub const MAP_PRIVATE: MmapFlag = 0x00002; - pub const MAP_FIXED: MmapFlag = 0x00010; - - pub const MAP_FILE: MmapFlag = 0x00000; - pub const MAP_ANONYMOUS: MmapFlag = 0x00020; - pub const MAP_ANON: MmapFlag = MAP_ANONYMOUS; - pub const MAP_32BIT: MmapFlag = 0x00040; - - pub const MAP_GROWSDOWN: MmapFlag = 0x00100; - pub const MAP_DENYWRITE: MmapFlag = 0x00800; - pub const MAP_EXECUTABLE: MmapFlag = 0x01000; - pub const MAP_LOCKED: MmapFlag = 0x02000; - pub const MAP_NORESERVE: MmapFlag = 0x04000; - pub const MAP_POPULATE: MmapFlag = 0x08000; - pub const MAP_NONBLOCK: MmapFlag = 0x10000; - pub const MAP_STACK: MmapFlag = 0x20000; - pub const MAP_HUGETLB: MmapFlag = 0x40000; - - pub type MmapProt = c_int; - - pub const PROT_READ: MmapProt = 0x1; - pub const PROT_WRITE: MmapProt = 0x2; - pub const PROT_EXEC: MmapProt = 0x4; - pub const PROT_NONE: MmapProt = 0x0; - pub const PROT_GROWSDOWN: MmapProt = 0x01000000; - pub const PROT_GROWSUP: MmapProt = 0x02000000; + use libc::{self, c_int}; + + bitflags!{ + flags MapFlags: c_int { + const MAP_FILE = libc::MAP_FILE, + const MAP_SHARED = libc::MAP_SHARED, + const MAP_PRIVATE = libc::MAP_PRIVATE, + const MAP_FIXED = libc::MAP_FIXED, + const MAP_ANON = libc::MAP_ANON, + const MAP_ANONYMOUS = libc::MAP_ANON, + const MAP_32BIT = libc::MAP_32BIT, + const MAP_GROWSDOWN = libc::MAP_GROWSDOWN, + const MAP_DENYWRITE = libc::MAP_DENYWRITE, + const MAP_EXECUTABLE = libc::MAP_EXECUTABLE, + const MAP_LOCKED = libc::MAP_LOCKED, + const MAP_NORESERVE = libc::MAP_NORESERVE, + const MAP_POPULATE = libc::MAP_POPULATE, + const MAP_NONBLOCK = libc::MAP_NONBLOCK, + const MAP_STACK = libc::MAP_STACK, + const MAP_HUGETLB = libc::MAP_HUGETLB, + } + } pub type MmapAdvise = c_int; @@ -58,11 +62,14 @@ mod consts { pub const MADV_DODUMP : MmapAdvise = 17; /* Clear the MADV_DONTDUMP flag. */ pub const MADV_HWPOISON : MmapAdvise = 100; /* Poison a page for testing. */ - pub type MmapSync = c_int; - pub const MS_ASYNC : MmapSync = 1; - pub const MS_SYNC : MmapSync = 4; - pub const MS_INVALIDATE : MmapSync = 2; + bitflags!{ + flags MsFlags: c_int { + const MS_ASYNC = libc::MS_ASYNC, + const MS_INVALIDATE = libc::MS_INVALIDATE, + const MS_SYNC = libc::MS_SYNC, + } + } pub const MAP_FAILED: isize = -1; } @@ -70,23 +77,19 @@ mod consts { #[cfg(any(target_os = "macos", target_os = "ios"))] mod consts { - use libc::c_int; - - pub type MmapFlag = c_int; - - pub const MAP_SHARED: MmapFlag = 0x00001; - pub const MAP_PRIVATE: MmapFlag = 0x00002; - pub const MAP_FIXED: MmapFlag = 0x00010; - - pub const MAP_NOCACHE: MmapFlag = 0x00400; - pub const MAP_JIT: MmapFlag = 0x00800; - - pub type MmapProt = c_int; - - pub const PROT_READ: MmapProt = 0x1; - pub const PROT_WRITE: MmapProt = 0x2; - pub const PROT_EXEC: MmapProt = 0x4; - pub const PROT_NONE: MmapProt = 0x0; + use libc::{self, c_int}; + + bitflags!{ + flags MapFlags: c_int { + const MAP_FILE = libc::MAP_FILE, + const MAP_SHARED = libc::MAP_SHARED, + const MAP_PRIVATE = libc::MAP_PRIVATE, + const MAP_FIXED = libc::MAP_FIXED, + const MAP_ANON = libc::MAP_ANON, + const MAP_NOCACHE = libc::MAP_NOCACHE, + const MAP_JIT = libc::MAP_JIT, + } + } pub type MmapAdvise = c_int; @@ -101,13 +104,15 @@ mod consts { pub const MADV_FREE_REUSE : MmapAdvise = 8; /* caller wants to reuse those pages */ pub const MADV_CAN_REUSE : MmapAdvise = 9; - pub type MmapSync = c_int; - - pub const MS_ASYNC : MmapSync = 0x0001; /* [MF|SIO] return immediately */ - pub const MS_INVALIDATE : MmapSync = 0x0002; /* [MF|SIO] invalidate all cached data */ - pub const MS_SYNC : MmapSync = 0x0010; /* [MF|SIO] msync synchronously */ - pub const MS_KILLPAGES : MmapSync = 0x0004; /* invalidate pages, leave mapped */ - pub const MS_DEACTIVATE : MmapSync = 0x0008; /* deactivate pages, leave mapped */ + bitflags!{ + flags MsFlags: c_int { + const MS_ASYNC = libc::MS_ASYNC, /* [MF|SIO] return immediately */ + const MS_INVALIDATE = libc::MS_INVALIDATE, /* [MF|SIO] invalidate all cached data */ + const MS_KILLPAGES = libc::MS_KILLPAGES, /* invalidate pages, leave mapped */ + const MS_DEACTIVATE = libc::MS_DEACTIVATE, /* deactivate pages, leave mapped */ + const MS_SYNC = libc::MS_SYNC, /* [MF|SIO] msync synchronously */ + } + } pub const MAP_FAILED: isize = -1; } @@ -116,28 +121,22 @@ mod consts { mod consts { use libc::c_int; - pub type MmapFlag = c_int; - - pub const MAP_SHARED: MmapFlag = 0x00001; - pub const MAP_PRIVATE: MmapFlag = 0x00002; - pub const MAP_FIXED: MmapFlag = 0x00010; - - pub const MAP_RENAME: MmapFlag = 0x00020; - pub const MAP_NORESERVE: MmapFlag = 0x00040; - pub const MAP_HASSEMAPHORE: MmapFlag = 0x00200; - pub const MAP_STACK: MmapFlag = 0x00400; - #[cfg(target_os = "netbsd")] - pub const MAP_WIRED: MmapFlag = 0x00800; - pub const MAP_NOSYNC: MmapFlag = 0x00800; - pub const MAP_FILE: MmapFlag = 0x00000; - pub const MAP_ANON: MmapFlag = 0x01000; - - pub type MmapProt = c_int; - - pub const PROT_READ: MmapProt = 0x1; - pub const PROT_WRITE: MmapProt = 0x2; - pub const PROT_EXEC: MmapProt = 0x4; - pub const PROT_NONE: MmapProt = 0x0; + bitflags!{ + flags MapFlags: c_int { + const MAP_FILE = libc::MAP_FILE, + const MAP_SHARED = libc::MAP_SHARED, + const MAP_PRIVATE = libc::MAP_PRIVATE, + const MAP_FIXED = libc::MAP_FIXED, + const MAP_RENAME = libc::MAP_RENAME, + const MAP_NORESERVE = libc::MAP_NORESERVE, + const MAP_HASSEMAPHORE = libc::MAP_HASSEMAPHORE, + const MAP_STACK = libc::MAP_STACK, + #[cfg(target_os = "netbsd")] + const MAP_WIRED = libc::MAP_WIRED, + const MAP_NOSYNC = libc::MAP_NOSYNC, + const MAP_ANON = libc::MAP_ANON, + } + } pub type MmapAdvise = c_int; @@ -158,21 +157,21 @@ mod consts { #[cfg(target_os = "dragonfly")] pub const MADV_SETMAP : MmapAdvise = 11; /* set page table directory page for map */ - pub type MmapSync = c_int; - - pub const MS_ASYNC : MmapSync = 0x0001; /* [MF|SIO] return immediately */ - pub const MS_INVALIDATE : MmapSync = 0x0002; /* [MF|SIO] invalidate all cached data */ - #[cfg(not(target_os = "dragonfly"))] - pub const MS_SYNC : MmapSync = 0x0010; /* [MF|SIO] msync synchronously */ - #[cfg(target_os = "dragonfly")] - pub const MS_SYNC : MmapSync = 0x0000; /* [MF|SIO] msync synchronously */ - #[cfg(not(target_os = "dragonfly"))] - pub const MS_KILLPAGES : MmapSync = 0x0004; /* invalidate pages, leave mapped */ - #[cfg(not(target_os = "dragonfly"))] - pub const MS_DEACTIVATE : MmapSync = 0x0008; /* deactivate pages, leave mapped */ + bitflags!{ + flags MsFlags: c_int { + const MS_ASYNC = libc::MS_ASYNC, /* [MF|SIO] return immediately */ + const MS_INVALIDATE = libc::MS_INVALIDATE, /* [MF|SIO] invalidate all cached data */ + #[cfg(not(target_os = "dragonfly"))] + const MS_KILLPAGES = 0x0004, /* invalidate pages, leave mapped */ + #[cfg(not(target_os = "dragonfly"))] + const MS_DEACTIVATE = 0x0004, /* deactivate pages, leave mapped */ + const MS_SYNC = libc::MS_SYNC, /* [MF|SIO] msync synchronously */ + } + } pub const MAP_FAILED: isize = -1; } + mod ffi { use libc::{c_void, size_t, c_int, c_char, mode_t}; @@ -199,8 +198,8 @@ pub fn munlock(addr: *const c_void, length: size_t) -> Result<()> { /// Calls to mmap are inherently unsafe, so they must be made in an unsafe block. Typically /// a higher-level abstraction will hide the unsafe interactions with the mmap'd region. -pub fn mmap(addr: *mut c_void, length: size_t, prot: MmapProt, flags: MmapFlag, fd: RawFd, offset: off_t) -> Result<*mut c_void> { - let ret = unsafe { ffi::mmap(addr, length, prot, flags, fd, offset) }; +pub fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> { + let ret = unsafe { ffi::mmap(addr, length, prot.bits(), flags.bits(), fd, offset) }; if ret as isize == MAP_FAILED { Err(Error::Sys(Errno::last())) @@ -217,8 +216,8 @@ pub fn madvise(addr: *const c_void, length: size_t, advise: MmapAdvise) -> Resul Errno::result(unsafe { ffi::madvise(addr, length, advise) }).map(drop) } -pub fn msync(addr: *const c_void, length: size_t, flags: MmapSync) -> Result<()> { - Errno::result(unsafe { ffi::msync(addr, length, flags) }).map(drop) +pub fn msync(addr: *const c_void, length: size_t, flags: MsFlags) -> Result<()> { + Errno::result(unsafe { ffi::msync(addr, length, flags.bits()) }).map(drop) } pub fn shm_open(name: &P, flag: OFlag, mode: Mode) -> Result {