summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fcntl.rs126
-rw-r--r--src/kmod.rs8
-rw-r--r--src/poll.rs52
-rw-r--r--src/pty.rs62
-rw-r--r--src/sched.rs6
-rw-r--r--src/sys/epoll.rs64
-rw-r--r--src/sys/event.rs16
-rw-r--r--src/sys/eventfd.rs6
-rw-r--r--src/sys/inotify.rs28
-rw-r--r--src/sys/memfd.rs6
-rw-r--r--src/sys/mman.rs2
-rw-r--r--src/sys/sendfile.rs62
-rw-r--r--src/sys/signalfd.rs38
-rw-r--r--src/sys/statfs.rs2
-rw-r--r--src/sys/statvfs.rs6
-rw-r--r--src/sys/termios.rs49
-rw-r--r--src/sys/timerfd.rs44
-rw-r--r--src/sys/uio.rs28
-rw-r--r--src/unistd.rs1271
19 files changed, 1254 insertions, 622 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 65bbd4ca..1e24f603 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -193,9 +193,13 @@ feature! {
// The conversion is not identical on all operating systems.
#[allow(clippy::useless_conversion)]
-pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
- let fd = path.with_nix_path(|cstr| {
- unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
+pub fn open<P: ?Sized + NixPath>(
+ path: &P,
+ oflag: OFlag,
+ mode: Mode,
+) -> Result<RawFd> {
+ let fd = path.with_nix_path(|cstr| unsafe {
+ libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint)
})?;
Errno::result(fd)
@@ -210,8 +214,8 @@ pub fn openat<P: ?Sized + NixPath>(
oflag: OFlag,
mode: Mode,
) -> Result<RawFd> {
- let fd = path.with_nix_path(|cstr| {
- unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
+ let fd = path.with_nix_path(|cstr| unsafe {
+ libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint)
})?;
Errno::result(fd)
}
@@ -303,7 +307,10 @@ fn readlink_maybe_at<P: ?Sized + NixPath>(
})
}
-fn inner_readlink<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P) -> Result<OsString> {
+fn inner_readlink<P: ?Sized + NixPath>(
+ dirfd: Option<RawFd>,
+ path: &P,
+) -> Result<OsString> {
let mut v = Vec::with_capacity(libc::PATH_MAX as usize);
{
@@ -387,7 +394,10 @@ pub fn readlink<P: ?Sized + NixPath>(path: &P) -> Result<OsString> {
}
#[cfg(not(target_os = "redox"))]
-pub fn readlinkat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P) -> Result<OsString> {
+pub fn readlinkat<P: ?Sized + NixPath>(
+ dirfd: RawFd,
+ path: &P,
+) -> Result<OsString> {
inner_readlink(Some(dirfd), path)
}
@@ -450,9 +460,17 @@ pub enum FcntlArg<'a> {
F_OFD_SETLKW(&'a libc::flock),
#[cfg(any(target_os = "linux", target_os = "android"))]
F_OFD_GETLK(&'a mut libc::flock),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "linux",
+ target_os = "freebsd"
+ ))]
F_ADD_SEALS(SealFlag),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "linux",
+ target_os = "freebsd"
+ ))]
F_GET_SEALS,
#[cfg(any(target_os = "macos", target_os = "ios"))]
F_FULLFSYNC,
@@ -481,7 +499,9 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
let res = unsafe {
match arg {
F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd),
- F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd),
+ F_DUPFD_CLOEXEC(rawfd) => {
+ libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd)
+ }
F_GETFD => libc::fcntl(fd, libc::F_GETFD),
F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
F_GETFL => libc::fcntl(fd, libc::F_GETFL),
@@ -498,9 +518,19 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
F_OFD_SETLKW(flock) => libc::fcntl(fd, libc::F_OFD_SETLKW, flock),
#[cfg(any(target_os = "android", target_os = "linux"))]
F_OFD_GETLK(flock) => libc::fcntl(fd, libc::F_OFD_GETLK, flock),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
- F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "linux",
+ target_os = "freebsd"
+ ))]
+ F_ADD_SEALS(flag) => {
+ libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits())
+ }
+ #[cfg(any(
+ target_os = "android",
+ target_os = "linux",
+ target_os = "freebsd"
+ ))]
F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
#[cfg(any(target_os = "macos", target_os = "ios"))]
F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
@@ -535,8 +565,12 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
LockShared => libc::flock(fd, libc::LOCK_SH),
LockExclusive => libc::flock(fd, libc::LOCK_EX),
Unlock => libc::flock(fd, libc::LOCK_UN),
- LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB),
- LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB),
+ LockSharedNonblock => {
+ libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB)
+ }
+ LockExclusiveNonblock => {
+ libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB)
+ }
UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
}
};
@@ -632,12 +666,19 @@ pub fn splice(
.map(|offset| offset as *mut libc::loff_t)
.unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) };
+ let ret = unsafe {
+ libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits())
+ };
Errno::result(ret).map(|r| r as usize)
}
#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> {
+pub fn tee(
+ fd_in: RawFd,
+ fd_out: RawFd,
+ len: usize,
+ flags: SpliceFFlags,
+) -> Result<usize> {
let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
Errno::result(ret).map(|r| r as usize)
}
@@ -646,9 +687,8 @@ pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Resu
pub fn vmsplice(
fd: RawFd,
iov: &[std::io::IoSlice<'_>],
- flags: SpliceFFlags
- ) -> Result<usize>
-{
+ flags: SpliceFFlags,
+) -> Result<usize> {
let ret = unsafe {
libc::vmsplice(
fd,
@@ -778,14 +818,19 @@ impl SpacectlRange {
/// ```
#[cfg(target_os = "freebsd")]
pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result<SpacectlRange> {
- let mut rqsr = libc::spacectl_range{r_offset: range.0, r_len: range.1};
- let res = unsafe { libc::fspacectl(
+ let mut rqsr = libc::spacectl_range {
+ r_offset: range.0,
+ r_len: range.1,
+ };
+ let res = unsafe {
+ libc::fspacectl(
fd,
libc::SPACECTL_DEALLOC, // Only one command is supported ATM
&rqsr,
- 0, // No flags are currently supported
- &mut rqsr
- )};
+ 0, // No flags are currently supported
+ &mut rqsr,
+ )
+ };
Errno::result(res).map(|_| SpacectlRange(rqsr.r_offset, rqsr.r_len))
}
@@ -820,18 +865,25 @@ pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result<SpacectlRange> {
/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef");
/// ```
#[cfg(target_os = "freebsd")]
-pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t)
- -> Result<()>
-{
- let mut rqsr = libc::spacectl_range{r_offset: offset, r_len: len};
+pub fn fspacectl_all(
+ fd: RawFd,
+ offset: libc::off_t,
+ len: libc::off_t,
+) -> Result<()> {
+ let mut rqsr = libc::spacectl_range {
+ r_offset: offset,
+ r_len: len,
+ };
while rqsr.r_len > 0 {
- let res = unsafe { libc::fspacectl(
+ let res = unsafe {
+ libc::fspacectl(
fd,
libc::SPACECTL_DEALLOC, // Only one command is supported ATM
&rqsr,
- 0, // No flags are currently supported
- &mut rqsr
- )};
+ 0, // No flags are currently supported
+ &mut rqsr,
+ )
+ };
Errno::result(res)?;
}
Ok(())
@@ -848,8 +900,8 @@ pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t)
))]
mod posix_fadvise {
use crate::errno::Errno;
- use std::os::unix::io::RawFd;
use crate::Result;
+ use std::os::unix::io::RawFd;
#[cfg(feature = "fs")]
libc_enum! {
@@ -894,7 +946,11 @@ mod posix_fadvise {
target_os = "wasi",
target_os = "freebsd"
))]
-pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<()> {
+pub fn posix_fallocate(
+ fd: RawFd,
+ offset: libc::off_t,
+ len: libc::off_t,
+) -> Result<()> {
let res = unsafe { libc::posix_fallocate(fd, offset, len) };
match Errno::result(res) {
Err(err) => Err(err),
diff --git a/src/kmod.rs b/src/kmod.rs
index 1fa6c170..d3725c3f 100644
--- a/src/kmod.rs
+++ b/src/kmod.rs
@@ -3,7 +3,7 @@
//! For more details see
use std::ffi::CStr;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use crate::errno::Errno;
use crate::Result;
@@ -79,15 +79,15 @@ libc_bitflags!(
/// ```
///
/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
-pub fn finit_module<T: AsRawFd>(
- fd: &T,
+pub fn finit_module<Fd: AsFd>(
+ fd: Fd,
param_values: &CStr,
flags: ModuleInitFlags,
) -> Result<()> {
let res = unsafe {
libc::syscall(
libc::SYS_finit_module,
- fd.as_raw_fd(),
+ fd.as_fd().as_raw_fd(),
param_values.as_ptr(),
flags.bits(),
)
diff --git a/src/poll.rs b/src/poll.rs
index 6f227fee..9181bf7f 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -1,5 +1,5 @@
//! Wait for events to trigger on specific file descriptors
-use std::os::unix::io::{AsRawFd, RawFd};
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd};
use crate::errno::Errno;
use crate::Result;
@@ -14,20 +14,36 @@ use crate::Result;
/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct PollFd {
+pub struct PollFd<'fd> {
pollfd: libc::pollfd,
+ _fd: std::marker::PhantomData<BorrowedFd<'fd>>,
}
-impl PollFd {
+impl<'fd> PollFd<'fd> {
/// Creates a new `PollFd` specifying the events of interest
/// for a given file descriptor.
- pub const fn new(fd: RawFd, events: PollFlags) -> PollFd {
+ //
+ // Different from other I/O-safe interfaces, here, we have to take `AsFd`
+ // by reference to prevent the case where the `fd` is closed but it is
+ // still in use. For example:
+ //
+ // ```rust
+ // let (reader, _) = pipe().unwrap();
+ //
+ // // If `PollFd::new()` takes `AsFd` by value, then `reader` will be consumed,
+ // // but the file descriptor of `reader` will still be in use.
+ // let pollfd = PollFd::new(reader, flag);
+ //
+ // // Do something with `pollfd`, which uses the CLOSED fd.
+ // ```
+ pub fn new<Fd: AsFd>(fd: &'fd Fd, events: PollFlags) -> PollFd<'fd> {
PollFd {
pollfd: libc::pollfd {
- fd,
+ fd: fd.as_fd().as_raw_fd(),
events: events.bits(),
revents: PollFlags::empty().bits(),
},
+ _fd: std::marker::PhantomData,
}
}
@@ -68,9 +84,29 @@ impl PollFd {
}
}
-impl AsRawFd for PollFd {
- fn as_raw_fd(&self) -> RawFd {
- self.pollfd.fd
+impl<'fd> AsFd for PollFd<'fd> {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ // Safety:
+ //
+ // BorrowedFd::borrow_raw(RawFd) requires that the raw fd being passed
+ // must remain open for the duration of the returned BorrowedFd, this is
+ // guaranteed as the returned BorrowedFd has the lifetime parameter same
+ // as `self`:
+ // "fn as_fd<'self>(&'self self) -> BorrowedFd<'self>"
+ // which means that `self` (PollFd) is guaranteed to outlive the returned
+ // BorrowedFd. (Lifetime: PollFd > BorrowedFd)
+ //
+ // And the lifetime parameter of PollFd::new(fd, ...) ensures that `fd`
+ // (an owned file descriptor) must outlive the returned PollFd:
+ // "pub fn new<Fd: AsFd>(fd: &'fd Fd, events: PollFlags) -> PollFd<'fd>"
+ // (Lifetime: Owned fd > PollFd)
+ //
+ // With two above relationships, we can conclude that the `Owned file
+ // descriptor` will outlive the returned BorrowedFd,
+ // (Lifetime: Owned fd > BorrowedFd)
+ // i.e., the raw fd being passed will remain valid for the lifetime of
+ // the returned BorrowedFd.
+ unsafe { BorrowedFd::borrow_raw(self.pollfd.fd) }
}
}
diff --git a/src/pty.rs b/src/pty.rs
index 28ae5e92..2866c6df 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -16,26 +16,24 @@ use crate::{fcntl, unistd, Result};
/// Representation of a master/slave pty pair
///
-/// This is returned by `openpty`. Note that this type does *not* implement `Drop`, so the user
-/// must manually close the file descriptors.
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+/// This is returned by [`openpty`].
+#[derive(Debug)]
pub struct OpenptyResult {
/// The master port in a virtual pty pair
- pub master: RawFd,
+ pub master: OwnedFd,
/// The slave port in a virtual pty pair
- pub slave: RawFd,
+ pub slave: OwnedFd,
}
feature! {
#![feature = "process"]
/// Representation of a master with a forked pty
///
-/// This is returned by `forkpty`. Note that this type does *not* implement `Drop`, so the user
-/// must manually close the file descriptors.
-#[derive(Clone, Copy, Debug)]
+/// This is returned by [`forkpty`].
+#[derive(Debug)]
pub struct ForkptyResult {
/// The master port in a virtual pty pair
- pub master: RawFd,
+ pub master: OwnedFd,
/// Metadata about forked process
pub fork_result: ForkResult,
}
@@ -43,51 +41,33 @@ pub struct ForkptyResult {
/// Representation of the Master device in a master/slave pty pair
///
-/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
-/// functions are given the correct file descriptor. Additionally this type implements `Drop`,
-/// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct PtyMaster(RawFd);
+/// While this datatype is a thin wrapper around `OwnedFd`, it enforces that the available PTY
+/// functions are given the correct file descriptor.
+#[derive(Debug)]
+pub struct PtyMaster(OwnedFd);
impl AsRawFd for PtyMaster {
fn as_raw_fd(&self) -> RawFd {
- self.0
+ self.0.as_raw_fd()
}
}
impl IntoRawFd for PtyMaster {
fn into_raw_fd(self) -> RawFd {
let fd = self.0;
- mem::forget(self);
- fd
- }
-}
-
-impl Drop for PtyMaster {
- fn drop(&mut self) {
- // On drop, we ignore errors like EINTR and EIO because there's no clear
- // way to handle them, we can't return anything, and (on FreeBSD at
- // least) the file descriptor is deallocated in these cases. However,
- // we must panic on EBADF, because it is always an error to close an
- // invalid file descriptor. That frequently indicates a double-close
- // condition, which can cause confusing errors for future I/O
- // operations.
- let e = unistd::close(self.0);
- if e == Err(Errno::EBADF) {
- panic!("Closing an invalid file descriptor!");
- };
+ fd.into_raw_fd()
}
}
impl io::Read for PtyMaster {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- unistd::read(self.0, buf).map_err(io::Error::from)
+ unistd::read(self.0.as_raw_fd(), buf).map_err(io::Error::from)
}
}
impl io::Write for PtyMaster {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- unistd::write(self.0, buf).map_err(io::Error::from)
+ unistd::write(self.0.as_raw_fd(), buf).map_err(io::Error::from)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
@@ -96,13 +76,13 @@ impl io::Write for PtyMaster {
impl io::Read for &PtyMaster {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- unistd::read(self.0, buf).map_err(io::Error::from)
+ unistd::read(self.0.as_raw_fd(), buf).map_err(io::Error::from)
}
}
impl io::Write for &PtyMaster {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- unistd::write(self.0, buf).map_err(io::Error::from)
+ unistd::write(self.0.as_raw_fd(), buf).map_err(io::Error::from)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
@@ -164,7 +144,7 @@ pub fn posix_openpt(flags: fcntl::OFlag) -> Result<PtyMaster> {
return Err(Errno::last());
}
- Ok(PtyMaster(fd))
+ Ok(PtyMaster(unsafe { OwnedFd::from_raw_fd(fd) }))
}
/// Get the name of the slave pseudoterminal (see
@@ -308,8 +288,8 @@ pub fn openpty<
unsafe {
Ok(OpenptyResult {
- master: master.assume_init(),
- slave: slave.assume_init(),
+ master: OwnedFd::from_raw_fd(master.assume_init()),
+ slave: OwnedFd::from_raw_fd(slave.assume_init()),
})
}
}
@@ -364,7 +344,7 @@ pub unsafe fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b T
})?;
Ok(ForkptyResult {
- master: master.assume_init(),
+ master: OwnedFd::from_raw_fd(master.assume_init()),
fork_result,
})
}
diff --git a/src/sched.rs b/src/sched.rs
index d5b1233c..0515e30f 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -16,7 +16,7 @@ mod sched_linux_like {
use libc::{self, c_int, c_void};
use std::mem;
use std::option::Option;
- use std::os::unix::io::RawFd;
+ use std::os::unix::io::{AsFd, AsRawFd};
// For some functions taking with a parameter of type CloneFlags,
// only a subset of these flags have an effect.
@@ -136,8 +136,8 @@ mod sched_linux_like {
/// reassociate thread with a namespace
///
/// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
- pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
- let res = unsafe { libc::setns(fd, nstype.bits()) };
+ pub fn setns<Fd: AsFd>(fd: Fd, nstype: CloneFlags) -> Result<()> {
+ let res = unsafe { libc::setns(fd.as_fd().as_raw_fd(), nstype.bits()) };
Errno::result(res).map(drop)
}
diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs
index 02c25d4d..36f9c17d 100644
--- a/src/sys/epoll.rs
+++ b/src/sys/epoll.rs
@@ -2,7 +2,7 @@ use crate::errno::Errno;
use crate::Result;
use libc::{self, c_int};
use std::mem;
-use std::os::unix::io::{FromRawFd,RawFd, OwnedFd, AsFd, AsRawFd};
+use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd};
libc_bitflags!(
pub struct EpollFlags: c_int {
@@ -78,22 +78,22 @@ impl EpollEvent {
/// # fn main() -> nix::Result<()> {
/// const DATA: u64 = 17;
/// const MILLIS: u64 = 100;
-///
+///
/// // Create epoll
/// let epoll = Epoll::new(EpollCreateFlags::empty())?;
-///
+///
/// // Create eventfd & Add event
-/// let eventfd = unsafe { OwnedFd::from_raw_fd(eventfd(0, EfdFlags::empty())?) };
+/// let eventfd = eventfd(0, EfdFlags::empty())?;
/// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
-///
+///
/// // Arm eventfd & Time wait
/// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?;
/// let now = Instant::now();
-///
+///
/// // Wait on event
/// let mut events = [EpollEvent::empty()];
/// epoll.wait(&mut events, MILLIS as isize)?;
-///
+///
/// // Assert data correct & timeout didn't occur
/// assert_eq!(events[0].data(), DATA);
/// assert!(now.elapsed() < Duration::from_millis(MILLIS));
@@ -104,7 +104,7 @@ impl EpollEvent {
pub struct Epoll(pub OwnedFd);
impl Epoll {
/// Creates a new epoll instance and returns a file descriptor referring to that instance.
- ///
+ ///
/// [`epoll_create1`](https://man7.org/linux/man-pages/man2/epoll_create1.2.html).
pub fn new(flags: EpollCreateFlags) -> Result<Self> {
let res = unsafe { libc::epoll_create1(flags.bits()) };
@@ -113,30 +113,38 @@ impl Epoll {
Ok(Self(owned_fd))
}
/// Add an entry to the interest list of the epoll file descriptor for
- /// specified in events.
- ///
+ /// specified in events.
+ ///
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_ADD`.
pub fn add<Fd: AsFd>(&self, fd: Fd, mut event: EpollEvent) -> Result<()> {
- self.epoll_ctl(EpollOp::EpollCtlAdd,fd,&mut event)
+ self.epoll_ctl(EpollOp::EpollCtlAdd, fd, &mut event)
}
/// Remove (deregister) the target file descriptor `fd` from the interest list.
- ///
+ ///
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_DEL` .
pub fn delete<Fd: AsFd>(&self, fd: Fd) -> Result<()> {
- self.epoll_ctl(EpollOp::EpollCtlDel,fd,None)
+ self.epoll_ctl(EpollOp::EpollCtlDel, fd, None)
}
/// Change the settings associated with `fd` in the interest list to the new settings specified
/// in `event`.
- ///
+ ///
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_MOD`.
- pub fn modify<Fd: AsFd>(&self,fd: Fd, event: &mut EpollEvent) -> Result<()> {
- self.epoll_ctl(EpollOp::EpollCtlMod,fd,event)
+ pub fn modify<Fd: AsFd>(
+ &self,
+ fd: Fd,
+ event: &mut EpollEvent,
+ ) -> Result<()> {
+ self.epoll_ctl(EpollOp::EpollCtlMod, fd, event)
}
/// Waits for I/O events, blocking the calling thread if no events are currently available.
/// (This can be thought of as fetching items from the ready list of the epoll instance.)
- ///
+ ///
/// [`epoll_wait`](https://man7.org/linux/man-pages/man2/epoll_wait.2.html)
- pub fn wait(&self, events: &mut [EpollEvent], timeout: isize) -> Result<usize> {
+ pub fn wait(
+ &self,
+ events: &mut [EpollEvent],
+ timeout: isize,
+ ) -> Result<usize> {
let res = unsafe {
libc::epoll_wait(
self.0.as_raw_fd(),
@@ -145,15 +153,15 @@ impl Epoll {
timeout as c_int,
)
};
-
+
Errno::result(res).map(|r| r as usize)
}
/// This system call is used to add, modify, or remove entries in the interest list of the epoll
/// instance referred to by `self`. It requests that the operation `op` be performed for the
/// target file descriptor, `fd`.
- ///
+ ///
/// When possible prefer [`Epoll::add`], [`Epoll::delete`] and [`Epoll::modify`].
- ///
+ ///
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
fn epoll_ctl<'a, Fd: AsFd, T>(
&self,
@@ -165,9 +173,17 @@ impl Epoll {
T: Into<Option<&'a mut EpollEvent>>,
{
let event: Option<&mut EpollEvent> = event.into();
- let ptr = event.map(|x|&mut x.event as *mut libc::epoll_event).unwrap_or(std::ptr::null_mut());
+ let ptr = event
+ .map(|x| &mut x.event as *mut libc::epoll_event)
+ .unwrap_or(std::ptr::null_mut());
unsafe {
- Errno::result(libc::epoll_ctl(self.0.as_raw_fd(), op as c_int, fd.as_fd().as_raw_fd(), ptr)).map(drop)
+ Errno::result(libc::epoll_ctl(
+ self.0.as_raw_fd(),
+ op as c_int,
+ fd.as_fd().as_raw_fd(),
+ ptr,
+ ))
+ .map(drop)
}
}
}
@@ -231,4 +247,4 @@ pub fn epoll_wait(
};
Errno::result(res).map(|r| r as usize)
-} \ No newline at end of file
+}
diff --git a/src/sys/event.rs b/src/sys/event.rs
index d8ad628e..f21ba173 100644
--- a/src/sys/event.rs
+++ b/src/sys/event.rs
@@ -8,7 +8,7 @@ use libc::{c_int, c_long, intptr_t, time_t, timespec, uintptr_t};
use libc::{c_long, intptr_t, size_t, time_t, timespec, uintptr_t};
use std::convert::TryInto;
use std::mem;
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd};
use std::ptr;
// Redefine kevent in terms of programmer-friendly enums and bitfields.
@@ -207,10 +207,10 @@ libc_bitflags!(
}
);
-pub fn kqueue() -> Result<RawFd> {
+pub fn kqueue() -> Result<OwnedFd> {
let res = unsafe { libc::kqueue() };
- Errno::result(res)
+ Errno::result(res).map(|fd| unsafe { OwnedFd::from_raw_fd(fd) })
}
// KEvent can't derive Send because on some operating systems, udata is defined
@@ -267,8 +267,8 @@ impl KEvent {
}
}
-pub fn kevent(
- kq: RawFd,
+pub fn kevent<Fd: AsFd>(
+ kq: Fd,
changelist: &[KEvent],
eventlist: &mut [KEvent],
timeout_ms: usize,
@@ -293,15 +293,15 @@ type type_of_nchanges = c_int;
#[cfg(target_os = "netbsd")]
type type_of_nchanges = size_t;
-pub fn kevent_ts(
- kq: RawFd,
+pub fn kevent_ts<Fd: AsFd>(
+ kq: Fd,
changelist: &[KEvent],
eventlist: &mut [KEvent],
timeout_opt: Option<timespec>,
) -> Result<usize> {
let res = unsafe {
libc::kevent(
- kq,
+ kq.as_fd().as_raw_fd(),
changelist.as_ptr() as *const libc::kevent,
changelist.len() as type_of_nchanges,
eventlist.as_mut_ptr() as *mut libc::kevent,
diff --git a/src/sys/eventfd.rs b/src/sys/eventfd.rs
index cd906720..f1723519 100644
--- a/src/sys/eventfd.rs
+++ b/src/sys/eventfd.rs
@@ -1,6 +1,6 @@
use crate::errno::Errno;
use crate::Result;
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{FromRawFd, OwnedFd};
libc_bitflags! {
pub struct EfdFlags: libc::c_int {
@@ -10,8 +10,8 @@ libc_bitflags! {
}
}
-pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd> {
+pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd> {
let res = unsafe { libc::eventfd(initval, flags.bits()) };
- Errno::result(res).map(|r| r as RawFd)
+ Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r) })
}
diff --git a/src/sys/inotify.rs b/src/sys/inotify.rs
index 84356ec7..2398c16e 100644
--- a/src/sys/inotify.rs
+++ b/src/sys/inotify.rs
@@ -32,7 +32,7 @@ use libc::{c_char, c_int};
use std::ffi::{CStr, OsStr, OsString};
use std::mem::{size_of, MaybeUninit};
use std::os::unix::ffi::OsStrExt;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::ptr;
libc_bitflags! {
@@ -101,9 +101,9 @@ libc_bitflags! {
/// An inotify instance. This is also a file descriptor, you can feed it to
/// other interfaces consuming file descriptors, epoll for example.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug)]
pub struct Inotify {
- fd: RawFd,
+ fd: OwnedFd,
}
/// This object is returned when you create a new watch on an inotify instance.
@@ -143,7 +143,7 @@ impl Inotify {
pub fn init(flags: InitFlags) -> Result<Inotify> {
let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) });
- res.map(|fd| Inotify { fd })
+ res.map(|fd| Inotify { fd: unsafe { OwnedFd::from_raw_fd(fd) } })
}
/// Adds a new watch on the target file or directory.
@@ -152,12 +152,12 @@ impl Inotify {
///
/// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
pub fn add_watch<P: ?Sized + NixPath>(
- self,
+ &self,
path: &P,
mask: AddWatchFlags,
) -> Result<WatchDescriptor> {
let res = path.with_nix_path(|cstr| unsafe {
- libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
+ libc::inotify_add_watch(self.fd.as_raw_fd(), cstr.as_ptr(), mask.bits())
})?;
Errno::result(res).map(|wd| WatchDescriptor { wd })
@@ -169,7 +169,7 @@ impl Inotify {
/// Returns an EINVAL error if the watch descriptor is invalid.
///
/// For more information see, [inotify_rm_watch(2)](https://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
- pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> {
+ pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
cfg_if! {
if #[cfg(target_os = "linux")] {
let arg = wd.wd;
@@ -177,7 +177,7 @@ impl Inotify {
let arg = wd.wd as u32;
}
}
- let res = unsafe { libc::inotify_rm_watch(self.fd, arg) };
+ let res = unsafe { libc::inotify_rm_watch(self.fd.as_raw_fd(), arg) };
Errno::result(res).map(drop)
}
@@ -188,14 +188,14 @@ impl Inotify {
///
/// Returns as many events as available. If the call was non blocking and no
/// events could be read then the EAGAIN error is returned.
- pub fn read_events(self) -> Result<Vec<InotifyEvent>> {
+ pub fn read_events(&self) -> Result<Vec<InotifyEvent>> {
let header_size = size_of::<libc::inotify_event>();
const BUFSIZ: usize = 4096;
let mut buffer = [0u8; BUFSIZ];
let mut events = Vec::new();
let mut offset = 0;
- let nread = read(self.fd, &mut buffer)?;
+ let nread = read(self.fd.as_raw_fd(), &mut buffer)?;
while (nread - offset) >= header_size {
let event = unsafe {
@@ -235,14 +235,8 @@ impl Inotify {
}
}
-impl AsRawFd for Inotify {
- fn as_raw_fd(&self) -> RawFd {
- self.fd
- }
-}
-
impl FromRawFd for Inotify {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
- Inotify { fd }
+ Inotify { fd: OwnedFd::from_raw_fd(fd) }
}
}
diff --git a/src/sys/memfd.rs b/src/sys/memfd.rs
index ad9345e8..f349a743 100644
--- a/src/sys/memfd.rs
+++ b/src/sys/memfd.rs
@@ -1,7 +1,7 @@
//! Interfaces for managing memory-backed files.
use cfg_if::cfg_if;
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
use crate::errno::Errno;
use crate::Result;
@@ -40,7 +40,7 @@ libc_bitflags!(
/// For more information, see [`memfd_create(2)`].
///
/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
-pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
+pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<OwnedFd> {
let res = unsafe {
cfg_if! {
if #[cfg(all(
@@ -60,5 +60,5 @@ pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
}
};
- Errno::result(res).map(|r| r as RawFd)
+ Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r as RawFd) })
}
diff --git a/src/sys/mman.rs b/src/sys/mman.rs
index deef7005..e689e06e 100644
--- a/src/sys/mman.rs
+++ b/src/sys/mman.rs
@@ -421,7 +421,7 @@ pub unsafe fn mmap<F: AsFd>(
length: NonZeroUsize,
prot: ProtFlags,
flags: MapFlags,
- f: Option<&F>,
+ f: Option<F>,
offset: off_t,
) -> Result<*mut c_void> {
let ptr =
diff --git a/src/sys/sendfile.rs b/src/sys/sendfile.rs
index fb293a4e..9f3c333f 100644
--- a/src/sys/sendfile.rs
+++ b/src/sys/sendfile.rs
@@ -1,7 +1,7 @@
//! Send data from a file to a socket, bypassing userland.
use cfg_if::cfg_if;
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use std::ptr;
use libc::{self, off_t};
@@ -23,16 +23,23 @@ use crate::Result;
/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html)
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn sendfile(
- out_fd: RawFd,
- in_fd: RawFd,
+pub fn sendfile<F1: AsFd, F2: AsFd>(
+ out_fd: F1,
+ in_fd: F2,
offset: Option<&mut off_t>,
count: usize,
) -> Result<usize> {
let offset = offset
.map(|offset| offset as *mut _)
.unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) };
+ let ret = unsafe {
+ libc::sendfile(
+ out_fd.as_fd().as_raw_fd(),
+ in_fd.as_fd().as_raw_fd(),
+ offset,
+ count,
+ )
+ };
Errno::result(ret).map(|r| r as usize)
}
@@ -50,16 +57,23 @@ pub fn sendfile(
/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html)
#[cfg(target_os = "linux")]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn sendfile64(
- out_fd: RawFd,
- in_fd: RawFd,
+pub fn sendfile64<F1: AsFd, F2: AsFd>(
+ out_fd: F1,
+ in_fd: F2,
offset: Option<&mut libc::off64_t>,
count: usize,
) -> Result<usize> {
let offset = offset
.map(|offset| offset as *mut _)
.unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::sendfile64(out_fd, in_fd, offset, count) };
+ let ret = unsafe {
+ libc::sendfile64(
+ out_fd.as_fd().as_raw_fd(),
+ in_fd.as_fd().as_raw_fd(),
+ offset,
+ count,
+ )
+ };
Errno::result(ret).map(|r| r as usize)
}
@@ -156,9 +170,9 @@ cfg_if! {
/// For more information, see
/// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2)
#[allow(clippy::too_many_arguments)]
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
+ pub fn sendfile<F1: AsFd, F2: AsFd>(
+ in_fd: F1,
+ out_sock: F2,
offset: off_t,
count: Option<usize>,
headers: Option<&[&[u8]]>,
@@ -175,8 +189,8 @@ cfg_if! {
let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
+ libc::sendfile(in_fd.as_fd().as_raw_fd(),
+ out_sock.as_fd().as_raw_fd(),
offset,
count.unwrap_or(0),
hdtr_ptr as *mut libc::sf_hdtr,
@@ -206,9 +220,9 @@ cfg_if! {
///
/// For more information, see
/// [the sendfile(2) man page.](https://leaf.dragonflybsd.org/cgi/web-man?command=sendfile&section=2)
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
+ pub fn sendfile<F1: AsFd, F2: AsFd>(
+ in_fd: F1,
+ out_sock: F2,
offset: off_t,
count: Option<usize>,
headers: Option<&[&[u8]]>,
@@ -218,8 +232,8 @@ cfg_if! {
let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
+ libc::sendfile(in_fd.as_fd().as_raw_fd(),
+ out_sock.as_fd().as_raw_fd(),
offset,
count.unwrap_or(0),
hdtr_ptr as *mut libc::sf_hdtr,
@@ -252,9 +266,9 @@ cfg_if! {
///
/// For more information, see
/// [the sendfile(2) man page.](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html)
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
+ pub fn sendfile<F1: AsFd, F2: AsFd>(
+ in_fd: F1,
+ out_sock: F2,
offset: off_t,
count: Option<off_t>,
headers: Option<&[&[u8]]>,
@@ -264,8 +278,8 @@ cfg_if! {
let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
+ libc::sendfile(in_fd.as_fd().as_raw_fd(),
+ out_sock.as_fd().as_raw_fd(),
offset,
&mut len as *mut off_t,
hdtr_ptr as *mut libc::sf_hdtr,
diff --git a/src/sys/signalfd.rs b/src/sys/signalfd.rs
index 095e5908..2b80ea64 100644
--- a/src/sys/signalfd.rs
+++ b/src/sys/signalfd.rs
@@ -17,12 +17,11 @@
//! signal handlers.
use crate::errno::Errno;
pub use crate::sys::signal::{self, SigSet};
-use crate::unistd;
use crate::Result;
pub use libc::signalfd_siginfo as siginfo;
use std::mem;
-use std::os::unix::io::{AsRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, RawFd, FromRawFd, OwnedFd, AsFd, BorrowedFd};
libc_bitflags! {
pub struct SfdFlags: libc::c_int {
@@ -31,7 +30,6 @@ libc_bitflags! {
}
}
-pub const SIGNALFD_NEW: RawFd = -1;
#[deprecated(since = "0.23.0", note = "use mem::size_of::<siginfo>() instead")]
pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();
@@ -46,13 +44,19 @@ pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();
/// signalfd (the default handler will be invoked instead).
///
/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
-pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
+#[deprecated(since = "0.27.0", note = "Use SignalFd instead")]
+pub fn signalfd<F: AsFd>(fd: Option<F>, mask: &SigSet, flags: SfdFlags) -> Result<OwnedFd> {
+ _signalfd(fd, mask, flags)
+}
+
+fn _signalfd<F: AsFd>(fd: Option<F>, mask: &SigSet, flags: SfdFlags) -> Result<OwnedFd> {
+ let raw_fd = fd.map_or(-1, |x|x.as_fd().as_raw_fd());
unsafe {
Errno::result(libc::signalfd(
- fd as libc::c_int,
+ raw_fd,
mask.as_ref(),
flags.bits(),
- ))
+ )).map(|raw_fd|FromRawFd::from_raw_fd(raw_fd))
}
}
@@ -82,8 +86,8 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
/// Err(err) => (), // some error happend
/// }
/// ```
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct SignalFd(RawFd);
+#[derive(Debug)]
+pub struct SignalFd(OwnedFd);
impl SignalFd {
pub fn new(mask: &SigSet) -> Result<SignalFd> {
@@ -91,13 +95,13 @@ impl SignalFd {
}
pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result<SignalFd> {
- let fd = signalfd(SIGNALFD_NEW, mask, flags)?;
+ let fd = _signalfd(None::<OwnedFd>, mask, flags)?;
Ok(SignalFd(fd))
}
pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
- signalfd(self.0, mask, SfdFlags::empty()).map(drop)
+ _signalfd(Some(self.0.as_fd()), mask, SfdFlags::empty()).map(drop)
}
pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
@@ -105,7 +109,7 @@ impl SignalFd {
let size = mem::size_of_val(&buffer);
let res = Errno::result(unsafe {
- libc::read(self.0, buffer.as_mut_ptr() as *mut libc::c_void, size)
+ libc::read(self.0.as_raw_fd(), buffer.as_mut_ptr() as *mut libc::c_void, size)
})
.map(|r| r as usize);
match res {
@@ -117,18 +121,14 @@ impl SignalFd {
}
}
-impl Drop for SignalFd {
- fn drop(&mut self) {
- let e = unistd::close(self.0);
- if !std::thread::panicking() && e == Err(Errno::EBADF) {
- panic!("Closing an invalid file descriptor!");
- };
+impl AsFd for SignalFd {
+ fn as_fd(&self) -> BorrowedFd {
+ self.0.as_fd()
}
}
-
impl AsRawFd for SignalFd {
fn as_raw_fd(&self) -> RawFd {
- self.0
+ self.0.as_raw_fd()
}
}
diff --git a/src/sys/statfs.rs b/src/sys/statfs.rs
index 721d45cb..5111df2e 100644
--- a/src/sys/statfs.rs
+++ b/src/sys/statfs.rs
@@ -740,7 +740,7 @@ pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
/// # Arguments
///
/// `fd` - File descriptor of any open file within the file system to describe
-pub fn fstatfs<Fd: AsFd>(fd: &Fd) -> Result<Statfs> {
+pub fn fstatfs<Fd: AsFd>(fd: Fd) -> Result<Statfs> {
unsafe {
let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
Errno::result(LIBC_FSTATFS(fd.as_fd().as_raw_fd(), stat.as_mut_ptr()))
diff --git a/src/sys/statvfs.rs b/src/sys/statvfs.rs
index 8de369f4..c2c86624 100644
--- a/src/sys/statvfs.rs
+++ b/src/sys/statvfs.rs
@@ -3,7 +3,7 @@
//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html)
//! for more details.
use std::mem;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use libc::{self, c_ulong};
@@ -146,11 +146,11 @@ pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
}
/// Return a `Statvfs` object with information about `fd`
-pub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> {
+pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> Result<Statvfs> {
unsafe {
Errno::clear();
let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
- Errno::result(libc::fstatvfs(fd.as_raw_fd(), stat.as_mut_ptr()))
+ Errno::result(libc::fstatvfs(fd.as_fd().as_raw_fd(), stat.as_mut_ptr()))
.map(|_| Statvfs(stat.assume_init()))
}
}
diff --git a/src/sys/termios.rs b/src/sys/termios.rs
index fba2cd82..b0286f51 100644
--- a/src/sys/termios.rs
+++ b/src/sys/termios.rs
@@ -222,7 +222,7 @@ use libc::{self, c_int, tcflag_t};
use std::cell::{Ref, RefCell};
use std::convert::From;
use std::mem;
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
#[cfg(feature = "process")]
use crate::unistd::Pid;
@@ -1143,10 +1143,12 @@ pub fn cfmakesane(termios: &mut Termios) {
/// `tcgetattr()` returns a `Termios` structure with the current configuration for a port. Modifying
/// this structure *will not* reconfigure the port, instead the modifications should be done to
/// the `Termios` structure and then the port should be reconfigured using `tcsetattr()`.
-pub fn tcgetattr(fd: RawFd) -> Result<Termios> {
+pub fn tcgetattr<Fd: AsFd>(fd: Fd) -> Result<Termios> {
let mut termios = mem::MaybeUninit::uninit();
- let res = unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) };
+ let res = unsafe {
+ libc::tcgetattr(fd.as_fd().as_raw_fd(), termios.as_mut_ptr())
+ };
Errno::result(res)?;
@@ -1159,18 +1161,26 @@ pub fn tcgetattr(fd: RawFd) -> Result<Termios> {
/// `tcsetattr()` reconfigures the given port based on a given `Termios` structure. This change
/// takes affect at a time specified by `actions`. Note that this function may return success if
/// *any* of the parameters were successfully set, not only if all were set successfully.
-pub fn tcsetattr(fd: RawFd, actions: SetArg, termios: &Termios) -> Result<()> {
+pub fn tcsetattr<Fd: AsFd>(
+ fd: Fd,
+ actions: SetArg,
+ termios: &Termios,
+) -> Result<()> {
let inner_termios = termios.get_libc_termios();
Errno::result(unsafe {
- libc::tcsetattr(fd, actions as c_int, &*inner_termios)
+ libc::tcsetattr(
+ fd.as_fd().as_raw_fd(),
+ actions as c_int,
+ &*inner_termios,
+ )
})
.map(drop)
}
/// Block until all output data is written (see
/// [tcdrain(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcdrain.html)).
-pub fn tcdrain(fd: RawFd) -> Result<()> {
- Errno::result(unsafe { libc::tcdrain(fd) }).map(drop)
+pub fn tcdrain<Fd: AsFd>(fd: Fd) -> Result<()> {
+ Errno::result(unsafe { libc::tcdrain(fd.as_fd().as_raw_fd()) }).map(drop)
}
/// Suspend or resume the transmission or reception of data (see
@@ -1178,8 +1188,11 @@ pub fn tcdrain(fd: RawFd) -> Result<()> {
///
/// `tcflow()` suspends of resumes the transmission or reception of data for the given port
/// depending on the value of `action`.
-pub fn tcflow(fd: RawFd, action: FlowArg) -> Result<()> {
- Errno::result(unsafe { libc::tcflow(fd, action as c_int) }).map(drop)
+pub fn tcflow<Fd: AsFd>(fd: Fd, action: FlowArg) -> Result<()> {
+ Errno::result(unsafe {
+ libc::tcflow(fd.as_fd().as_raw_fd(), action as c_int)
+ })
+ .map(drop)
}
/// Discard data in the output or input queue (see
@@ -1187,8 +1200,11 @@ pub fn tcflow(fd: RawFd, action: FlowArg) -> Result<()> {
///
/// `tcflush()` will discard data for a terminal port in the input queue, output queue, or both
/// depending on the value of `action`.
-pub fn tcflush(fd: RawFd, action: FlushArg) -> Result<()> {
- Errno::result(unsafe { libc::tcflush(fd, action as c_int) }).map(drop)
+pub fn tcflush<Fd: AsFd>(fd: Fd, action: FlushArg) -> Result<()> {
+ Errno::result(unsafe {
+ libc::tcflush(fd.as_fd().as_raw_fd(), action as c_int)
+ })
+ .map(drop)
}
/// Send a break for a specific duration (see
@@ -1196,16 +1212,19 @@ pub fn tcflush(fd: RawFd, action: FlushArg) -> Result<()> {
///
/// When using asynchronous data transmission `tcsendbreak()` will transmit a continuous stream
/// of zero-valued bits for an implementation-defined duration.
-pub fn tcsendbreak(fd: RawFd, duration: c_int) -> Result<()> {
- Errno::result(unsafe { libc::tcsendbreak(fd, duration) }).map(drop)
+pub fn tcsendbreak<Fd: AsFd>(fd: Fd, duration: c_int) -> Result<()> {
+ Errno::result(unsafe {
+ libc::tcsendbreak(fd.as_fd().as_raw_fd(), duration)
+ })
+ .map(drop)
}
feature! {
#![feature = "process"]
/// Get the session controlled by the given terminal (see
/// [tcgetsid(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetsid.html)).
-pub fn tcgetsid(fd: RawFd) -> Result<Pid> {
- let res = unsafe { libc::tcgetsid(fd) };
+pub fn tcgetsid<Fd: AsFd>(fd: Fd) -> Result<Pid> {
+ let res = unsafe { libc::tcgetsid(fd.as_fd().as_raw_fd()) };
Errno::result(res).map(Pid::from_raw)
}
diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs
index a35fc927..90a05a8c 100644
--- a/src/sys/timerfd.rs
+++ b/src/sys/timerfd.rs
@@ -33,24 +33,28 @@ pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags};
use crate::unistd::read;
use crate::{errno::Errno, Result};
use libc::c_int;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
/// A timerfd instance. This is also a file descriptor, you can feed it to
-/// other interfaces consuming file descriptors, epoll for example.
+/// other interfaces taking file descriptors as arguments, [`epoll`] for example.
+///
+/// [`epoll`]: crate::sys::epoll
#[derive(Debug)]
pub struct TimerFd {
- fd: RawFd,
+ fd: OwnedFd,
}
-impl AsRawFd for TimerFd {
- fn as_raw_fd(&self) -> RawFd {
- self.fd
+impl AsFd for TimerFd {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ self.fd.as_fd()
}
}
impl FromRawFd for TimerFd {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
- TimerFd { fd }
+ TimerFd {
+ fd: OwnedFd::from_raw_fd(fd),
+ }
}
}
@@ -97,7 +101,9 @@ impl TimerFd {
Errno::result(unsafe {
libc::timerfd_create(clockid as i32, flags.bits())
})
- .map(|fd| Self { fd })
+ .map(|fd| Self {
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
+ })
}
/// Sets a new alarm on the timer.
@@ -145,7 +151,7 @@ impl TimerFd {
let timerspec: TimerSpec = expiration.into();
Errno::result(unsafe {
libc::timerfd_settime(
- self.fd,
+ self.fd.as_fd().as_raw_fd(),
flags.bits(),
timerspec.as_ref(),
std::ptr::null_mut(),
@@ -159,7 +165,10 @@ impl TimerFd {
pub fn get(&self) -> Result<Option<Expiration>> {
let mut timerspec = TimerSpec::none();
Errno::result(unsafe {
- libc::timerfd_gettime(self.fd, timerspec.as_mut())
+ libc::timerfd_gettime(
+ self.fd.as_fd().as_raw_fd(),
+ timerspec.as_mut(),
+ )
})
.map(|_| {
if timerspec.as_ref().it_interval.tv_sec == 0
@@ -179,7 +188,7 @@ impl TimerFd {
pub fn unset(&self) -> Result<()> {
Errno::result(unsafe {
libc::timerfd_settime(
- self.fd,
+ self.fd.as_fd().as_raw_fd(),
TimerSetTimeFlags::empty().bits(),
TimerSpec::none().as_ref(),
std::ptr::null_mut(),
@@ -192,7 +201,7 @@ impl TimerFd {
///
/// Note: If the alarm is unset, then you will wait forever.
pub fn wait(&self) -> Result<()> {
- while let Err(e) = read(self.fd, &mut [0u8; 8]) {
+ while let Err(e) = read(self.fd.as_fd().as_raw_fd(), &mut [0u8; 8]) {
if e != Errno::EINTR {
return Err(e);
}
@@ -201,14 +210,3 @@ impl TimerFd {
Ok(())
}
}
-
-impl Drop for TimerFd {
- fn drop(&mut self) {
- if !std::thread::panicking() {
- let result = Errno::result(unsafe { libc::close(self.fd) });
- if let Err(Errno::EBADF) = result {
- panic!("close of TimerFd encountered EBADF");
- }
- }
- }
-}
diff --git a/src/sys/uio.rs b/src/sys/uio.rs
index 7248bd0c..ce0fb54d 100644
--- a/src/sys/uio.rs
+++ b/src/sys/uio.rs
@@ -4,12 +4,12 @@ use crate::errno::Errno;
use crate::Result;
use libc::{self, c_int, c_void, off_t, size_t};
use std::io::{IoSlice, IoSliceMut};
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
/// Low-level vectored write to a raw file descriptor
///
/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html)
-pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
+pub fn writev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>]) -> Result<usize> {
// SAFETY: to quote the documentation for `IoSlice`:
//
// [IoSlice] is semantically a wrapper around a &[u8], but is
@@ -18,7 +18,7 @@ pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
//
// Because it is ABI compatible, a pointer cast here is valid
let res = unsafe {
- libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
+ libc::writev(fd.as_fd().as_raw_fd(), iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
};
Errno::result(res).map(|r| r as usize)
@@ -27,10 +27,10 @@ pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
/// Low-level vectored read from a raw file descriptor
///
/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html)
-pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
+pub fn readv<Fd: AsFd>(fd: Fd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
// SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec
let res = unsafe {
- libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
+ libc::readv(fd.as_fd().as_raw_fd(), iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
};
Errno::result(res).map(|r| r as usize)
@@ -44,14 +44,14 @@ pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html)
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
+pub fn pwritev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t; // uclibc doesn't use off_t
// SAFETY: same as in writev()
let res = unsafe {
libc::pwritev(
- fd,
+ fd.as_fd().as_raw_fd(),
iov.as_ptr() as *const libc::iovec,
iov.len() as c_int,
offset,
@@ -70,8 +70,8 @@ pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html)
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn preadv(
- fd: RawFd,
+pub fn preadv<Fd: AsFd>(
+ fd: Fd,
iov: &mut [IoSliceMut<'_>],
offset: off_t,
) -> Result<usize> {
@@ -81,7 +81,7 @@ pub fn preadv(
// SAFETY: same as in readv()
let res = unsafe {
libc::preadv(
- fd,
+ fd.as_fd().as_raw_fd(),
iov.as_ptr() as *const libc::iovec,
iov.len() as c_int,
offset,
@@ -95,10 +95,10 @@ pub fn preadv(
///
/// See also [pwrite(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html)
// TODO: move to unistd
-pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
+pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pwrite(
- fd,
+ fd.as_fd().as_raw_fd(),
buf.as_ptr() as *const c_void,
buf.len() as size_t,
offset,
@@ -112,10 +112,10 @@ pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
///
/// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html)
// TODO: move to unistd
-pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize> {
+pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pread(
- fd,
+ fd.as_fd().as_raw_fd(),
buf.as_mut_ptr() as *mut c_void,
buf.len() as size_t,
offset,
diff --git a/src/unistd.rs b/src/unistd.rs
index 1bfeb7b9..ae1cca95 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -217,7 +217,6 @@ impl fmt::Display for Pid {
}
}
-
/// Represents the successful result of calling `fork`
///
/// When `fork` is called, the process continues execution in the parent process
@@ -230,7 +229,6 @@ pub enum ForkResult {
}
impl ForkResult {
-
/// Return `true` if this is the child process of the `fork()`
#[inline]
pub fn is_child(self) -> bool {
@@ -478,9 +476,8 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
/// pages for additional details on possible failure cases.
#[inline]
pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::chdir(cstr.as_ptr()) }
- })?;
+ let res =
+ path.with_nix_path(|cstr| unsafe { libc::chdir(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
@@ -527,8 +524,8 @@ pub fn fchdir(dirfd: RawFd) -> Result<()> {
/// ```
#[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) }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t)
})?;
Errno::result(res).map(drop)
@@ -566,8 +563,8 @@ pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
#[inline]
#[cfg(not(target_os = "redox"))] // RedoxFS does not support fifo yet
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) }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t)
})?;
Errno::result(res).map(drop)
@@ -591,7 +588,11 @@ pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
target_os = "android",
target_os = "redox"
)))]
-pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
+pub fn mkfifoat<P: ?Sized + NixPath>(
+ dirfd: Option<RawFd>,
+ path: &P,
+ mode: Mode,
+) -> Result<()> {
let res = path.with_nix_path(|cstr| unsafe {
libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t)
})?;
@@ -612,19 +613,17 @@ pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode)
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()
- )
- }
- })
- })??;
+ 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)
}
}
@@ -674,7 +673,9 @@ pub fn getcwd() -> Result<PathBuf> {
// To safely handle this we start with a reasonable size (512 bytes)
// and double the buffer size upon every error
if !libc::getcwd(ptr, buf.capacity()).is_null() {
- let len = CStr::from_ptr(buf.as_ptr() as *const c_char).to_bytes().len();
+ 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)));
@@ -684,7 +685,7 @@ pub fn getcwd() -> Result<PathBuf> {
if error != Errno::ERANGE {
return Err(error);
}
- }
+ }
// Trigger the internal buffer resizing logic.
reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?;
@@ -699,10 +700,7 @@ feature! {
/// Computes the raw UID and GID values to pass to a `*chown` call.
// The cast is not unnecessary on all platforms.
#[allow(clippy::unnecessary_cast)]
-fn chown_raw_ids(
- owner: Option<Uid>,
- group: Option<Gid>,
-) -> (uid_t, gid_t) {
+fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (uid_t, gid_t) {
// According to the POSIX specification, -1 is used to indicate that owner and group
// are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap
// around to get -1.
@@ -792,8 +790,13 @@ pub fn fchownat<P: ?Sized + NixPath>(
};
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)
+ libc::fchownat(
+ at_rawfd(dirfd),
+ cstr.as_ptr(),
+ uid,
+ gid,
+ atflag.bits() as libc::c_int,
+ )
})?;
Errno::result(res).map(drop)
@@ -912,13 +915,15 @@ pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(
target_os = "freebsd"
))]
#[inline]
-pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[SE]) -> Result<Infallible> {
+pub fn fexecve<SA: AsRef<CStr>, SE: AsRef<CStr>>(
+ fd: RawFd,
+ args: &[SA],
+ env: &[SE],
+) -> Result<Infallible> {
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())
- };
+ unsafe { libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr()) };
Err(Errno::last())
}
@@ -935,14 +940,25 @@ pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[
/// is referenced as a file descriptor to the base directory plus a path.
#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
-pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr, args: &[SA],
- env: &[SE], flags: super::fcntl::AtFlags) -> Result<Infallible> {
+pub fn execveat<SA: AsRef<CStr>, SE: AsRef<CStr>>(
+ dirfd: RawFd,
+ pathname: &CStr,
+ args: &[SA],
+ env: &[SE],
+ flags: super::fcntl::AtFlags,
+) -> Result<Infallible> {
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);
+ libc::syscall(
+ libc::SYS_execveat,
+ dirfd,
+ pathname.as_ptr(),
+ args_p.as_ptr(),
+ env_p.as_ptr(),
+ flags,
+ );
};
Err(Errno::last())
@@ -1157,7 +1173,11 @@ pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result<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> {
+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)
@@ -1211,9 +1231,8 @@ feature! {
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
- let res = unsafe {
- libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits())
- };
+ let res =
+ unsafe { libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits()) };
Errno::result(res)?;
@@ -1283,27 +1302,22 @@ pub fn linkat<P: ?Sized + NixPath>(
newpath: &P,
flag: LinkatFlags,
) -> Result<()> {
+ let atflag = match flag {
+ LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW,
+ LinkatFlags::NoSymlinkFollow => AtFlags::empty(),
+ };
- let atflag =
- match flag {
- LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW,
- LinkatFlags::NoSymlinkFollow => AtFlags::empty(),
- };
-
- let res =
- oldpath.with_nix_path(|oldcstr| {
- newpath.with_nix_path(|newcstr| {
- unsafe {
- libc::linkat(
- at_rawfd(olddirfd),
- oldcstr.as_ptr(),
- at_rawfd(newdirfd),
- newcstr.as_ptr(),
- atflag.bits() as libc::c_int
- )
- }
- })
- })??;
+ let res = oldpath.with_nix_path(|oldcstr| {
+ newpath.with_nix_path(|newcstr| unsafe {
+ libc::linkat(
+ at_rawfd(olddirfd),
+ oldcstr.as_ptr(),
+ at_rawfd(newdirfd),
+ newcstr.as_ptr(),
+ atflag.bits() as libc::c_int,
+ )
+ })
+ })??;
Errno::result(res).map(drop)
}
@@ -1339,15 +1353,16 @@ pub fn unlinkat<P: ?Sized + NixPath>(
path: &P,
flag: UnlinkatFlags,
) -> Result<()> {
- let atflag =
- match flag {
- UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR,
- UnlinkatFlags::NoRemoveDir => AtFlags::empty(),
- };
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::unlinkat(at_rawfd(dirfd), cstr.as_ptr(), atflag.bits() as libc::c_int)
- }
+ let atflag = match flag {
+ UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR,
+ UnlinkatFlags::NoRemoveDir => AtFlags::empty(),
+ };
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::unlinkat(
+ at_rawfd(dirfd),
+ cstr.as_ptr(),
+ atflag.bits() as libc::c_int,
+ )
})?;
Errno::result(res).map(drop)
}
@@ -1562,27 +1577,31 @@ pub fn getgroups() -> Result<Vec<Gid>> {
// Now actually get the groups. We try multiple times in case the number of
// groups has changed since the first call to getgroups() and the buffer is
// now too small.
- let mut groups = Vec::<Gid>::with_capacity(Errno::result(ngroups)? as usize);
+ let mut groups =
+ Vec::<Gid>::with_capacity(Errno::result(ngroups)? as usize);
loop {
// FIXME: On the platforms we currently support, the `Gid` struct has
// the same representation in memory as a bare `gid_t`. This is not
// necessarily the case on all Rust platforms, though. See RFC 1785.
let ngroups = unsafe {
- libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t)
+ libc::getgroups(
+ groups.capacity() as c_int,
+ groups.as_mut_ptr() as *mut gid_t,
+ )
};
match Errno::result(ngroups) {
Ok(s) => {
unsafe { groups.set_len(s as usize) };
return Ok(groups);
- },
+ }
Err(Errno::EINVAL) => {
// EINVAL indicates that the buffer size was too
// small, resize it up to ngroups_max as limit.
reserve_double_buffer_size(&mut groups, ngroups_max)
.or(Err(Errno::EINVAL))?;
- },
- Err(e) => return Err(e)
+ }
+ Err(e) => return Err(e),
}
}
}
@@ -1618,7 +1637,12 @@ pub fn getgroups() -> Result<Vec<Gid>> {
/// #
/// # try_main().unwrap();
/// ```
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
+#[cfg(not(any(
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+ target_os = "haiku"
+)))]
pub fn setgroups(groups: &[Gid]) -> Result<()> {
cfg_if! {
if #[cfg(any(target_os = "dragonfly",
@@ -1638,7 +1662,10 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
// same representation in memory as a bare `gid_t`. This is not necessarily
// the case on all Rust platforms, though. See RFC 1785.
let res = unsafe {
- libc::setgroups(groups.len() as setgroups_ngroups_t, groups.as_ptr() as *const gid_t)
+ libc::setgroups(
+ groups.len() as setgroups_ngroups_t,
+ groups.as_ptr() as *const gid_t,
+ )
};
Errno::result(res).map(drop)
@@ -1664,10 +1691,12 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
/// and `setgroups()`. Additionally, while some implementations will return a
/// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation
/// will only ever return the complete list or else an error.
-#[cfg(not(any(target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "redox")))]
+#[cfg(not(any(
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox"
+)))]
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,
@@ -1686,10 +1715,12 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
loop {
let mut ngroups = groups.capacity() as i32;
let ret = unsafe {
- libc::getgrouplist(user.as_ptr(),
- gid as getgrouplist_group_t,
- groups.as_mut_ptr() as *mut getgrouplist_group_t,
- &mut ngroups)
+ libc::getgrouplist(
+ user.as_ptr(),
+ gid as getgrouplist_group_t,
+ groups.as_mut_ptr() as *mut getgrouplist_group_t,
+ &mut ngroups,
+ )
};
// BSD systems only return 0 or -1, Linux returns ngroups on success.
@@ -1745,7 +1776,12 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
/// #
/// # try_main().unwrap();
/// ```
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
+#[cfg(not(any(
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+ target_os = "haiku"
+)))]
pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
cfg_if! {
if #[cfg(any(target_os = "ios", target_os = "macos"))] {
@@ -1755,7 +1791,8 @@ pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
}
}
let gid: gid_t = group.into();
- let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
+ let res =
+ unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
Errno::result(res).map(drop)
}
@@ -1799,8 +1836,8 @@ pub mod alarm {
//!
//! Scheduling an alarm and waiting for the signal:
//!
-#![cfg_attr(target_os = "redox", doc = " ```rust,ignore")]
-#![cfg_attr(not(target_os = "redox"), doc = " ```rust")]
+ #![cfg_attr(target_os = "redox", doc = " ```rust,ignore")]
+ #![cfg_attr(not(target_os = "redox"), doc = " ```rust")]
//! use std::time::{Duration, Instant};
//!
//! use nix::unistd::{alarm, pause};
@@ -1876,17 +1913,16 @@ feature! {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
pub mod acct {
- use crate::{Result, NixPath};
use crate::errno::Errno;
+ use crate::{NixPath, Result};
use std::ptr;
/// Enable process accounting
///
/// See also [acct(2)](https://linux.die.net/man/2/acct)
pub fn enable<P: ?Sized + NixPath>(filename: &P) -> Result<()> {
- let res = filename.with_nix_path(|cstr| {
- unsafe { libc::acct(cstr.as_ptr()) }
- })?;
+ let res = filename
+ .with_nix_path(|cstr| unsafe { libc::acct(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
@@ -1928,7 +1964,8 @@ feature! {
/// ```
#[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 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(); // drop the trailing nul
@@ -1962,8 +1999,14 @@ feature! {
#[repr(i32)]
#[non_exhaustive]
pub enum PathconfVar {
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
- target_os = "netbsd", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
/// Minimum number of bits needed to represent, as a signed integer value,
/// the maximum size of a regular file allowed in the specified directory.
#[cfg_attr(docsrs, doc(cfg(all())))]
@@ -1987,42 +2030,86 @@ pub enum PathconfVar {
/// Maximum number of bytes that is guaranteed to be atomic when writing to
/// a pipe.
PIPE_BUF = libc::_PC_PIPE_BUF,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "illumos",
- target_os = "linux", target_os = "netbsd", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Symbolic links can be created.
POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Minimum number of bytes of storage actually allocated for any portion of
/// a file.
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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Recommended increment for file transfer sizes between the
/// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values.
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", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Maximum recommended file transfer size.
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", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Minimum recommended file transfer size.
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", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Recommended file transfer buffer alignment.
POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "netbsd",
- target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Maximum number of bytes in a symbolic link.
SYMLINK_MAX = libc::_PC_SYMLINK_MAX,
@@ -2036,23 +2123,45 @@ pub enum PathconfVar {
/// This symbol shall be defined to be the value of a character that shall
/// disable terminal special character handling.
_POSIX_VDISABLE = libc::_PC_VDISABLE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Asynchronous input or output operations may be performed for the
/// associated file.
_POSIX_ASYNC_IO = libc::_PC_ASYNC_IO,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Prioritized input or output operations may be performed for the
/// associated file.
_POSIX_PRIO_IO = libc::_PC_PRIO_IO,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "netbsd",
- target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Synchronized input or output operations may be performed for the
/// associated file.
@@ -2060,7 +2169,7 @@ pub enum PathconfVar {
#[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The resolution in nanoseconds for all file timestamps.
- _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION
+ _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION,
}
/// Like `pathconf`, but works with file descriptors instead of paths (see
@@ -2116,12 +2225,13 @@ pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result<Option<c_long>> {
/// - `Ok(None)`: the variable has no limit (for limit variables) or is
/// unsupported (for option variables)
/// - `Err(x)`: an error occurred
-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)
- }
+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 {
@@ -2168,9 +2278,15 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum amount by which a process can decrease its asynchronous I/O
/// priority level from its own scheduling priority.
@@ -2215,9 +2331,17 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Maximum length of a host name (not including the terminating null) as
/// returned from the `gethostname` function
@@ -2258,14 +2382,28 @@ pub enum SysconfVar {
/// A value one greater than the maximum value that the system may assign to
/// a newly-created file descriptor.
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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Advisory Information option.
_POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports barriers.
_POSIX_BARRIERS = libc::_SC_BARRIERS,
@@ -2273,15 +2411,31 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports clock selection.
_POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Process CPU-Time Clocks option.
_POSIX_CPUTIME = libc::_SC_CPUTIME,
@@ -2289,9 +2443,16 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_FSYNC = libc::_SC_FSYNC,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the IPv6 option.
_POSIX_IPV6 = libc::_SC_IPV6,
@@ -2323,9 +2484,17 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "illumos", target_os = "ios", target_os="linux",
- target_os = "macos", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Prioritized Input and Output option.
_POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO,
@@ -2333,27 +2502,56 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Raw Sockets option.
_POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports read-write locks.
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports realtime signals.
_POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Regular Expression Handling option.
_POSIX_REGEXP = libc::_SC_REGEXP,
@@ -2369,31 +2567,59 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the POSIX shell.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Spawn option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports spin locks.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Process Sporadic Server option.
_POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX,
/// The implementation supports the Synchronized Input and Output option.
@@ -2408,8 +2634,13 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Thread CPU-Time Clocks option.
_POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME,
@@ -2426,18 +2657,32 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Thread Process-Shared Synchronization
/// option.
_POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED,
- #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "linux",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Robust Mutex Priority Inheritance option.
_POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT,
- #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "linux",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Robust Mutex Priority Protection option.
_POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT,
@@ -2445,8 +2690,14 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Thread Sporadic Server option.
_POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER,
@@ -2454,8 +2705,14 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports timeouts.
_POSIX_TIMEOUTS = libc::_SC_TIMEOUTS,
@@ -2463,44 +2720,90 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace Event Filter option.
_POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace Inherit option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace Log option.
_POSIX_TRACE_LOG = libc::_SC_TRACE_LOG,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Typed Memory Objects option.
_POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS,
@@ -2508,31 +2811,55 @@ pub enum SysconfVar {
/// to which the implementation conforms. For implementations conforming to
/// POSIX.1-2008, the value shall be 200809L.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with
/// 32-bit `int`, `long`, `pointer`, and `off_t` types.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with
/// 32-bit `int`, `long`, and pointer types and an `off_t` type using at
/// least 64 bits.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with
/// 32-bit `int` and 64-bit `long`, `pointer`, and `off_t` types.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with an
/// `int` type using at least 32 bits and `long`, pointer, and `off_t` types
@@ -2563,40 +2890,76 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Environment Services and Utilities
/// option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Accounting option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Checkpoint/Restart option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Locate Batch Job Request option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Job Message Request option.
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Track Batch Job Request option.
_POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK,
@@ -2632,28 +2995,52 @@ pub enum SysconfVar {
PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX,
#[cfg(not(target_os = "haiku"))]
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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
RTSIG_MAX = libc::_SC_RTSIG_MAX,
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX,
#[cfg(not(target_os = "redox"))]
@@ -2661,33 +3048,63 @@ pub enum SysconfVar {
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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the X/Open Encryption Option Group.
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Issue 4, Version 2 Enhanced
/// Internationalization Option Group.
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the X/Open Realtime Option Group.
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the X/Open Realtime Threads Option Group.
_XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS,
@@ -2696,36 +3113,54 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_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"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the XSI STREAMS Option Group.
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the XSI option
_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"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Integer value indicating version of the X/Open Portability Guide to
/// which the implementation conforms.
_XOPEN_VERSION = libc::_SC_XOPEN_VERSION,
/// The number of pages of physical memory. Note that it is possible for
/// the product of this value to overflow.
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_PHYS_PAGES = libc::_SC_PHYS_PAGES,
/// The number of currently available pages of physical memory.
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_AVPHYS_PAGES = libc::_SC_AVPHYS_PAGES,
/// The number of processors configured.
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_NPROCESSORS_CONF = libc::_SC_NPROCESSORS_CONF,
/// The number of processors currently online (available).
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_NPROCESSORS_ONLN = libc::_SC_NPROCESSORS_ONLN,
}
@@ -2797,9 +3232,9 @@ mod setres {
feature! {
#![feature = "user"]
- use crate::Result;
+ use super::{Gid, Uid};
use crate::errno::Errno;
- use super::{Uid, Gid};
+ use crate::Result;
/// Sets the real, effective, and saved uid.
/// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html))
@@ -2812,7 +3247,8 @@ mod setres {
/// Err is returned if the user doesn't have permission to set this UID.
#[inline]
pub fn setresuid(ruid: Uid, euid: Uid, suid: Uid) -> Result<()> {
- let res = unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
+ let res =
+ unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
Errno::result(res).map(drop)
}
@@ -2828,7 +3264,8 @@ mod setres {
/// Err is returned if the user doesn't have permission to set this GID.
#[inline]
pub fn setresgid(rgid: Gid, egid: Gid, sgid: Gid) -> Result<()> {
- let res = unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
+ let res =
+ unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
Errno::result(res).map(drop)
}
@@ -2846,16 +3283,16 @@ mod getres {
feature! {
#![feature = "user"]
- use crate::Result;
+ use super::{Gid, Uid};
use crate::errno::Errno;
- use super::{Uid, Gid};
+ use crate::Result;
/// Real, effective and saved user IDs.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ResUid {
pub real: Uid,
pub effective: Uid,
- pub saved: Uid
+ pub saved: Uid,
}
/// Real, effective and saved group IDs.
@@ -2863,7 +3300,7 @@ mod getres {
pub struct ResGid {
pub real: Gid,
pub effective: Gid,
- pub saved: Gid
+ pub saved: Gid,
}
/// Gets the real, effective, and saved user IDs.
@@ -2882,7 +3319,11 @@ mod getres {
let mut suid = libc::uid_t::max_value();
let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) };
- Errno::result(res).map(|_| ResUid{ real: Uid(ruid), effective: Uid(euid), saved: Uid(suid) })
+ Errno::result(res).map(|_| ResUid {
+ real: Uid(ruid),
+ effective: Uid(euid),
+ saved: Uid(suid),
+ })
}
/// Gets the real, effective, and saved group IDs.
@@ -2901,7 +3342,11 @@ mod getres {
let mut sgid = libc::gid_t::max_value();
let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) };
- Errno::result(res).map(|_| ResGid { real: Gid(rgid), effective: Gid(egid), saved: Gid(sgid) } )
+ Errno::result(res).map(|_| ResGid {
+ real: Gid(rgid),
+ effective: Gid(egid),
+ saved: Gid(sgid),
+ })
}
}
}
@@ -2945,11 +3390,19 @@ pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html)
// redox: does not appear to support the *at family of syscalls.
#[cfg(not(target_os = "redox"))]
-pub fn faccessat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: AccessFlags, flags: AtFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::faccessat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits(), flags.bits())
- }
+pub fn faccessat<P: ?Sized + NixPath>(
+ dirfd: Option<RawFd>,
+ path: &P,
+ mode: AccessFlags,
+ flags: AtFlags,
+) -> Result<()> {
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::faccessat(
+ at_rawfd(dirfd),
+ cstr.as_ptr(),
+ mode.bits(),
+ flags.bits(),
+ )
})?;
Errno::result(res).map(drop)
}
@@ -3002,32 +3455,38 @@ pub struct User {
/// Path to shell
pub shell: PathBuf,
/// Login class
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub class: CString,
/// Last password change
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub change: libc::time_t,
/// Expiration time of account
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub expire: libc::time_t
+ pub expire: libc::time_t,
}
#[cfg(not(target_os = "redox"))] //RedoxFS does not support passwd
@@ -3035,35 +3494,71 @@ impl From<&libc::passwd> for User {
fn from(pw: &libc::passwd) -> User {
unsafe {
User {
- name: if pw.pw_name.is_null() { Default::default() } else { CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned() },
- passwd: if pw.pw_passwd.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes()).unwrap() },
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
- gecos: if pw.pw_gecos.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes()).unwrap() },
- dir: if pw.pw_dir.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_dir).to_bytes())) },
- shell: if pw.pw_shell.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_shell).to_bytes())) },
+ name: if pw.pw_name.is_null() {
+ Default::default()
+ } else {
+ CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned()
+ },
+ passwd: if pw.pw_passwd.is_null() {
+ Default::default()
+ } else {
+ CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes())
+ .unwrap()
+ },
+ #[cfg(not(all(
+ target_os = "android",
+ target_pointer_width = "32"
+ )))]
+ gecos: if pw.pw_gecos.is_null() {
+ Default::default()
+ } else {
+ CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes())
+ .unwrap()
+ },
+ dir: if pw.pw_dir.is_null() {
+ Default::default()
+ } else {
+ PathBuf::from(OsStr::from_bytes(
+ CStr::from_ptr(pw.pw_dir).to_bytes(),
+ ))
+ },
+ shell: if pw.pw_shell.is_null() {
+ Default::default()
+ } else {
+ PathBuf::from(OsStr::from_bytes(
+ CStr::from_ptr(pw.pw_shell).to_bytes(),
+ ))
+ },
uid: Uid::from_raw(pw.pw_uid),
gid: Gid::from_raw(pw.pw_gid),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes()).unwrap(),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
+ class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes())
+ .unwrap(),
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
change: pw.pw_change,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- expire: pw.pw_expire
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
+ expire: pw.pw_expire,
}
}
}
@@ -3087,32 +3582,41 @@ impl From<User> for libc::passwd {
Self {
pw_name: name,
pw_passwd: u.passwd.into_raw(),
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
+ #[cfg(not(all(
+ target_os = "android",
+ target_pointer_width = "32"
+ )))]
pw_gecos: u.gecos.into_raw(),
pw_dir: dir,
pw_shell: shell,
pw_uid: u.uid.0,
pw_gid: u.gid.0,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
pw_class: u.class.into_raw(),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
pw_change: u.change,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
pw_expire: u.expire,
#[cfg(target_os = "illumos")]
pw_age: CString::new("").unwrap().into_raw(),
@@ -3128,10 +3632,12 @@ impl From<User> for libc::passwd {
impl User {
fn from_anything<F>(f: F) -> Result<Option<Self>>
where
- F: Fn(*mut libc::passwd,
- *mut c_char,
- libc::size_t,
- *mut *mut libc::passwd) -> libc::c_int
+ F: Fn(
+ *mut libc::passwd,
+ *mut c_char,
+ libc::size_t,
+ *mut *mut libc::passwd,
+ ) -> libc::c_int,
{
let buflimit = 1048576;
let bufsize = match sysconf(SysconfVar::GETPW_R_SIZE_MAX) {
@@ -3144,7 +3650,12 @@ impl User {
let mut res = ptr::null_mut();
loop {
- let error = f(pwd.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
+ let error = f(
+ pwd.as_mut_ptr(),
+ cbuf.as_mut_ptr(),
+ cbuf.capacity(),
+ &mut res,
+ );
if error == 0 {
if res.is_null() {
return Ok(None);
@@ -3175,8 +3686,8 @@ impl User {
/// assert_eq!(res.name, "root");
/// ```
pub fn from_uid(uid: Uid) -> Result<Option<Self>> {
- User::from_anything(|pwd, cbuf, cap, res| {
- unsafe { libc::getpwuid_r(uid.0, pwd, cbuf, cap, res) }
+ User::from_anything(|pwd, cbuf, cap, res| unsafe {
+ libc::getpwuid_r(uid.0, pwd, cbuf, cap, res)
})
}
@@ -3198,8 +3709,8 @@ impl User {
Ok(c_str) => c_str,
Err(_nul_error) => return Ok(None),
};
- User::from_anything(|pwd, cbuf, cap, res| {
- unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) }
+ User::from_anything(|pwd, cbuf, cap, res| unsafe {
+ libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res)
})
}
}
@@ -3215,7 +3726,7 @@ pub struct Group {
/// Group ID
pub gid: Gid,
/// List of Group members
- pub mem: Vec<String>
+ pub mem: Vec<String>,
}
#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
@@ -3224,9 +3735,10 @@ impl From<&libc::group> for Group {
unsafe {
Group {
name: CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned(),
- passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes()).unwrap(),
+ passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes())
+ .unwrap(),
gid: Gid::from_raw(gr.gr_gid),
- mem: Group::members(gr.gr_mem)
+ mem: Group::members(gr.gr_mem),
}
}
}
@@ -3252,10 +3764,12 @@ impl Group {
fn from_anything<F>(f: F) -> Result<Option<Self>>
where
- F: Fn(*mut libc::group,
- *mut c_char,
- libc::size_t,
- *mut *mut libc::group) -> libc::c_int
+ F: Fn(
+ *mut libc::group,
+ *mut c_char,
+ libc::size_t,
+ *mut *mut libc::group,
+ ) -> libc::c_int,
{
let buflimit = 1048576;
let bufsize = match sysconf(SysconfVar::GETGR_R_SIZE_MAX) {
@@ -3268,7 +3782,12 @@ impl Group {
let mut res = ptr::null_mut();
loop {
- let error = f(grp.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
+ let error = f(
+ grp.as_mut_ptr(),
+ cbuf.as_mut_ptr(),
+ cbuf.capacity(),
+ &mut res,
+ );
if error == 0 {
if res.is_null() {
return Ok(None);
@@ -3301,8 +3820,8 @@ impl Group {
/// assert!(res.name == "root");
/// ```
pub fn from_gid(gid: Gid) -> Result<Option<Self>> {
- Group::from_anything(|grp, cbuf, cap, res| {
- unsafe { libc::getgrgid_r(gid.0, grp, cbuf, cap, res) }
+ Group::from_anything(|grp, cbuf, cap, res| unsafe {
+ libc::getgrgid_r(gid.0, grp, cbuf, cap, res)
})
}
@@ -3326,8 +3845,8 @@ impl Group {
Ok(c_str) => c_str,
Err(_nul_error) => return Ok(None),
};
- Group::from_anything(|grp, cbuf, cap, res| {
- unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) }
+ Group::from_anything(|grp, cbuf, cap, res| unsafe {
+ libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res)
})
}
}