use errno::{self, Errno};
use {Error, Result, NixPath};
use fcntl::{AtFlags, at_rawfd, fcntl, FdFlag, OFlag};
use fcntl::FcntlArg::F_SETFD;
use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
uid_t, gid_t, mode_t};
use std::{fmt, mem, ptr};
use std::ffi::{CString, CStr, OsString, OsStr};
use std::os::unix::ffi::{OsStringExt, OsStrExt};
use std::os::unix::io::RawFd;
use std::path::PathBuf;
use void::Void;
use sys::stat::Mode;
#[cfg(any(target_os = "android", target_os = "linux"))]
pub use self::pivot_root::*;
#[cfg(any(target_os = "android", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
pub use self::setres::*;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Uid(uid_t);
impl Uid {
pub fn from_raw(uid: uid_t) -> Self {
Uid(uid)
}
pub fn current() -> Self {
getuid()
}
pub fn effective() -> Self {
geteuid()
}
pub fn is_root(&self) -> bool {
*self == ROOT
}
pub fn as_raw(&self) -> uid_t {
self.0
}
}
impl From<Uid> for uid_t {
fn from(uid: Uid) -> Self {
uid.0
}
}
impl fmt::Display for Uid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
pub const ROOT: Uid = Uid(0);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Gid(gid_t);
impl Gid {
pub fn from_raw(gid: gid_t) -> Self {
Gid(gid)
}
pub fn current() -> Self {
getgid()
}
pub fn effective() -> Self {
getegid()
}
pub fn as_raw(&self) -> gid_t {
self.0
}
}
impl From<Gid> for gid_t {
fn from(gid: Gid) -> Self {
gid.0
}
}
impl fmt::Display for Gid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Pid(pid_t);
impl Pid {
pub fn from_raw(pid: pid_t) -> Self {
Pid(pid)
}
pub fn this() -> Self {
getpid()
}
pub fn parent() -> Self {
getppid()
}
pub fn as_raw(&self) -> pid_t {
self.0
}
}
impl From<Pid> for pid_t {
fn from(pid: Pid) -> Self {
pid.0
}
}
impl fmt::Display for Pid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
#[derive(Clone, Copy, Debug)]
pub enum ForkResult {
Parent { child: Pid },
Child,
}
impl ForkResult {
#[inline]
pub fn is_child(&self) -> bool {
match *self {
ForkResult::Child => true,
_ => false
}
}
#[inline]
pub fn is_parent(&self) -> bool {
!self.is_child()
}
}
#[inline]
pub fn fork() -> Result<ForkResult> {
use self::ForkResult::*;
let res = unsafe { libc::fork() };
Errno::result(res).map(|res| match res {
0 => Child,
res => Parent { child: Pid(res) },
})
}
#[inline]
pub fn getpid() -> Pid {
Pid(unsafe { libc::getpid() })
}
#[inline]
pub fn getppid() -> Pid {
Pid(unsafe { libc::getppid() }) }
#[inline]
pub fn setpgid(pid: Pid, pgid: Pid) -> Result<()> {
let res = unsafe { libc::setpgid(pid.into(), pgid.into()) };
Errno::result(res).map(drop)
}
#[inline]
pub fn getpgid(pid: Option<Pid>) -> Result<Pid> {
let res = unsafe { libc::getpgid(pid.unwrap_or(Pid(0)).into()) };
Errno::result(res).map(Pid)
}
#[inline]
pub fn setsid() -> Result<Pid> {
Errno::result(unsafe { libc::setsid() }).map(Pid)
}
#[inline]
pub fn getsid(pid: Option<Pid>) -> Result<Pid> {
let res = unsafe { libc::getsid(pid.unwrap_or(Pid(0)).into()) };
Errno::result(res).map(Pid)
}
#[inline]
pub fn tcgetpgrp(fd: c_int) -> Result<Pid> {
let res = unsafe { libc::tcgetpgrp(fd) };
Errno::result(res).map(Pid)
}
#[inline]
pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> {
let res = unsafe { libc::tcsetpgrp(fd, pgrp.into()) };
Errno::result(res).map(drop)
}
#[inline]
pub fn getpgrp() -> Pid {
Pid(unsafe { libc::getpgrp() })
}
#[cfg(any(target_os = "linux", target_os = "android"))]
#[inline]
pub fn gettid() -> Pid {
Pid(unsafe { libc::syscall(libc::SYS_gettid) as pid_t })
}
#[inline]
pub fn dup(oldfd: RawFd) -> Result<RawFd> {
let res = unsafe { libc::dup(oldfd) };
Errno::result(res)
}
#[inline]
pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> {
let res = unsafe { libc::dup2(oldfd, newfd) };
Errno::result(res)
}
pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
dup3_polyfill(oldfd, newfd, flags)
}
#[inline]
fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
if oldfd == newfd {
return Err(Error::Sys(Errno::EINVAL));
}
let fd = dup2(oldfd, newfd)?;
if flags.contains(OFlag::O_CLOEXEC) {
if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) {
let _ = close(fd);
return Err(e);
}
}
Ok(fd)
}
#[inline]
pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe { libc::chdir(cstr.as_ptr()) }
})?;
Errno::result(res).map(drop)
}
#[inline]
pub fn fchdir(dirfd: RawFd) -> Result<()> {
let res = unsafe { libc::fchdir(dirfd) };
Errno::result(res).map(drop)
}
#[inline]
pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe { libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t) }
})?;
Errno::result(res).map(drop)
}
#[inline]
pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) }
})?;
Errno::result(res).map(drop)
}
pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
path1: &P1,
dirfd: Option<RawFd>,
path2: &P2) -> Result<()> {
let res =
path1.with_nix_path(|path1| {
path2.with_nix_path(|path2| {
unsafe {
libc::symlinkat(
path1.as_ptr(),
dirfd.unwrap_or(libc::AT_FDCWD),
path2.as_ptr()
)
}
})
})??;
Errno::result(res).map(drop)
}
#[inline]
pub fn getcwd() -> Result<PathBuf> {
let mut buf = Vec::with_capacity(512);
loop {
unsafe {
let ptr = buf.as_mut_ptr() as *mut c_char;
if !libc::getcwd(ptr, buf.capacity()).is_null() {
let len = CStr::from_ptr(buf.as_ptr() as *const c_char).to_bytes().len();
buf.set_len(len);
buf.shrink_to_fit();
return Ok(PathBuf::from(OsString::from_vec(buf)));
} else {
let error = Errno::last();
if error != Errno::ERANGE {
return Err(Error::Sys(error));
}
}
let cap = buf.capacity();
buf.set_len(cap);
buf.reserve(1);
}
}
}
fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (libc::uid_t, libc::gid_t) {
let uid = owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1));
let gid = group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1));
(uid, gid)
}
#[inline]
pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
let res = path.with_nix_path(|cstr| {
let (uid, gid) = chown_raw_ids(owner, group);
unsafe { libc::chown(cstr.as_ptr(), uid, gid) }
})?;
Errno::result(res).map(drop)
}
#[derive(Clone, Copy, Debug)]
pub enum FchownatFlags {
FollowSymlink,
NoFollowSymlink,
}
pub fn fchownat<P: ?Sized + NixPath>(
dirfd: Option<RawFd>,
path: &P,
owner: Option<Uid>,
group: Option<Gid>,
flag: FchownatFlags,
) -> Result<()> {
let atflag =
match flag {
FchownatFlags::FollowSymlink => AtFlags::empty(),
FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
};
let res = path.with_nix_path(|cstr| unsafe {
let (uid, gid) = chown_raw_ids(owner, group);
libc::fchownat(at_rawfd(dirfd), cstr.as_ptr(), uid, gid,
atflag.bits() as libc::c_int)
})?;
Errno::result(res).map(drop)
}
fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
args_p.push(ptr::null());
args_p
}
#[inline]
pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
let args_p = to_exec_array(argv);
unsafe {
libc::execv(path.as_ptr(), args_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
}
#[inline]
pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
unsafe {
libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
}
#[inline]
pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
let args_p = to_exec_array(args);
unsafe {
libc::execvp(filename.as_ptr(), args_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
}
#[cfg(any(target_os = "haiku",
target_os = "linux",
target_os = "openbsd"))]
pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
unsafe {
libc::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
}
#[cfg(any(target_os = "android",
target_os = "linux",
target_os = "freebsd"))]
#[inline]
pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
unsafe {
libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
pub fn execveat(dirfd: RawFd, pathname: &CString, args: &[CString],
env: &[CString], flags: super::fcntl::AtFlags) -> Result<Void> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
unsafe {
libc::syscall(libc::SYS_execveat, dirfd, pathname.as_ptr(),
args_p.as_ptr(), env_p.as_ptr(), flags);
};
Err(Error::Sys(Errno::last()))
}
#[cfg_attr(any(target_os = "macos", target_os = "ios"), deprecated(
since="0.14.0",
note="Deprecated in MacOSX 10.5"
))]
#[cfg_attr(any(target_os = "macos", target_os = "ios"), allow(deprecated))]
pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
Errno::result(res).map(drop)
}
pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
cfg_if! {
if #[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos", ))] {
type sethostname_len_t = c_int;
} else {
type sethostname_len_t = size_t;
}
}
let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
let len = name.as_ref().len() as sethostname_len_t;
let res = unsafe { libc::sethostname(ptr, len) };
Errno::result(res).map(drop)
}
pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> {
let ptr = buffer.as_mut_ptr() as *mut c_char;
let len = buffer.len() as size_t;
let res = unsafe { libc::gethostname(ptr, len) };
Errno::result(res).map(|_| {
buffer[len - 1] = 0; unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) }
})
}
pub fn close(fd: RawFd) -> Result<()> {
let res = unsafe { libc::close(fd) };
Errno::result(res).map(drop)
}
pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize> {
let res = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
Errno::result(res).map(|r| r as usize)
}
pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
let res = unsafe { libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
Errno::result(res).map(|r| r as usize)
}
#[repr(i32)]
#[derive(Clone, Copy, Debug)]
pub enum Whence {
SeekSet = libc::SEEK_SET,
SeekCur = libc::SEEK_CUR,
SeekEnd = libc::SEEK_END,
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
all(target_os = "linux", not(any(target_env = "musl",
target_arch = "mips",
target_arch = "mips64")))))]
SeekData = libc::SEEK_DATA,
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
all(target_os = "linux", not(any(target_env = "musl",
target_arch = "mips",
target_arch = "mips64")))))]
SeekHole = libc::SEEK_HOLE
}
pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result<off_t> {
let res = unsafe { libc::lseek(fd, offset, whence as i32) };
Errno::result(res).map(|r| r as off_t)
}
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result<libc::off64_t> {
let res = unsafe { libc::lseek64(fd, offset, whence as i32) };
Errno::result(res).map(|r| r as libc::off64_t)
}
pub fn pipe() -> Result<(RawFd, RawFd)> {
unsafe {
let mut fds: [c_int; 2] = mem::uninitialized();
let res = libc::pipe(fds.as_mut_ptr());
Errno::result(res)?;
Ok((fds[0], fds[1]))
}
}
#[cfg(any(target_os = "android",
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd"))]
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
let res = unsafe { libc::pipe2(fds.as_mut_ptr(), flags.bits()) };
Errno::result(res)?;
Ok((fds[0], fds[1]))
}
#[cfg(any(target_os = "ios", target_os = "macos"))]
#[deprecated(
since="0.10.0",
note="pipe2(2) is not actually atomic on these platforms. Use pipe(2) and fcntl(2) instead"
)]
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
let res = unsafe { libc::pipe(fds.as_mut_ptr()) };
Errno::result(res)?;
pipe2_setflags(fds[0], fds[1], flags)?;
Ok((fds[0], fds[1]))
}
#[cfg(any(target_os = "ios", target_os = "macos"))]
fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
use fcntl::FcntlArg::F_SETFL;
let mut res = Ok(0);
if flags.contains(OFlag::O_CLOEXEC) {
res = res
.and_then(|_| fcntl(fd1, F_SETFD(FdFlag::FD_CLOEXEC)))
.and_then(|_| fcntl(fd2, F_SETFD(FdFlag::FD_CLOEXEC)));
}
if flags.contains(OFlag::O_NONBLOCK) {
res = res
.and_then(|_| fcntl(fd1, F_SETFL(OFlag::O_NONBLOCK)))
.and_then(|_| fcntl(fd2, F_SETFL(OFlag::O_NONBLOCK)));
}
match res {
Ok(_) => Ok(()),
Err(e) => {
let _ = close(fd1);
let _ = close(fd2);
Err(e)
}
}
}
pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe {
libc::truncate(cstr.as_ptr(), len)
}
})?;
Errno::result(res).map(drop)
}
pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
}
pub fn isatty(fd: RawFd) -> Result<bool> {
unsafe {
if libc::isatty(fd) == 1 {
Ok(true)
} else {
match Errno::last() {
Errno::ENOTTY => Ok(false),
err => Err(Error::Sys(err)),
}
}
}
}
pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe {
libc::unlink(cstr.as_ptr())
}
})?;
Errno::result(res).map(drop)
}
#[inline]
pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe { libc::chroot(cstr.as_ptr()) }
})?;
Errno::result(res).map(drop)
}
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd"
))]
pub fn sync() -> () {
unsafe { libc::sync() };
}
#[inline]
pub fn fsync(fd: RawFd) -> Result<()> {
let res = unsafe { libc::fsync(fd) };
Errno::result(res).map(drop)
}
#[cfg(any(target_os = "linux",
target_os = "android",
target_os = "emscripten"))]
#[inline]
pub fn fdatasync(fd: RawFd) -> Result<()> {
let res = unsafe { libc::fdatasync(fd) };
Errno::result(res).map(drop)
}
#[inline]
pub fn getuid() -> Uid {
Uid(unsafe { libc::getuid() })
}
#[inline]
pub fn geteuid() -> Uid {
Uid(unsafe { libc::geteuid() })
}
#[inline]
pub fn getgid() -> Gid {
Gid(unsafe { libc::getgid() })
}
#[inline]
pub fn getegid() -> Gid {
Gid(unsafe { libc::getegid() })
}
#[inline]
pub fn seteuid(euid: Uid) -> Result<()> {
let res = unsafe { libc::seteuid(euid.into()) };
Errno::result(res).map(drop)
}
#[inline]
pub fn setegid(egid: Gid) -> Result<()> {
let res = unsafe { libc::setegid(egid.into()) };
Errno::result(res).map(drop)
}
#[inline]
pub fn setuid(uid: Uid) -> Result<()> {
let res = unsafe { libc::setuid(uid.into()) };
Errno::result(res).map(drop)
}
#[inline]
pub fn setgid(gid: Gid) -> Result<()> {
let res = unsafe { libc::setgid(gid.into()) };
Errno::result(res).map(drop)
}
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
pub fn getgroups() -> Result<Vec<Gid>> {
let ret = unsafe { libc::getgroups(0, ptr::null_mut()) };
let mut groups = Vec::<Gid>::with_capacity(Errno::result(ret)? as usize);
loop {
let ret = unsafe {
libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t)
};
match Errno::result(ret) {
Ok(s) => {
unsafe { groups.set_len(s as usize) };
return Ok(groups);
},
Err(Error::Sys(Errno::EINVAL)) => {
let cap = groups.capacity();
unsafe { groups.set_len(cap) };
groups.reserve(1);
},
Err(e) => return Err(e)
}
}
}
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
pub fn setgroups(groups: &[Gid]) -> Result<()> {
cfg_if! {
if #[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"))] {
type setgroups_ngroups_t = c_int;
} else {
type setgroups_ngroups_t = size_t;
}
}
let res = unsafe {
libc::setgroups(groups.len() as setgroups_ngroups_t, groups.as_ptr() as *const gid_t)
};
Errno::result(res).map(drop)
}
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
Ok(Some(n)) => n as c_int,
Ok(None) | Err(_) => <c_int>::max_value(),
};
use std::cmp::min;
let mut ngroups = min(ngroups_max, 8);
let mut groups = Vec::<Gid>::with_capacity(ngroups as usize);
cfg_if! {
if #[cfg(any(target_os = "ios", target_os = "macos"))] {
type getgrouplist_group_t = c_int;
} else {
type getgrouplist_group_t = gid_t;
}
}
let gid: gid_t = group.into();
loop {
let ret = unsafe {
libc::getgrouplist(user.as_ptr(),
gid as getgrouplist_group_t,
groups.as_mut_ptr() as *mut getgrouplist_group_t,
&mut ngroups)
};
if ret >= 0 {
unsafe { groups.set_len(ngroups as usize) };
return Ok(groups);
} else if ret == -1 {
let cap = groups.capacity();
if cap >= ngroups_max as usize {
return Err(Error::invalid_argument());
}
groups.reserve(ngroups as usize);
ngroups = min(ngroups_max, groups.capacity() as c_int);
}
}
}
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
cfg_if! {
if #[cfg(any(target_os = "ios", target_os = "macos"))] {
type initgroups_group_t = c_int;
} else {
type initgroups_group_t = gid_t;
}
}
let gid: gid_t = group.into();
let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
Errno::result(res).map(drop)
}
#[inline]
pub fn pause() {
unsafe { libc::pause() };
}
pub mod alarm {
use libc;
pub fn set(secs: libc::c_uint) -> Option<libc::c_uint> {
assert!(secs != 0, "passing 0 to `alarm::set` is not allowed, to cancel an alarm use `alarm::cancel`");
alarm(secs)
}
pub fn cancel() -> Option<libc::c_uint> {
alarm(0)
}
fn alarm(secs: libc::c_uint) -> Option<libc::c_uint> {
match unsafe { libc::alarm(secs) } {
0 => None,
secs => Some(secs),
}
}
}
#[inline]
pub fn sleep(seconds: c_uint) -> c_uint {
unsafe { libc::sleep(seconds) }
}
pub mod acct {
use libc;
use {Result, NixPath};
use errno::Errno;
use std::ptr;
pub fn enable<P: ?Sized + NixPath>(filename: &P) -> Result<()> {
let res = filename.with_nix_path(|cstr| {
unsafe { libc::acct(cstr.as_ptr()) }
})?;
Errno::result(res).map(drop)
}
pub fn disable() -> Result<()> {
let res = unsafe { libc::acct(ptr::null()) };
Errno::result(res).map(drop)
}
}
#[inline]
pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
let mut path = template.with_nix_path(|path| {path.to_bytes_with_nul().to_owned()})?;
let p = path.as_mut_ptr() as *mut _;
let fd = unsafe { libc::mkstemp(p) };
let last = path.pop(); debug_assert!(last == Some(b'\0'));
let pathname = OsString::from_vec(path);
Errno::result(fd)?;
Ok((fd, PathBuf::from(pathname)))
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(i32)]
pub enum PathconfVar {
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
target_os = "netbsd", target_os = "openbsd"))]
FILESIZEBITS = libc::_PC_FILESIZEBITS,
LINK_MAX = libc::_PC_LINK_MAX,
MAX_CANON = libc::_PC_MAX_CANON,
MAX_INPUT = libc::_PC_MAX_INPUT,
NAME_MAX = libc::_PC_NAME_MAX,
PATH_MAX = libc::_PC_PATH_MAX,
PIPE_BUF = libc::_PC_PIPE_BUF,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux",
target_os = "netbsd", target_os = "openbsd"))]
POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
SYMLINK_MAX = libc::_PC_SYMLINK_MAX,
_POSIX_CHOWN_RESTRICTED = libc::_PC_CHOWN_RESTRICTED,
_POSIX_NO_TRUNC = libc::_PC_NO_TRUNC,
_POSIX_VDISABLE = libc::_PC_VDISABLE,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
_POSIX_ASYNC_IO = libc::_PC_ASYNC_IO,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
_POSIX_PRIO_IO = libc::_PC_PRIO_IO,
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
_POSIX_SYNC_IO = libc::_PC_SYNC_IO,
#[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
_POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION
}
pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result<Option<c_long>> {
let raw = unsafe {
Errno::clear();
libc::fpathconf(fd, var as c_int)
};
if raw == -1 {
if errno::errno() == 0 {
Ok(None)
} else {
Err(Error::Sys(Errno::last()))
}
} else {
Ok(Some(raw))
}
}
pub fn pathconf<P: ?Sized + NixPath>(path: &P, var: PathconfVar) -> Result<Option<c_long>> {
let raw = path.with_nix_path(|cstr| {
unsafe {
Errno::clear();
libc::pathconf(cstr.as_ptr(), var as c_int)
}
})?;
if raw == -1 {
if errno::errno() == 0 {
Ok(None)
} else {
Err(Error::Sys(Errno::last()))
}
} else {
Ok(Some(raw))
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(i32)]
pub enum SysconfVar {
AIO_LISTIO_MAX = libc::_SC_AIO_LISTIO_MAX,
AIO_MAX = libc::_SC_AIO_MAX,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
AIO_PRIO_DELTA_MAX = libc::_SC_AIO_PRIO_DELTA_MAX,
ARG_MAX = libc::_SC_ARG_MAX,
ATEXIT_MAX = libc::_SC_ATEXIT_MAX,
BC_BASE_MAX = libc::_SC_BC_BASE_MAX,
BC_DIM_MAX = libc::_SC_BC_DIM_MAX,
BC_SCALE_MAX = libc::_SC_BC_SCALE_MAX,
BC_STRING_MAX = libc::_SC_BC_STRING_MAX,
CHILD_MAX = libc::_SC_CHILD_MAX,
COLL_WEIGHTS_MAX = libc::_SC_COLL_WEIGHTS_MAX,
DELAYTIMER_MAX = libc::_SC_DELAYTIMER_MAX,
EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
HOST_NAME_MAX = libc::_SC_HOST_NAME_MAX,
IOV_MAX = libc::_SC_IOV_MAX,
LINE_MAX = libc::_SC_LINE_MAX,
LOGIN_NAME_MAX = libc::_SC_LOGIN_NAME_MAX,
NGROUPS_MAX = libc::_SC_NGROUPS_MAX,
GETGR_R_SIZE_MAX = libc::_SC_GETGR_R_SIZE_MAX,
GETPW_R_SIZE_MAX = libc::_SC_GETPW_R_SIZE_MAX,
MQ_OPEN_MAX = libc::_SC_MQ_OPEN_MAX,
MQ_PRIO_MAX = libc::_SC_MQ_PRIO_MAX,
OPEN_MAX = libc::_SC_OPEN_MAX,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_BARRIERS = libc::_SC_BARRIERS,
_POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_CPUTIME = libc::_SC_CPUTIME,
_POSIX_FSYNC = libc::_SC_FSYNC,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_IPV6 = libc::_SC_IPV6,
_POSIX_JOB_CONTROL = libc::_SC_JOB_CONTROL,
_POSIX_MAPPED_FILES = libc::_SC_MAPPED_FILES,
_POSIX_MEMLOCK = libc::_SC_MEMLOCK,
_POSIX_MEMLOCK_RANGE = libc::_SC_MEMLOCK_RANGE,
_POSIX_MEMORY_PROTECTION = libc::_SC_MEMORY_PROTECTION,
_POSIX_MESSAGE_PASSING = libc::_SC_MESSAGE_PASSING,
_POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO,
_POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS,
#[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os = "openbsd"))]
_POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_REGEXP = libc::_SC_REGEXP,
_POSIX_SAVED_IDS = libc::_SC_SAVED_IDS,
_POSIX_SEMAPHORES = libc::_SC_SEMAPHORES,
_POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_SHELL = libc::_SC_SHELL,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_SPAWN = libc::_SC_SPAWN,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_SPIN_LOCKS = libc::_SC_SPIN_LOCKS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER,
#[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX,
_POSIX_SYNCHRONIZED_IO = libc::_SC_SYNCHRONIZED_IO,
_POSIX_THREAD_ATTR_STACKADDR = libc::_SC_THREAD_ATTR_STACKADDR,
_POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE,
#[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
target_os="netbsd", target_os="openbsd"))]
_POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME,
_POSIX_THREAD_PRIO_INHERIT = libc::_SC_THREAD_PRIO_INHERIT,
_POSIX_THREAD_PRIO_PROTECT = libc::_SC_THREAD_PRIO_PROTECT,
_POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED,
#[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
_POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT,
#[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
_POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT,
_POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER,
_POSIX_THREADS = libc::_SC_THREADS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_TIMEOUTS = libc::_SC_TIMEOUTS,
_POSIX_TIMERS = libc::_SC_TIMERS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_TRACE = libc::_SC_TRACE,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER,
#[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_POSIX_TRACE_EVENT_NAME_MAX = libc::_SC_TRACE_EVENT_NAME_MAX,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_TRACE_INHERIT = libc::_SC_TRACE_INHERIT,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_TRACE_LOG = libc::_SC_TRACE_LOG,
#[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX,
#[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX,
#[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_POSIX_TRACE_USER_EVENT_MAX = libc::_SC_TRACE_USER_EVENT_MAX,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS,
_POSIX_VERSION = libc::_SC_VERSION,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_V6_ILP32_OFF32 = libc::_SC_V6_ILP32_OFF32,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_V6_ILP32_OFFBIG = libc::_SC_V6_ILP32_OFFBIG,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_V6_LP64_OFF64 = libc::_SC_V6_LP64_OFF64,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX_V6_LPBIG_OFFBIG = libc::_SC_V6_LPBIG_OFFBIG,
_POSIX2_C_BIND = libc::_SC_2_C_BIND,
_POSIX2_C_DEV = libc::_SC_2_C_DEV,
_POSIX2_CHAR_TERM = libc::_SC_2_CHAR_TERM,
_POSIX2_FORT_DEV = libc::_SC_2_FORT_DEV,
_POSIX2_FORT_RUN = libc::_SC_2_FORT_RUN,
_POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX2_PBS = libc::_SC_2_PBS,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX2_PBS_ACCOUNTING = libc::_SC_2_PBS_ACCOUNTING,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX2_PBS_CHECKPOINT = libc::_SC_2_PBS_CHECKPOINT,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX2_PBS_LOCATE = libc::_SC_2_PBS_LOCATE,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX2_PBS_MESSAGE = libc::_SC_2_PBS_MESSAGE,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
_POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK,
_POSIX2_SW_DEV = libc::_SC_2_SW_DEV,
_POSIX2_UPE = libc::_SC_2_UPE,
_POSIX2_VERSION = libc::_SC_2_VERSION,
PAGE_SIZE = libc::_SC_PAGE_SIZE,
PTHREAD_DESTRUCTOR_ITERATIONS = libc::_SC_THREAD_DESTRUCTOR_ITERATIONS,
PTHREAD_KEYS_MAX = libc::_SC_THREAD_KEYS_MAX,
PTHREAD_STACK_MIN = libc::_SC_THREAD_STACK_MIN,
PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX,
RE_DUP_MAX = libc::_SC_RE_DUP_MAX,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
RTSIG_MAX = libc::_SC_RTSIG_MAX,
SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
SEM_VALUE_MAX = libc::_SC_SEM_VALUE_MAX,
#[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os = "openbsd"))]
SIGQUEUE_MAX = libc::_SC_SIGQUEUE_MAX,
STREAM_MAX = libc::_SC_STREAM_MAX,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="netbsd",
target_os="openbsd"))]
SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX,
TIMER_MAX = libc::_SC_TIMER_MAX,
TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX,
TZNAME_MAX = libc::_SC_TZNAME_MAX,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_CRYPT = libc::_SC_XOPEN_CRYPT,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_ENH_I18N = libc::_SC_XOPEN_ENH_I18N,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_LEGACY = libc::_SC_XOPEN_LEGACY,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_REALTIME = libc::_SC_XOPEN_REALTIME,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS,
_XOPEN_SHM = libc::_SC_XOPEN_SHM,
#[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
target_os="linux", target_os = "macos", target_os="openbsd"))]
_XOPEN_STREAMS = libc::_SC_XOPEN_STREAMS,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_UNIX = libc::_SC_XOPEN_UNIX,
#[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
target_os = "ios", target_os="linux", target_os = "macos",
target_os="openbsd"))]
_XOPEN_VERSION = libc::_SC_XOPEN_VERSION,
}
pub fn sysconf(var: SysconfVar) -> Result<Option<c_long>> {
let raw = unsafe {
Errno::clear();
libc::sysconf(var as c_int)
};
if raw == -1 {
if errno::errno() == 0 {
Ok(None)
} else {
Err(Error::Sys(Errno::last()))
}
} else {
Ok(Some(raw))
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
mod pivot_root {
use libc;
use {Result, NixPath};
use errno::Errno;
pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
new_root: &P1, put_old: &P2) -> Result<()> {
let res = new_root.with_nix_path(|new_root| {
put_old.with_nix_path(|put_old| {
unsafe {
libc::syscall(libc::SYS_pivot_root, new_root.as_ptr(), put_old.as_ptr())
}
})
})??;
Errno::result(res).map(drop)
}
}
#[cfg(any(target_os = "android", target_os = "freebsd",
target_os = "linux", target_os = "openbsd"))]
mod setres {
use libc;
use Result;
use errno::Errno;
use super::{Uid, Gid};
#[inline]
pub fn setresuid(ruid: Uid, euid: Uid, suid: Uid) -> Result<()> {
let res = unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
Errno::result(res).map(drop)
}
#[inline]
pub fn setresgid(rgid: Gid, egid: Gid, sgid: Gid) -> Result<()> {
let res = unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
Errno::result(res).map(drop)
}
}
libc_bitflags!{
pub struct AccessFlags : c_int {
F_OK;
R_OK;
W_OK;
X_OK;
}
}
pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
let res = path.with_nix_path(|cstr| {
unsafe {
libc::access(cstr.as_ptr(), amode.bits)
}
})?;
Errno::result(res).map(drop)
}