summaryrefslogtreecommitdiffstats
path: root/third_party/rust/nix/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/nix/src/sys')
-rw-r--r--third_party/rust/nix/src/sys/aio.rs80
-rw-r--r--third_party/rust/nix/src/sys/epoll.rs25
-rw-r--r--third_party/rust/nix/src/sys/event.rs171
-rw-r--r--third_party/rust/nix/src/sys/eventfd.rs77
-rw-r--r--third_party/rust/nix/src/sys/fanotify.rs416
-rw-r--r--third_party/rust/nix/src/sys/inotify.rs16
-rw-r--r--third_party/rust/nix/src/sys/ioctl/bsd.rs4
-rw-r--r--third_party/rust/nix/src/sys/ioctl/linux.rs2
-rw-r--r--third_party/rust/nix/src/sys/ioctl/mod.rs112
-rw-r--r--third_party/rust/nix/src/sys/memfd.rs43
-rw-r--r--third_party/rust/nix/src/sys/mman.rs320
-rw-r--r--third_party/rust/nix/src/sys/mod.rs82
-rw-r--r--third_party/rust/nix/src/sys/personality.rs2
-rw-r--r--third_party/rust/nix/src/sys/prctl.rs23
-rw-r--r--third_party/rust/nix/src/sys/ptrace/bsd.rs42
-rw-r--r--third_party/rust/nix/src/sys/ptrace/linux.rs58
-rw-r--r--third_party/rust/nix/src/sys/ptrace/mod.rs20
-rw-r--r--third_party/rust/nix/src/sys/quota.rs6
-rw-r--r--third_party/rust/nix/src/sys/reboot.rs175
-rw-r--r--third_party/rust/nix/src/sys/resource.rs109
-rw-r--r--third_party/rust/nix/src/sys/select.rs267
-rw-r--r--third_party/rust/nix/src/sys/sendfile.rs116
-rw-r--r--third_party/rust/nix/src/sys/signal.rs461
-rw-r--r--third_party/rust/nix/src/sys/signalfd.rs66
-rw-r--r--third_party/rust/nix/src/sys/socket/addr.rs873
-rw-r--r--third_party/rust/nix/src/sys/socket/mod.rs943
-rw-r--r--third_party/rust/nix/src/sys/socket/sockopt.rs454
-rw-r--r--third_party/rust/nix/src/sys/stat.rs73
-rw-r--r--third_party/rust/nix/src/sys/statfs.rs363
-rw-r--r--third_party/rust/nix/src/sys/statvfs.rs48
-rw-r--r--third_party/rust/nix/src/sys/termios.rs570
-rw-r--r--third_party/rust/nix/src/sys/time.rs121
-rw-r--r--third_party/rust/nix/src/sys/timerfd.rs2
-rw-r--r--third_party/rust/nix/src/sys/uio.rs49
-rw-r--r--third_party/rust/nix/src/sys/utsname.rs23
-rw-r--r--third_party/rust/nix/src/sys/wait.rs58
36 files changed, 2685 insertions, 3585 deletions
diff --git a/third_party/rust/nix/src/sys/aio.rs b/third_party/rust/nix/src/sys/aio.rs
index 5471177e3e..e9213c6434 100644
--- a/third_party/rust/nix/src/sys/aio.rs
+++ b/third_party/rust/nix/src/sys/aio.rs
@@ -35,7 +35,7 @@ use std::{
ptr, thread,
};
-use libc::{c_void, off_t};
+use libc::off_t;
use pin_utils::unsafe_pinned;
use crate::{
@@ -53,12 +53,9 @@ libc_enum! {
/// do it like `fsync`
O_SYNC,
/// on supported operating systems only, do it like `fdatasync`
- #[cfg(any(target_os = "ios",
+ #[cfg(any(apple_targets,
target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ netbsdlike))]
O_DSYNC
}
impl TryFrom<i32>
@@ -161,7 +158,7 @@ impl AioCb {
let r = unsafe { libc::aio_error(&self.aiocb().0) };
match r {
0 => Ok(()),
- num if num > 0 => Err(Errno::from_i32(num)),
+ num if num > 0 => Err(Errno::from_raw(num)),
-1 => Err(Errno::last()),
num => panic!("unknown aio_error return value {num:?}"),
}
@@ -581,7 +578,7 @@ impl<'a> AioRead<'a> {
) -> Self {
let mut aiocb = AioCb::common_init(fd, prio, sigev_notify);
aiocb.aiocb.0.aio_nbytes = buf.len();
- aiocb.aiocb.0.aio_buf = buf.as_mut_ptr() as *mut c_void;
+ aiocb.aiocb.0.aio_buf = buf.as_mut_ptr().cast();
aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READ;
aiocb.aiocb.0.aio_offset = offs;
AioRead {
@@ -702,7 +699,7 @@ impl<'a> AioReadv<'a> {
// In vectored mode, aio_nbytes stores the length of the iovec array,
// not the byte count.
aiocb.aiocb.0.aio_nbytes = bufs.len();
- aiocb.aiocb.0.aio_buf = bufs.as_mut_ptr() as *mut c_void;
+ aiocb.aiocb.0.aio_buf = bufs.as_mut_ptr().cast();
aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READV;
aiocb.aiocb.0.aio_offset = offs;
AioReadv {
@@ -817,7 +814,7 @@ impl<'a> AioWrite<'a> {
// but technically its only unsafe to dereference it, not to create
// it. Type Safety guarantees that we'll never pass aiocb to
// aio_read or aio_readv.
- aiocb.aiocb.0.aio_buf = buf.as_ptr() as *mut c_void;
+ aiocb.aiocb.0.aio_buf = buf.as_ptr().cast_mut().cast();
aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITE;
aiocb.aiocb.0.aio_offset = offs;
AioWrite {
@@ -935,7 +932,7 @@ impl<'a> AioWritev<'a> {
// but technically its only unsafe to dereference it, not to create
// it. Type Safety guarantees that we'll never pass aiocb to
// aio_read or aio_readv.
- aiocb.aiocb.0.aio_buf = bufs.as_ptr() as *mut c_void;
+ aiocb.aiocb.0.aio_buf = bufs.as_ptr().cast_mut().cast();
aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITEV;
aiocb.aiocb.0.aio_offset = offs;
AioWritev {
@@ -1055,7 +1052,8 @@ pub fn aio_suspend(
// generic, and accepting arguments like &[AioWrite]. But that would
// prevent using aio_suspend to wait on a heterogeneous list of mixed
// operations.
- let v = list.iter()
+ let v = list
+ .iter()
.map(|x| x.as_ref() as *const libc::aiocb)
.collect::<Vec<*const libc::aiocb>>();
let p = v.as_ptr();
@@ -1175,7 +1173,10 @@ pub fn aio_suspend(
/// // notification, we know that all operations are complete.
/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
/// ```
-#[deprecated(since = "0.27.0", note = "https://github.com/nix-rust/nix/issues/2017")]
+#[deprecated(
+ since = "0.27.0",
+ note = "https://github.com/nix-rust/nix/issues/2017"
+)]
pub fn lio_listio(
mode: LioMode,
list: &mut [Pin<&mut dyn AsMut<libc::aiocb>>],
@@ -1190,56 +1191,3 @@ pub fn lio_listio(
})
.map(drop)
}
-
-#[cfg(test)]
-mod t {
- use super::*;
-
- /// aio_suspend relies on casting Rust Aio* struct pointers to libc::aiocb
- /// pointers. This test ensures that such casts are valid.
- #[test]
- fn casting() {
- let sev = SigevNotify::SigevNone;
- let aiof = AioFsync::new(666, AioFsyncMode::O_SYNC, 0, sev);
- assert_eq!(
- aiof.as_ref() as *const libc::aiocb,
- &aiof as *const AioFsync as *const libc::aiocb
- );
-
- let mut rbuf = [];
- let aior = AioRead::new(666, 0, &mut rbuf, 0, sev);
- assert_eq!(
- aior.as_ref() as *const libc::aiocb,
- &aior as *const AioRead as *const libc::aiocb
- );
-
- let wbuf = [];
- let aiow = AioWrite::new(666, 0, &wbuf, 0, sev);
- assert_eq!(
- aiow.as_ref() as *const libc::aiocb,
- &aiow as *const AioWrite as *const libc::aiocb
- );
- }
-
- #[cfg(target_os = "freebsd")]
- #[test]
- fn casting_vectored() {
- let sev = SigevNotify::SigevNone;
-
- let mut rbuf = [];
- let mut rbufs = [IoSliceMut::new(&mut rbuf)];
- let aiorv = AioReadv::new(666, 0, &mut rbufs[..], 0, sev);
- assert_eq!(
- aiorv.as_ref() as *const libc::aiocb,
- &aiorv as *const AioReadv as *const libc::aiocb
- );
-
- let wbuf = [];
- let wbufs = [IoSlice::new(&wbuf)];
- let aiowv = AioWritev::new(666, 0, &wbufs, 0, sev);
- assert_eq!(
- aiowv.as_ref() as *const libc::aiocb,
- &aiowv as *const AioWritev as *const libc::aiocb
- );
- }
-}
diff --git a/third_party/rust/nix/src/sys/epoll.rs b/third_party/rust/nix/src/sys/epoll.rs
index 36f9c17d0e..ec146a8c53 100644
--- a/third_party/rust/nix/src/sys/epoll.rs
+++ b/third_party/rust/nix/src/sys/epoll.rs
@@ -1,4 +1,5 @@
use crate::errno::Errno;
+pub use crate::poll_timeout::PollTimeout as EpollTimeout;
use crate::Result;
use libc::{self, c_int};
use std::mem;
@@ -71,32 +72,32 @@ impl EpollEvent {
/// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html).
/// ```
-/// # use nix::sys::{epoll::{Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{eventfd, EfdFlags}};
+/// # use nix::sys::{epoll::{EpollTimeout, Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{EventFd, EfdFlags}};
/// # use nix::unistd::write;
-/// # use std::os::unix::io::{OwnedFd, FromRawFd, AsRawFd, AsFd};
+/// # use std::os::unix::io::{OwnedFd, FromRawFd, AsFd};
/// # use std::time::{Instant, Duration};
/// # fn main() -> nix::Result<()> {
/// const DATA: u64 = 17;
-/// const MILLIS: u64 = 100;
+/// const MILLIS: u8 = 100;
///
/// // Create epoll
/// let epoll = Epoll::new(EpollCreateFlags::empty())?;
///
/// // Create eventfd & Add event
-/// let eventfd = eventfd(0, EfdFlags::empty())?;
+/// let eventfd = EventFd::new()?;
/// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
///
/// // Arm eventfd & Time wait
-/// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?;
+/// eventfd.arm()?;
/// let now = Instant::now();
///
/// // Wait on event
/// let mut events = [EpollEvent::empty()];
-/// epoll.wait(&mut events, MILLIS as isize)?;
+/// epoll.wait(&mut events, MILLIS)?;
///
/// // Assert data correct & timeout didn't occur
/// assert_eq!(events[0].data(), DATA);
-/// assert!(now.elapsed() < Duration::from_millis(MILLIS));
+/// assert!(now.elapsed().as_millis() < MILLIS.into());
/// # Ok(())
/// # }
/// ```
@@ -140,17 +141,17 @@ impl Epoll {
/// (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(
+ pub fn wait<T: Into<EpollTimeout>>(
&self,
events: &mut [EpollEvent],
- timeout: isize,
+ timeout: T,
) -> Result<usize> {
let res = unsafe {
libc::epoll_wait(
self.0.as_raw_fd(),
- events.as_mut_ptr() as *mut libc::epoll_event,
+ events.as_mut_ptr().cast(),
events.len() as c_int,
- timeout as c_int,
+ timeout.into().into(),
)
};
@@ -240,7 +241,7 @@ pub fn epoll_wait(
let res = unsafe {
libc::epoll_wait(
epfd,
- events.as_mut_ptr() as *mut libc::epoll_event,
+ events.as_mut_ptr().cast(),
events.len() as c_int,
timeout_ms as c_int,
)
diff --git a/third_party/rust/nix/src/sys/event.rs b/third_party/rust/nix/src/sys/event.rs
index ec7f7e277a..b294d27c70 100644
--- a/third_party/rust/nix/src/sys/event.rs
+++ b/third_party/rust/nix/src/sys/event.rs
@@ -10,6 +10,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::fd::{AsFd, BorrowedFd};
use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd};
use std::ptr;
@@ -29,6 +30,18 @@ pub struct KEvent {
#[derive(Debug)]
pub struct Kqueue(OwnedFd);
+impl AsFd for Kqueue {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ self.0.as_fd()
+ }
+}
+
+impl From<Kqueue> for OwnedFd {
+ fn from(value: Kqueue) -> Self {
+ value.0
+ }
+}
+
impl Kqueue {
/// Create a new kernel event queue.
pub fn new() -> Result<Self> {
@@ -63,9 +76,9 @@ impl Kqueue {
let res = unsafe {
libc::kevent(
self.0.as_raw_fd(),
- changelist.as_ptr() as *const libc::kevent,
+ changelist.as_ptr().cast(),
changelist.len() as type_of_nchanges,
- eventlist.as_mut_ptr() as *mut libc::kevent,
+ eventlist.as_mut_ptr().cast(),
eventlist.len() as type_of_nchanges,
if let Some(ref timeout) = timeout_opt {
timeout as *const timespec
@@ -78,13 +91,7 @@ impl Kqueue {
}
}
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "openbsd"
-))]
+#[cfg(any(freebsdlike, apple_targets, target_os = "openbsd"))]
type type_of_udata = *mut libc::c_void;
#[cfg(target_os = "netbsd")]
type type_of_udata = intptr_t;
@@ -109,10 +116,7 @@ libc_enum! {
/// Takes a descriptor as the identifier, and returns whenever one of
/// the specified exceptional conditions has occurred on the descriptor.
EVFILT_EXCEPT,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))]
+ #[cfg(any(freebsdlike, apple_targets))]
/// Establishes a file system monitor.
EVFILT_FS,
#[cfg(target_os = "freebsd")]
@@ -120,7 +124,7 @@ libc_enum! {
/// # See Also
/// [lio_listio(2)](https://www.freebsd.org/cgi/man.cgi?query=lio_listio)
EVFILT_LIO,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
/// Mach portsets
EVFILT_MACHPORT,
/// Notifies when a process performs one or more of the requested
@@ -144,13 +148,10 @@ libc_enum! {
EVFILT_SIGNAL,
/// Establishes a timer and notifies when the timer expires.
EVFILT_TIMER,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))]
+ #[cfg(any(freebsdlike, apple_targets))]
/// Notifies only when explicitly requested by the user.
EVFILT_USER,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
/// Virtual memory events
EVFILT_VM,
/// Notifies when a requested event happens on a specified file.
@@ -162,13 +163,7 @@ libc_enum! {
impl TryFrom<type_of_event_filter>
}
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "openbsd"
-))]
+#[cfg(any(freebsdlike, apple_targets, target_os = "openbsd"))]
#[doc(hidden)]
pub type type_of_event_flag = u16;
#[cfg(target_os = "netbsd")]
@@ -187,9 +182,7 @@ libc_bitflags! {
EV_DELETE;
#[allow(missing_docs)]
EV_DISABLE;
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
- target_os = "ios", target_os = "macos",
- target_os = "netbsd", target_os = "openbsd"))]
+ #[cfg(bsd)]
#[allow(missing_docs)]
EV_DISPATCH;
#[cfg(target_os = "freebsd")]
@@ -201,7 +194,7 @@ libc_bitflags! {
EV_EOF;
#[allow(missing_docs)]
EV_ERROR;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
EV_FLAG0;
#[allow(missing_docs)]
@@ -211,15 +204,13 @@ libc_bitflags! {
EV_NODATA;
#[allow(missing_docs)]
EV_ONESHOT;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
EV_OOBAND;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
EV_POLL;
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
- target_os = "ios", target_os = "macos",
- target_os = "netbsd", target_os = "openbsd"))]
+ #[cfg(bsd)]
#[allow(missing_docs)]
EV_RECEIPT;
}
@@ -231,7 +222,7 @@ libc_bitflags!(
// that wouldn't simply be repeating the man page.
#[allow(missing_docs)]
pub struct FilterFlag: u32 {
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_ABSOLUTE;
#[allow(missing_docs)]
@@ -247,45 +238,27 @@ libc_bitflags!(
NOTE_EXEC;
#[allow(missing_docs)]
NOTE_EXIT;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_EXITSTATUS;
#[allow(missing_docs)]
NOTE_EXTEND;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_FFAND;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_FFCOPY;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_FFCTRLMASK;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_FFLAGSMASK;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_FFNOP;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_FFOR;
#[allow(missing_docs)]
@@ -297,10 +270,12 @@ libc_bitflags!(
#[cfg(target_os = "freebsd")]
#[allow(missing_docs)]
NOTE_MSECONDS;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_NONE;
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
+ #[cfg(any(
+ apple_targets,
+ target_os = "freebsd"))]
#[allow(missing_docs)]
NOTE_NSECONDS;
#[cfg(target_os = "dragonfly")]
@@ -314,38 +289,39 @@ libc_bitflags!(
NOTE_RENAME;
#[allow(missing_docs)]
NOTE_REVOKE;
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
+ #[cfg(any(
+ apple_targets,
+ target_os = "freebsd"))]
#[allow(missing_docs)]
NOTE_SECONDS;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_SIGNAL;
#[allow(missing_docs)]
NOTE_TRACK;
#[allow(missing_docs)]
NOTE_TRACKERR;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(any(apple_targets, freebsdlike))]
#[allow(missing_docs)]
NOTE_TRIGGER;
#[cfg(target_os = "openbsd")]
#[allow(missing_docs)]
NOTE_TRUNCATE;
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
+ #[cfg(any(
+ apple_targets,
+ target_os = "freebsd"))]
#[allow(missing_docs)]
NOTE_USECONDS;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_VM_ERROR;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_VM_PRESSURE;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_VM_PRESSURE_SUDDEN_TERMINATE;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
NOTE_VM_PRESSURE_TERMINATE;
#[allow(missing_docs)]
@@ -443,13 +419,7 @@ pub fn kevent(
kq.kevent(changelist, eventlist, Some(timeout))
}
-#[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "openbsd"
-))]
+#[cfg(any(apple_targets, freebsdlike, target_os = "openbsd"))]
type type_of_nchanges = c_int;
#[cfg(target_os = "netbsd")]
type type_of_nchanges = size_t;
@@ -484,42 +454,3 @@ pub fn ev_set(
ev.kevent.data = 0;
ev.kevent.udata = udata as type_of_udata;
}
-
-#[test]
-fn test_struct_kevent() {
- use std::mem;
-
- let udata: intptr_t = 12345;
-
- let actual = KEvent::new(
- 0xdead_beef,
- EventFilter::EVFILT_READ,
- EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
- FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
- 0x1337,
- udata,
- );
- assert_eq!(0xdead_beef, actual.ident());
- let filter = actual.kevent.filter;
- assert_eq!(libc::EVFILT_READ, filter);
- assert_eq!(libc::EV_ONESHOT | libc::EV_ADD, actual.flags().bits());
- assert_eq!(libc::NOTE_CHILD | libc::NOTE_EXIT, actual.fflags().bits());
- assert_eq!(0x1337, actual.data());
- assert_eq!(udata as type_of_udata, actual.udata() as type_of_udata);
- assert_eq!(mem::size_of::<libc::kevent>(), mem::size_of::<KEvent>());
-}
-
-#[test]
-fn test_kevent_filter() {
- let udata: intptr_t = 12345;
-
- let actual = KEvent::new(
- 0xdead_beef,
- EventFilter::EVFILT_READ,
- EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
- FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
- 0x1337,
- udata,
- );
- assert_eq!(EventFilter::EVFILT_READ, actual.filter().unwrap());
-}
diff --git a/third_party/rust/nix/src/sys/eventfd.rs b/third_party/rust/nix/src/sys/eventfd.rs
index f1723519cf..50a4f091bd 100644
--- a/third_party/rust/nix/src/sys/eventfd.rs
+++ b/third_party/rust/nix/src/sys/eventfd.rs
@@ -1,17 +1,84 @@
use crate::errno::Errno;
-use crate::Result;
-use std::os::unix::io::{FromRawFd, OwnedFd};
+use crate::{Result,unistd};
+use std::os::unix::io::{FromRawFd, OwnedFd, AsRawFd, AsFd, RawFd, BorrowedFd};
libc_bitflags! {
pub struct EfdFlags: libc::c_int {
- EFD_CLOEXEC; // Since Linux 2.6.27
- EFD_NONBLOCK; // Since Linux 2.6.27
- EFD_SEMAPHORE; // Since Linux 2.6.30
+ EFD_CLOEXEC; // Since Linux 2.6.27/FreeBSD 13.0
+ EFD_NONBLOCK; // Since Linux 2.6.27/FreeBSD 13.0
+ EFD_SEMAPHORE; // Since Linux 2.6.30/FreeBSD 13.0
}
}
+#[deprecated(since = "0.28.0", note = "Use EventFd::from_value_and_flags() instead")]
pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd> {
let res = unsafe { libc::eventfd(initval, flags.bits()) };
Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r) })
}
+
+#[derive(Debug)]
+#[repr(transparent)]
+pub struct EventFd(OwnedFd);
+impl EventFd {
+ /// [`EventFd::from_value_and_flags`] with `init_val = 0` and `flags = EfdFlags::empty()`.
+ pub fn new() -> Result<Self> {
+ Self::from_value_and_flags(0, EfdFlags::empty())
+ }
+ /// Constructs [`EventFd`] with the given `init_val` and `flags`.
+ ///
+ /// Wrapper around [`libc::eventfd`].
+ pub fn from_value_and_flags(init_val: u32, flags: EfdFlags) -> Result<Self> {
+ let res = unsafe { libc::eventfd(init_val, flags.bits()) };
+ Errno::result(res).map(|r| Self(unsafe { OwnedFd::from_raw_fd(r) }))
+ }
+ /// [`EventFd::from_value_and_flags`] with `init_val = 0` and given `flags`.
+ pub fn from_flags(flags: EfdFlags) -> Result<Self> {
+ Self::from_value_and_flags(0, flags)
+ }
+ /// [`EventFd::from_value_and_flags`] with given `init_val` and `flags = EfdFlags::empty()`.
+ pub fn from_value(init_val: u32) -> Result<Self> {
+ Self::from_value_and_flags(init_val, EfdFlags::empty())
+ }
+ /// Arms `self`, a following call to `poll`, `select` or `epoll` will return immediately.
+ ///
+ /// [`EventFd::write`] with `1`.
+ pub fn arm(&self) -> Result<usize> {
+ self.write(1)
+ }
+ /// Defuses `self`, a following call to `poll`, `select` or `epoll` will block.
+ ///
+ /// [`EventFd::write`] with `0`.
+ pub fn defuse(&self) -> Result<usize> {
+ self.write(0)
+ }
+ /// Enqueues `value` triggers.
+ ///
+ /// The next `value` calls to `poll`, `select` or `epoll` will return immediately.
+ ///
+ /// [`EventFd::write`] with `value`.
+ pub fn write(&self, value: u64) -> Result<usize> {
+ unistd::write(&self.0,&value.to_ne_bytes())
+ }
+ // Reads the value from the file descriptor.
+ pub fn read(&self) -> Result<u64> {
+ let mut arr = [0; std::mem::size_of::<u64>()];
+ unistd::read(self.0.as_raw_fd(),&mut arr)?;
+ Ok(u64::from_ne_bytes(arr))
+ }
+}
+impl AsFd for EventFd {
+ fn as_fd(&self) -> BorrowedFd {
+ self.0.as_fd()
+ }
+}
+impl AsRawFd for EventFd {
+ fn as_raw_fd(&self) -> RawFd {
+ self.0.as_raw_fd()
+ }
+}
+impl From<EventFd> for OwnedFd {
+ fn from(x: EventFd) -> OwnedFd {
+ x.0
+ }
+}
diff --git a/third_party/rust/nix/src/sys/fanotify.rs b/third_party/rust/nix/src/sys/fanotify.rs
new file mode 100644
index 0000000000..e217406e02
--- /dev/null
+++ b/third_party/rust/nix/src/sys/fanotify.rs
@@ -0,0 +1,416 @@
+//! Monitoring API for filesystem events.
+//!
+//! Fanotify is a Linux-only API to monitor filesystems events.
+//!
+//! Additional capabilities compared to the `inotify` API include the ability to
+//! monitor all of the objects in a mounted filesystem, the ability to make
+//! access permission decisions, and the possibility to read or modify files
+//! before access by other applications.
+//!
+//! For more documentation, please read
+//! [fanotify(7)](https://man7.org/linux/man-pages/man7/fanotify.7.html).
+
+use crate::errno::Errno;
+use crate::fcntl::{at_rawfd, OFlag};
+use crate::unistd::{close, read, write};
+use crate::{NixPath, Result};
+use std::marker::PhantomData;
+use std::mem::{size_of, MaybeUninit};
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
+use std::ptr;
+
+libc_bitflags! {
+ /// Mask for defining which events shall be listened with
+ /// [`fanotify_mark`](fn.fanotify_mark.html) and for querying notifications.
+ pub struct MaskFlags: u64 {
+ /// File was accessed.
+ FAN_ACCESS;
+ /// File was modified.
+ FAN_MODIFY;
+ /// Metadata has changed. Since Linux 5.1.
+ FAN_ATTRIB;
+ /// Writtable file was closed.
+ FAN_CLOSE_WRITE;
+ /// Unwrittable file was closed.
+ FAN_CLOSE_NOWRITE;
+ /// File was opened.
+ FAN_OPEN;
+ /// File was moved from X. Since Linux 5.1.
+ FAN_MOVED_FROM;
+ /// File was moved to Y. Since Linux 5.1.
+ FAN_MOVED_TO;
+ /// Subfile was created. Since Linux 5.1.
+ FAN_CREATE;
+ /// Subfile was deleted. Since Linux 5.1.
+ FAN_DELETE;
+ /// Self was deleted. Since Linux 5.1.
+ FAN_DELETE_SELF;
+ /// Self was moved. Since Linux 5.1.
+ FAN_MOVE_SELF;
+ /// File was opened for execution. Since Linux 5.0.
+ FAN_OPEN_EXEC;
+
+ /// Event queue overflowed.
+ FAN_Q_OVERFLOW;
+ /// Filesystem error. Since Linux 5.16.
+ FAN_FS_ERROR;
+
+ /// Permission to open file was requested.
+ FAN_OPEN_PERM;
+ /// Permission to access file was requested.
+ FAN_ACCESS_PERM;
+ /// Permission to open file for execution was requested. Since Linux
+ /// 5.0.
+ FAN_OPEN_EXEC_PERM;
+
+ /// Interested in child events.
+ FAN_EVENT_ON_CHILD;
+
+ /// File was renamed. Since Linux 5.17.
+ FAN_RENAME;
+
+ /// Event occurred against dir.
+ FAN_ONDIR;
+
+ /// Combination of `FAN_CLOSE_WRITE` and `FAN_CLOSE_NOWRITE`.
+ FAN_CLOSE;
+ /// Combination of `FAN_MOVED_FROM` and `FAN_MOVED_TO`.
+ FAN_MOVE;
+ }
+}
+
+libc_bitflags! {
+ /// Configuration options for [`fanotify_init`](fn.fanotify_init.html).
+ pub struct InitFlags: libc::c_uint {
+ /// Close-on-exec flag set on the file descriptor.
+ FAN_CLOEXEC;
+ /// Nonblocking flag set on the file descriptor.
+ FAN_NONBLOCK;
+
+ /// Receipt of events notifications.
+ FAN_CLASS_NOTIF;
+ /// Receipt of events for permission decisions, after they contain final
+ /// data.
+ FAN_CLASS_CONTENT;
+ /// Receipt of events for permission decisions, before they contain
+ /// final data.
+ FAN_CLASS_PRE_CONTENT;
+
+ /// Remove the limit of 16384 events for the event queue.
+ FAN_UNLIMITED_QUEUE;
+ /// Remove the limit of 8192 marks.
+ FAN_UNLIMITED_MARKS;
+
+ /// Make `FanotifyEvent::pid` return pidfd. Since Linux 5.15.
+ FAN_REPORT_PIDFD;
+ /// Make `FanotifyEvent::pid` return thread id. Since Linux 4.20.
+ FAN_REPORT_TID;
+ }
+}
+
+libc_bitflags! {
+ /// File status flags for fanotify events file descriptors.
+ pub struct EventFFlags: libc::c_uint {
+ /// Read only access.
+ O_RDONLY as libc::c_uint;
+ /// Write only access.
+ O_WRONLY as libc::c_uint;
+ /// Read and write access.
+ O_RDWR as libc::c_uint;
+ /// Support for files exceeded 2 GB.
+ O_LARGEFILE as libc::c_uint;
+ /// Close-on-exec flag for the file descriptor. Since Linux 3.18.
+ O_CLOEXEC as libc::c_uint;
+ /// Append mode for the file descriptor.
+ O_APPEND as libc::c_uint;
+ /// Synchronized I/O data integrity completion.
+ O_DSYNC as libc::c_uint;
+ /// No file last access time update.
+ O_NOATIME as libc::c_uint;
+ /// Nonblocking mode for the file descriptor.
+ O_NONBLOCK as libc::c_uint;
+ /// Synchronized I/O file integrity completion.
+ O_SYNC as libc::c_uint;
+ }
+}
+
+impl TryFrom<OFlag> for EventFFlags {
+ type Error = Errno;
+
+ fn try_from(o_flag: OFlag) -> Result<Self> {
+ EventFFlags::from_bits(o_flag.bits() as u32).ok_or(Errno::EINVAL)
+ }
+}
+
+impl From<EventFFlags> for OFlag {
+ fn from(event_f_flags: EventFFlags) -> Self {
+ OFlag::from_bits_retain(event_f_flags.bits() as i32)
+ }
+}
+
+libc_bitflags! {
+ /// Configuration options for [`fanotify_mark`](fn.fanotify_mark.html).
+ pub struct MarkFlags: libc::c_uint {
+ /// Add the events to the marks.
+ FAN_MARK_ADD;
+ /// Remove the events to the marks.
+ FAN_MARK_REMOVE;
+ /// Don't follow symlinks, mark them.
+ FAN_MARK_DONT_FOLLOW;
+ /// Raise an error if filesystem to be marked is not a directory.
+ FAN_MARK_ONLYDIR;
+ /// Events added to or removed from the marks.
+ FAN_MARK_IGNORED_MASK;
+ /// Ignore mask shall survive modify events.
+ FAN_MARK_IGNORED_SURV_MODIFY;
+ /// Remove all marks.
+ FAN_MARK_FLUSH;
+ /// Do not pin inode object in the inode cache. Since Linux 5.19.
+ FAN_MARK_EVICTABLE;
+ /// Events added to or removed from the marks. Since Linux 6.0.
+ FAN_MARK_IGNORE;
+
+ /// Default flag.
+ FAN_MARK_INODE;
+ /// Mark the mount specified by pathname.
+ FAN_MARK_MOUNT;
+ /// Mark the filesystem specified by pathname. Since Linux 4.20.
+ FAN_MARK_FILESYSTEM;
+
+ /// Combination of `FAN_MARK_IGNORE` and `FAN_MARK_IGNORED_SURV_MODIFY`.
+ FAN_MARK_IGNORE_SURV;
+ }
+}
+
+/// Compile version number of fanotify API.
+pub const FANOTIFY_METADATA_VERSION: u8 = libc::FANOTIFY_METADATA_VERSION;
+
+/// Abstract over `libc::fanotify_event_metadata`, which represents an event
+/// received via `Fanotify::read_events`.
+// Is not Clone due to fd field, to avoid use-after-close scenarios.
+#[derive(Debug, Eq, Hash, PartialEq)]
+#[repr(transparent)]
+#[allow(missing_copy_implementations)]
+pub struct FanotifyEvent(libc::fanotify_event_metadata);
+
+impl FanotifyEvent {
+ /// Version number for the structure. It must be compared to
+ /// `FANOTIFY_METADATA_VERSION` to verify compile version and runtime
+ /// version does match. It can be done with the
+ /// `FanotifyEvent::check_version` method.
+ pub fn version(&self) -> u8 {
+ self.0.vers
+ }
+
+ /// Checks that compile fanotify API version is equal to the version of the
+ /// event.
+ pub fn check_version(&self) -> bool {
+ self.version() == FANOTIFY_METADATA_VERSION
+ }
+
+ /// Mask flags of the events.
+ pub fn mask(&self) -> MaskFlags {
+ MaskFlags::from_bits_truncate(self.0.mask)
+ }
+
+ /// The file descriptor of the event. If the value is `None` when reading
+ /// from the fanotify group, this event is to notify that a group queue
+ /// overflow occured.
+ pub fn fd(&self) -> Option<BorrowedFd> {
+ if self.0.fd == libc::FAN_NOFD {
+ None
+ } else {
+ // SAFETY: self.0.fd will be opened for the lifetime of `Self`,
+ // which is longer than the lifetime of the returned BorrowedFd, so
+ // it is safe.
+ Some(unsafe { BorrowedFd::borrow_raw(self.0.fd) })
+ }
+ }
+
+ /// PID of the process that caused the event. TID in case flag
+ /// `FAN_REPORT_TID` was set at group initialization.
+ pub fn pid(&self) -> i32 {
+ self.0.pid
+ }
+}
+
+impl Drop for FanotifyEvent {
+ fn drop(&mut self) {
+ let e = close(self.0.fd);
+ if !std::thread::panicking() && e == Err(Errno::EBADF) {
+ panic!("Closing an invalid file descriptor!");
+ };
+ }
+}
+
+/// Abstraction over the structure to be sent to allow or deny a given event.
+#[derive(Debug)]
+#[repr(transparent)]
+pub struct FanotifyResponse<'a> {
+ inner: libc::fanotify_response,
+ _borrowed_fd: PhantomData<BorrowedFd<'a>>,
+}
+
+impl<'a> FanotifyResponse<'a> {
+ /// Create a new response.
+ pub fn new(fd: BorrowedFd<'a>, response: Response) -> Self {
+ Self {
+ inner: libc::fanotify_response {
+ fd: fd.as_raw_fd(),
+ response: response.bits(),
+ },
+ _borrowed_fd: PhantomData,
+ }
+ }
+}
+
+libc_bitflags! {
+ /// Response to be wrapped in `FanotifyResponse` and sent to the `Fanotify`
+ /// group to allow or deny an event.
+ pub struct Response: u32 {
+ /// Allow the event.
+ FAN_ALLOW;
+ /// Deny the event.
+ FAN_DENY;
+ }
+}
+
+/// A fanotify group. This is also a file descriptor that can feed to other
+/// interfaces consuming file descriptors.
+#[derive(Debug)]
+pub struct Fanotify {
+ fd: OwnedFd,
+}
+
+impl Fanotify {
+ /// Initialize a new fanotify group.
+ ///
+ /// Returns a Result containing a Fanotify instance.
+ ///
+ /// For more information, see [fanotify_init(2)](https://man7.org/linux/man-pages/man7/fanotify_init.2.html).
+ pub fn init(
+ flags: InitFlags,
+ event_f_flags: EventFFlags,
+ ) -> Result<Fanotify> {
+ let res = Errno::result(unsafe {
+ libc::fanotify_init(flags.bits(), event_f_flags.bits())
+ });
+ res.map(|fd| Fanotify {
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
+ })
+ }
+
+ /// Add, remove, or modify an fanotify mark on a filesystem object.
+ /// If `dirfd` is `None`, `AT_FDCWD` is used.
+ ///
+ /// Returns a Result containing either `()` on success or errno otherwise.
+ ///
+ /// For more information, see [fanotify_mark(2)](https://man7.org/linux/man-pages/man7/fanotify_mark.2.html).
+ pub fn mark<P: ?Sized + NixPath>(
+ &self,
+ flags: MarkFlags,
+ mask: MaskFlags,
+ dirfd: Option<RawFd>,
+ path: Option<&P>,
+ ) -> Result<()> {
+ fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
+ where
+ P: ?Sized + NixPath,
+ F: FnOnce(*const libc::c_char) -> T,
+ {
+ match p {
+ Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
+ None => Ok(f(std::ptr::null())),
+ }
+ }
+
+ let res = with_opt_nix_path(path, |p| unsafe {
+ libc::fanotify_mark(
+ self.fd.as_raw_fd(),
+ flags.bits(),
+ mask.bits(),
+ at_rawfd(dirfd),
+ p,
+ )
+ })?;
+
+ Errno::result(res).map(|_| ())
+ }
+
+ /// Read incoming events from the fanotify group.
+ ///
+ /// Returns a Result containing either a `Vec` of events on success or errno
+ /// otherwise.
+ ///
+ /// # Errors
+ ///
+ /// Possible errors can be those that are explicitly listed in
+ /// [fanotify(2)](https://man7.org/linux/man-pages/man7/fanotify.2.html) in
+ /// addition to the possible errors caused by `read` call.
+ /// In particular, `EAGAIN` is returned when no event is available on a
+ /// group that has been initialized with the flag `InitFlags::FAN_NONBLOCK`,
+ /// thus making this method nonblocking.
+ pub fn read_events(&self) -> Result<Vec<FanotifyEvent>> {
+ let metadata_size = size_of::<libc::fanotify_event_metadata>();
+ const BUFSIZ: usize = 4096;
+ let mut buffer = [0u8; BUFSIZ];
+ let mut events = Vec::new();
+ let mut offset = 0;
+
+ let nread = read(self.fd.as_raw_fd(), &mut buffer)?;
+
+ while (nread - offset) >= metadata_size {
+ let metadata = unsafe {
+ let mut metadata =
+ MaybeUninit::<libc::fanotify_event_metadata>::uninit();
+ ptr::copy_nonoverlapping(
+ buffer.as_ptr().add(offset),
+ metadata.as_mut_ptr().cast(),
+ (BUFSIZ - offset).min(metadata_size),
+ );
+ metadata.assume_init()
+ };
+
+ events.push(FanotifyEvent(metadata));
+ offset += metadata.event_len as usize;
+ }
+
+ Ok(events)
+ }
+
+ /// Write an event response on the fanotify group.
+ ///
+ /// Returns a Result containing either `()` on success or errno otherwise.
+ ///
+ /// # Errors
+ ///
+ /// Possible errors can be those that are explicitly listed in
+ /// [fanotify(2)](https://man7.org/linux/man-pages/man7/fanotify.2.html) in
+ /// addition to the possible errors caused by `write` call.
+ /// In particular, `EAGAIN` or `EWOULDBLOCK` is returned when no event is
+ /// available on a group that has been initialized with the flag
+ /// `InitFlags::FAN_NONBLOCK`, thus making this method nonblocking.
+ pub fn write_response(&self, response: FanotifyResponse) -> Result<()> {
+ write(self.fd.as_fd(), unsafe {
+ std::slice::from_raw_parts(
+ (&response.inner as *const libc::fanotify_response).cast(),
+ size_of::<libc::fanotify_response>(),
+ )
+ })?;
+ Ok(())
+ }
+}
+
+impl FromRawFd for Fanotify {
+ unsafe fn from_raw_fd(fd: RawFd) -> Self {
+ Fanotify {
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
+ }
+ }
+}
+
+impl AsFd for Fanotify {
+ fn as_fd(&'_ self) -> BorrowedFd<'_> {
+ self.fd.as_fd()
+ }
+}
diff --git a/third_party/rust/nix/src/sys/inotify.rs b/third_party/rust/nix/src/sys/inotify.rs
index e5fe930f49..9cbeb53973 100644
--- a/third_party/rust/nix/src/sys/inotify.rs
+++ b/third_party/rust/nix/src/sys/inotify.rs
@@ -143,7 +143,9 @@ impl Inotify {
pub fn init(flags: InitFlags) -> Result<Inotify> {
let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) });
- res.map(|fd| Inotify { fd: unsafe { OwnedFd::from_raw_fd(fd) } })
+ res.map(|fd| Inotify {
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
+ })
}
/// Adds a new watch on the target file or directory.
@@ -157,7 +159,11 @@ impl Inotify {
mask: AddWatchFlags,
) -> Result<WatchDescriptor> {
let res = path.with_nix_path(|cstr| unsafe {
- libc::inotify_add_watch(self.fd.as_raw_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 })
@@ -202,7 +208,7 @@ impl Inotify {
let mut event = MaybeUninit::<libc::inotify_event>::uninit();
ptr::copy_nonoverlapping(
buffer.as_ptr().add(offset),
- event.as_mut_ptr() as *mut u8,
+ event.as_mut_ptr().cast(),
(BUFSIZ - offset).min(header_size),
);
event.assume_init()
@@ -237,7 +243,9 @@ impl Inotify {
impl FromRawFd for Inotify {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
- Inotify { fd: OwnedFd::from_raw_fd(fd) }
+ Inotify {
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
+ }
}
}
diff --git a/third_party/rust/nix/src/sys/ioctl/bsd.rs b/third_party/rust/nix/src/sys/ioctl/bsd.rs
index 307994cb96..cedc8e63fe 100644
--- a/third_party/rust/nix/src/sys/ioctl/bsd.rs
+++ b/third_party/rust/nix/src/sys/ioctl/bsd.rs
@@ -1,10 +1,10 @@
/// The datatype used for the ioctl number
#[doc(hidden)]
-#[cfg(not(target_os = "illumos"))]
+#[cfg(not(solarish))]
pub type ioctl_num_type = ::libc::c_ulong;
#[doc(hidden)]
-#[cfg(target_os = "illumos")]
+#[cfg(solarish)]
pub type ioctl_num_type = ::libc::c_int;
/// The datatype used for the 3rd argument
diff --git a/third_party/rust/nix/src/sys/ioctl/linux.rs b/third_party/rust/nix/src/sys/ioctl/linux.rs
index 610b8ddac0..52312f4f04 100644
--- a/third_party/rust/nix/src/sys/ioctl/linux.rs
+++ b/third_party/rust/nix/src/sys/ioctl/linux.rs
@@ -19,7 +19,9 @@ pub const TYPEBITS: ioctl_num_type = 8;
cfg_if! {
if #[cfg(any(
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "sparc64"
diff --git a/third_party/rust/nix/src/sys/ioctl/mod.rs b/third_party/rust/nix/src/sys/ioctl/mod.rs
index 0b3fe3e769..e1e808f19e 100644
--- a/third_party/rust/nix/src/sys/ioctl/mod.rs
+++ b/third_party/rust/nix/src/sys/ioctl/mod.rs
@@ -72,7 +72,7 @@
//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
//! # const SPI_IOC_TYPE_MODE: u8 = 1;
//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> {
-//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data);
+//! let res = unsafe { libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data) };
//! Errno::result(res)
//! }
//! # fn main() {}
@@ -121,11 +121,11 @@
//!
//! ```
//! # #[macro_use] extern crate nix;
-//! # #[cfg(any(target_os = "android", target_os = "linux"))]
+//! # #[cfg(linux_android)]
//! # use nix::libc::TCGETS as TCGETS;
-//! # #[cfg(any(target_os = "android", target_os = "linux"))]
+//! # #[cfg(linux_android)]
//! # use nix::libc::termios as termios;
-//! # #[cfg(any(target_os = "android", target_os = "linux"))]
+//! # #[cfg(linux_android)]
//! ioctl_read_bad!(tcgets, TCGETS, termios);
//! # fn main() {}
//! ```
@@ -179,9 +179,13 @@
//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0;
//! # pub struct spi_ioc_transfer(u64);
//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> {
-//! let res = libc::ioctl(fd,
-//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
-//! data);
+//! let res = unsafe {
+//! libc::ioctl(
+//! fd,
+//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
+//! data
+//! )
+//! };
//! Errno::result(res)
//! }
//! # fn main() {}
@@ -223,40 +227,18 @@
//! ```
use cfg_if::cfg_if;
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
+#[cfg(any(linux_android, target_os = "redox"))]
#[macro_use]
mod linux;
-#[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "redox"
-))]
+#[cfg(any(linux_android, target_os = "redox"))]
pub use self::linux::*;
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
-))]
+#[cfg(any(bsd, solarish, target_os = "haiku",))]
#[macro_use]
mod bsd;
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
-))]
+#[cfg(any(bsd, solarish, target_os = "haiku",))]
pub use self::bsd::*;
/// Convert raw ioctl return value to a Nix result
@@ -305,7 +287,9 @@ macro_rules! ioctl_none {
$(#[$attr])*
pub unsafe fn $name(fd: $crate::libc::c_int)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
+ }
}
)
}
@@ -345,7 +329,9 @@ macro_rules! ioctl_none_bad {
$(#[$attr])*
pub unsafe fn $name(fd: $crate::libc::c_int)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
+ }
}
)
}
@@ -383,7 +369,9 @@ macro_rules! ioctl_read {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *mut $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -408,7 +396,7 @@ macro_rules! ioctl_read {
///
/// ```
/// # #[macro_use] extern crate nix;
-/// # #[cfg(any(target_os = "android", target_os = "linux"))]
+/// # #[cfg(linux_android)]
/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
/// # fn main() {}
/// ```
@@ -419,7 +407,9 @@ macro_rules! ioctl_read_bad {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *mut $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -456,7 +446,9 @@ macro_rules! ioctl_write_ptr {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *const $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -481,7 +473,7 @@ macro_rules! ioctl_write_ptr {
///
/// ```
/// # #[macro_use] extern crate nix;
-/// # #[cfg(any(target_os = "android", target_os = "linux"))]
+/// # #[cfg(linux_android)]
/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
/// # fn main() {}
/// ```
@@ -492,13 +484,15 @@ macro_rules! ioctl_write_ptr_bad {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *const $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
cfg_if! {
- if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
+ if #[cfg(freebsdlike)] {
/// Generates a wrapper function for a ioctl that writes an integer to the kernel.
///
/// The arguments to this macro are:
@@ -533,7 +527,9 @@ cfg_if! {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: $crate::sys::ioctl::ioctl_param_type)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -574,7 +570,9 @@ cfg_if! {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: $crate::sys::ioctl::ioctl_param_type)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -600,7 +598,7 @@ cfg_if! {
///
/// ```
/// # #[macro_use] extern crate nix;
-/// # #[cfg(any(target_os = "android", target_os = "linux"))]
+/// # #[cfg(linux_android)]
/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
/// # fn main() {}
/// ```
@@ -618,7 +616,9 @@ macro_rules! ioctl_write_int_bad {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: $crate::libc::c_int)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -655,7 +655,9 @@ macro_rules! ioctl_readwrite {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *mut $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -683,7 +685,9 @@ macro_rules! ioctl_readwrite_bad {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *mut $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ }
}
)
}
@@ -712,7 +716,9 @@ macro_rules! ioctl_read_buf {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: &mut [$ty])
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr()))
+ }
}
)
}
@@ -751,7 +757,9 @@ macro_rules! ioctl_write_buf {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: &[$ty])
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_ptr()))
+ }
}
)
}
@@ -780,7 +788,9 @@ macro_rules! ioctl_readwrite_buf {
pub unsafe fn $name(fd: $crate::libc::c_int,
data: &mut [$ty])
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data))
+ unsafe {
+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr()))
+ }
}
)
}
diff --git a/third_party/rust/nix/src/sys/memfd.rs b/third_party/rust/nix/src/sys/memfd.rs
index 516ffd3262..22ee5fc5b7 100644
--- a/third_party/rust/nix/src/sys/memfd.rs
+++ b/third_party/rust/nix/src/sys/memfd.rs
@@ -29,6 +29,49 @@ libc_bitflags!(
///
/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
MFD_ALLOW_SEALING;
+ /// Anonymous file will be created using huge pages. It should be safe now to
+ /// combine with [`MFD_ALLOW_SEALING`] too.
+ /// However, despite its presence, on FreeBSD it is unimplemented for now (ENOSYS).
+ ///
+ /// See also the hugetlb filesystem in [`memfd_create(2)`].
+ ///
+ /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
+ #[cfg(linux_android)]
+ MFD_HUGETLB;
+ /// Following are to be used with [`MFD_HUGETLB`], indicating the desired hugetlb size.
+ ///
+ /// See also the hugetlb filesystem in [`memfd_create(2)`].
+ ///
+ /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
+ #[cfg(linux_android)]
+ MFD_HUGE_1MB;
+ /// hugetlb size of 2MB.
+ #[cfg(linux_android)]
+ MFD_HUGE_2MB;
+ /// hugetlb size of 8MB.
+ #[cfg(linux_android)]
+ MFD_HUGE_8MB;
+ /// hugetlb size of 16MB.
+ #[cfg(linux_android)]
+ MFD_HUGE_16MB;
+ /// hugetlb size of 32MB.
+ #[cfg(linux_android)]
+ MFD_HUGE_32MB;
+ /// hugetlb size of 256MB.
+ #[cfg(linux_android)]
+ MFD_HUGE_256MB;
+ /// hugetlb size of 512MB.
+ #[cfg(linux_android)]
+ MFD_HUGE_512MB;
+ /// hugetlb size of 1GB.
+ #[cfg(linux_android)]
+ MFD_HUGE_1GB;
+ /// hugetlb size of 2GB.
+ #[cfg(linux_android)]
+ MFD_HUGE_2GB;
+ /// hugetlb size of 16GB.
+ #[cfg(linux_android)]
+ MFD_HUGE_16GB;
}
);
diff --git a/third_party/rust/nix/src/sys/mman.rs b/third_party/rust/nix/src/sys/mman.rs
index 8cfd6d6d54..a64f14f588 100644
--- a/third_party/rust/nix/src/sys/mman.rs
+++ b/third_party/rust/nix/src/sys/mman.rs
@@ -8,7 +8,11 @@ use crate::Result;
#[cfg(feature = "fs")]
use crate::{fcntl::OFlag, sys::stat::Mode};
use libc::{self, c_int, c_void, off_t, size_t};
-use std::{num::NonZeroUsize, os::unix::io::{AsRawFd, AsFd}};
+use std::ptr::NonNull;
+use std::{
+ num::NonZeroUsize,
+ os::unix::io::{AsFd, AsRawFd},
+};
libc_bitflags! {
/// Desired memory protection of a memory mapping.
@@ -22,12 +26,10 @@ libc_bitflags! {
/// Pages can be executed
PROT_EXEC;
/// Apply protection up to the end of a mapping that grows upwards.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
PROT_GROWSDOWN;
/// Apply protection down to the beginning of a mapping that grows downwards.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
PROT_GROWSUP;
}
}
@@ -45,145 +47,143 @@ libc_bitflags! {
MAP_FIXED;
/// Place the mapping at exactly the address specified in `addr`, but never clobber an existing range.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_FIXED_NOREPLACE;
/// To be used with `MAP_FIXED`, to forbid the system
/// to select a different address than the one specified.
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_EXCL;
/// Synonym for `MAP_ANONYMOUS`.
MAP_ANON;
/// The mapping is not backed by any file.
MAP_ANONYMOUS;
/// Put the mapping into the first 2GB of the process address space.
- #[cfg(any(all(any(target_os = "android", target_os = "linux"),
+ #[cfg(any(all(linux_android,
any(target_arch = "x86", target_arch = "x86_64")),
all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")),
all(target_os = "freebsd", target_pointer_width = "64")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_32BIT;
/// Used for stacks; indicates to the kernel that the mapping should extend downward in memory.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_GROWSDOWN;
/// Compatibility flag. Ignored.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_DENYWRITE;
/// Compatibility flag. Ignored.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_EXECUTABLE;
/// Mark the mmaped region to be locked in the same way as `mlock(2)`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_LOCKED;
/// Do not reserve swap space for this mapping.
///
/// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(freebsdlike, target_os = "aix", target_os = "hurd")))]
MAP_NORESERVE;
/// Populate page tables for a mapping.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_POPULATE;
/// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_NONBLOCK;
/// Allocate the mapping using "huge pages."
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_HUGETLB;
/// Make use of 64KB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_64KB;
/// Make use of 512KB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_512KB;
/// Make use of 1MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_1MB;
/// Make use of 2MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_2MB;
/// Make use of 8MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_8MB;
/// Make use of 16MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_16MB;
/// Make use of 32MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_32MB;
/// Make use of 256MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_256MB;
/// Make use of 512MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_512MB;
/// Make use of 1GB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_1GB;
/// Make use of 2GB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_2GB;
/// Make use of 16GB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_16GB;
/// Lock the mapped region into memory as with `mlock(2)`.
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_WIRED;
/// Causes dirtied data in the specified range to be flushed to disk only when necessary.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MAP_NOSYNC;
/// Rename private pages to a file.
///
/// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(netbsdlike)]
MAP_RENAME;
/// Region may contain semaphores.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(freebsdlike, netbsdlike))]
MAP_HASSEMAPHORE;
/// Region grows down, like a stack.
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, freebsdlike, target_os = "openbsd"))]
MAP_STACK;
/// Pages in this mapping are not retained in the kernel's memory cache.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MAP_NOCACHE;
/// Allows the W/X bit on the page, it's necessary on aarch64 architecture.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MAP_JIT;
/// Allows to use large pages, underlying alignment based on size.
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_ALIGNED_SUPER;
/// Pages will be discarded in the core dumps.
#[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_CONCEAL;
+ /// Attempt to place the mapping at exactly the address specified in `addr`.
+ /// it's a default behavior on OpenBSD.
+ #[cfg(netbsdlike)]
+ MAP_TRYFIXED;
+ }
+}
+
+impl MapFlags {
+ /// Create `MAP_HUGETLB` with provided size of huge page.
+ ///
+ /// Under the hood it computes `MAP_HUGETLB | (huge_page_size_log2 << libc::MAP_HUGE_SHIFT`).
+ /// `huge_page_size_log2` denotes logarithm of huge page size to use and should be
+ /// between 16 and 63 (inclusively).
+ ///
+ /// ```
+ /// # use nix::sys::mman::MapFlags;
+ /// let f = MapFlags::map_hugetlb_with_size_log2(30).unwrap();
+ /// assert_eq!(f, MapFlags::MAP_HUGETLB | MapFlags::MAP_HUGE_1GB);
+ /// ```
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
+ pub fn map_hugetlb_with_size_log2(
+ huge_page_size_log2: u32,
+ ) -> Option<Self> {
+ if (16..=63).contains(&huge_page_size_log2) {
+ let flag = libc::MAP_HUGETLB
+ | (huge_page_size_log2 << libc::MAP_HUGE_SHIFT) as i32;
+ Some(Self(flag.into()))
+ } else {
+ None
+ }
}
}
@@ -193,19 +193,15 @@ libc_bitflags! {
pub struct MRemapFlags: c_int {
/// Permit the kernel to relocate the mapping to a new virtual address, if necessary.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MREMAP_MAYMOVE;
/// Place the mapping at exactly the address specified in `new_address`.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MREMAP_FIXED;
/// Place the mapping at exactly the address specified in `new_address`.
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_FIXED;
/// Allows to duplicate the mapping to be able to apply different flags on the copy.
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_REMAPDUP;
}
}
@@ -228,30 +224,24 @@ libc_enum! {
/// Do not expect access in the near future.
MADV_DONTNEED,
/// Free up a given range of pages and its associated backing store.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_REMOVE,
/// Do not make pages in this range available to the child after a `fork(2)`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DONTFORK,
/// Undo the effect of `MADV_DONTFORK`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DOFORK,
/// Poison the given pages.
///
/// Subsequent references to those pages are treated like hardware memory corruption.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_HWPOISON,
/// Enable Kernel Samepage Merging (KSM) for the given pages.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_MERGEABLE,
/// Undo the effect of `MADV_MERGEABLE`
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_UNMERGEABLE,
/// Preserve the memory of each page but offline the original page.
#[cfg(any(target_os = "android",
@@ -266,68 +256,52 @@ libc_enum! {
target_arch = "sparc64"))))]
MADV_SOFT_OFFLINE,
/// Enable Transparent Huge Pages (THP) for pages in the given range.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_HUGEPAGE,
/// Undo the effect of `MADV_HUGEPAGE`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_NOHUGEPAGE,
/// Exclude the given range from a core dump.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DONTDUMP,
/// Undo the effect of an earlier `MADV_DONTDUMP`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DODUMP,
/// Specify that the application no longer needs the pages in the given range.
- #[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(target_os = "aix", target_os = "hurd")))]
MADV_FREE,
/// Request that the system not flush the current range to disk unless it needs to.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_NOSYNC,
/// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_AUTOSYNC,
/// Region is not included in a core file.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_NOCORE,
/// Include region in a core file
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_CORE,
/// This process should not be killed when swap space is exhausted.
#[cfg(any(target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MADV_PROTECT,
/// Invalidate the hardware page table for the given region.
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MADV_INVAL,
/// Set the offset of the page directory page to `value` for the virtual page table.
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MADV_SETMAP,
/// Indicates that the application will not need the data in the given range.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MADV_ZERO_WIRED_PAGES,
/// Pages can be reused (by anyone).
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MADV_FREE_REUSABLE,
/// Caller wants to reuse those pages.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MADV_FREE_REUSE,
// Darwin doesn't document this flag's behavior.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
MADV_CAN_REUSE,
}
@@ -341,12 +315,10 @@ libc_bitflags! {
/// Invalidate all cached data.
MS_INVALIDATE;
/// Invalidate pages, but leave them mapped.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MS_KILLPAGES;
/// Deactivate pages, but leave them mapped.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MS_DEACTIVATE;
/// Perform an update and wait for it to complete.
MS_SYNC;
@@ -374,8 +346,8 @@ libc_bitflags! {
/// `addr` must meet all the requirements described in the [`mlock(2)`] man page.
///
/// [`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html
-pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
- Errno::result(libc::mlock(addr, length)).map(drop)
+pub unsafe fn mlock(addr: NonNull<c_void>, length: size_t) -> Result<()> {
+ unsafe { Errno::result(libc::mlock(addr.as_ptr(), length)).map(drop) }
}
/// Unlocks all memory pages that contain part of the address range with
@@ -387,8 +359,8 @@ pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
/// page.
///
/// [`munlock(2)`]: https://man7.org/linux/man-pages/man2/munlock.2.html
-pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
- Errno::result(libc::munlock(addr, length)).map(drop)
+pub unsafe fn munlock(addr: NonNull<c_void>, length: size_t) -> Result<()> {
+ unsafe { Errno::result(libc::munlock(addr.as_ptr(), length)).map(drop) }
}
/// Locks all memory pages mapped into this process' address space.
@@ -411,7 +383,9 @@ pub fn munlockall() -> Result<()> {
unsafe { Errno::result(libc::munlockall()) }.map(drop)
}
-/// allocate memory, or map files or devices into memory
+/// Allocate memory, or map files or devices into memory
+///
+/// For anonymous mappings (`MAP_ANON`/`MAP_ANONYMOUS`), see [mmap_anonymous].
///
/// # Safety
///
@@ -423,20 +397,54 @@ pub unsafe fn mmap<F: AsFd>(
length: NonZeroUsize,
prot: ProtFlags,
flags: MapFlags,
- f: Option<F>,
+ f: F,
offset: off_t,
-) -> Result<*mut c_void> {
- let ptr =
- addr.map_or(std::ptr::null_mut(), |a| usize::from(a) as *mut c_void);
+) -> Result<NonNull<c_void>> {
+ let ptr = addr.map_or(std::ptr::null_mut(), |a| a.get() as *mut c_void);
- let fd = f.map(|f| f.as_fd().as_raw_fd()).unwrap_or(-1);
- let ret =
- libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset);
+ let fd = f.as_fd().as_raw_fd();
+ let ret = unsafe {
+ libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset)
+ };
+
+ if ret == libc::MAP_FAILED {
+ Err(Errno::last())
+ } else {
+ // SAFETY: `libc::mmap` returns a valid non-null pointer or `libc::MAP_FAILED`, thus `ret`
+ // will be non-null here.
+ Ok(unsafe { NonNull::new_unchecked(ret) })
+ }
+}
+
+/// Create an anonymous memory mapping.
+///
+/// This function is a wrapper around [`mmap`]:
+/// `mmap(ptr, len, prot, MAP_ANONYMOUS | flags, -1, 0)`.
+///
+/// # Safety
+///
+/// See the [`mmap(2)`] man page for detailed requirements.
+///
+/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
+pub unsafe fn mmap_anonymous(
+ addr: Option<NonZeroUsize>,
+ length: NonZeroUsize,
+ prot: ProtFlags,
+ flags: MapFlags,
+) -> Result<NonNull<c_void>> {
+ let ptr = addr.map_or(std::ptr::null_mut(), |a| a.get() as *mut c_void);
+
+ let flags = MapFlags::MAP_ANONYMOUS | flags;
+ let ret = unsafe {
+ libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), -1, 0)
+ };
if ret == libc::MAP_FAILED {
Err(Errno::last())
} else {
- Ok(ret)
+ // SAFETY: `libc::mmap` returns a valid non-null pointer or `libc::MAP_FAILED`, thus `ret`
+ // will be non-null here.
+ Ok(unsafe { NonNull::new_unchecked(ret) })
}
}
@@ -449,33 +457,43 @@ pub unsafe fn mmap<F: AsFd>(
/// detailed requirements.
#[cfg(any(target_os = "linux", target_os = "netbsd"))]
pub unsafe fn mremap(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
old_size: size_t,
new_size: size_t,
flags: MRemapFlags,
- new_address: Option<*mut c_void>,
-) -> Result<*mut c_void> {
+ new_address: Option<NonNull<c_void>>,
+) -> Result<NonNull<c_void>> {
#[cfg(target_os = "linux")]
- let ret = libc::mremap(
- addr,
- old_size,
- new_size,
- flags.bits(),
- new_address.unwrap_or(std::ptr::null_mut()),
- );
+ let ret = unsafe {
+ libc::mremap(
+ addr.as_ptr(),
+ old_size,
+ new_size,
+ flags.bits(),
+ new_address
+ .map(NonNull::as_ptr)
+ .unwrap_or(std::ptr::null_mut()),
+ )
+ };
#[cfg(target_os = "netbsd")]
- let ret = libc::mremap(
- addr,
- old_size,
- new_address.unwrap_or(std::ptr::null_mut()),
- new_size,
- flags.bits(),
- );
+ let ret = unsafe {
+ libc::mremap(
+ addr.as_ptr(),
+ old_size,
+ new_address
+ .map(NonNull::as_ptr)
+ .unwrap_or(std::ptr::null_mut()),
+ new_size,
+ flags.bits(),
+ )
+ };
if ret == libc::MAP_FAILED {
Err(Errno::last())
} else {
- Ok(ret)
+ // SAFETY: `libc::mremap` returns a valid non-null pointer or `libc::MAP_FAILED`, thus `ret`
+ // will be non-null here.
+ Ok(unsafe { NonNull::new_unchecked(ret) })
}
}
@@ -487,8 +505,8 @@ pub unsafe fn mremap(
/// page.
///
/// [`munmap(2)`]: https://man7.org/linux/man-pages/man2/munmap.2.html
-pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
- Errno::result(libc::munmap(addr, len)).map(drop)
+pub unsafe fn munmap(addr: NonNull<c_void>, len: size_t) -> Result<()> {
+ unsafe { Errno::result(libc::munmap(addr.as_ptr(), len)).map(drop) }
}
/// give advice about use of memory
@@ -499,12 +517,16 @@ pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
/// [`MmapAdvise::MADV_FREE`].
///
/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html
+#[allow(rustdoc::broken_intra_doc_links)] // For Hurd as `MADV_FREE` is not available on it
pub unsafe fn madvise(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
length: size_t,
advise: MmapAdvise,
) -> Result<()> {
- Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
+ unsafe {
+ Errno::result(libc::madvise(addr.as_ptr(), length, advise as i32))
+ .map(drop)
+ }
}
/// Set protection of memory mapping.
@@ -519,27 +541,30 @@ pub unsafe fn madvise(
///
/// ```
/// # use nix::libc::size_t;
-/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
+/// # use nix::sys::mman::{mmap_anonymous, mprotect, MapFlags, ProtFlags};
/// # use std::ptr;
/// # use std::os::unix::io::BorrowedFd;
/// const ONE_K: size_t = 1024;
/// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap();
/// let mut slice: &mut [u8] = unsafe {
-/// let mem = mmap::<BorrowedFd>(None, one_k_non_zero, ProtFlags::PROT_NONE,
-/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, None, 0).unwrap();
+/// let mem = mmap_anonymous(None, one_k_non_zero, ProtFlags::PROT_NONE, MapFlags::MAP_PRIVATE)
+/// .unwrap();
/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
-/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
+/// std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
/// };
/// assert_eq!(slice[0], 0x00);
/// slice[0] = 0xFF;
/// assert_eq!(slice[0], 0xFF);
/// ```
pub unsafe fn mprotect(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
length: size_t,
prot: ProtFlags,
) -> Result<()> {
- Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
+ unsafe {
+ Errno::result(libc::mprotect(addr.as_ptr(), length, prot.bits()))
+ .map(drop)
+ }
}
/// synchronize a mapped region
@@ -551,11 +576,14 @@ pub unsafe fn mprotect(
///
/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html
pub unsafe fn msync(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
length: size_t,
flags: MsFlags,
) -> Result<()> {
- Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
+ unsafe {
+ Errno::result(libc::msync(addr.as_ptr(), length, flags.bits()))
+ .map(drop)
+ }
}
#[cfg(not(target_os = "android"))]
@@ -576,11 +604,11 @@ pub fn shm_open<P>(
use std::os::unix::io::{FromRawFd, OwnedFd};
let ret = name.with_nix_path(|cstr| {
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
unsafe {
libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint)
}
- #[cfg(not(any(target_os = "macos", target_os = "ios")))]
+ #[cfg(not(apple_targets))]
unsafe {
libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t)
}
diff --git a/third_party/rust/nix/src/sys/mod.rs b/third_party/rust/nix/src/sys/mod.rs
index bf047b3dda..93339d1935 100644
--- a/third_party/rust/nix/src/sys/mod.rs
+++ b/third_party/rust/nix/src/sys/mod.rs
@@ -1,10 +1,8 @@
//! Mostly platform-specific functionality
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
+ freebsdlike,
all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "macos",
+ apple_targets,
target_os = "netbsd"
))]
feature! {
@@ -15,41 +13,31 @@ feature! {
feature! {
#![feature = "event"]
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[allow(missing_docs)]
pub mod epoll;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
+ #[cfg(bsd)]
pub mod event;
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(any(linux_android, target_os = "freebsd"))]
#[allow(missing_docs)]
pub mod eventfd;
}
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "redox",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
-))]
+#[cfg(target_os = "linux")]
+feature! {
+ #![feature = "fanotify"]
+ pub mod fanotify;
+}
+
+#[cfg(any(bsd, linux_android, target_os = "redox", solarish))]
#[cfg(feature = "ioctl")]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
#[macro_use]
pub mod ioctl;
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
feature! {
#![feature = "fs"]
pub mod memfd;
@@ -78,15 +66,7 @@ feature! {
pub mod pthread;
}
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
+#[cfg(any(linux_android, bsd))]
feature! {
#![feature = "ptrace"]
#[allow(missing_docs)]
@@ -99,7 +79,7 @@ feature! {
pub mod quota;
}
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", netbsdlike))]
feature! {
#![feature = "reboot"]
pub mod reboot;
@@ -108,7 +88,7 @@ feature! {
#[cfg(not(any(
target_os = "redox",
target_os = "fuchsia",
- target_os = "illumos",
+ solarish,
target_os = "haiku"
)))]
feature! {
@@ -121,14 +101,7 @@ feature! {
pub mod select;
}
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"
-))]
+#[cfg(any(linux_android, freebsdlike, apple_targets, solarish))]
feature! {
#![feature = "zerocopy"]
pub mod sendfile;
@@ -136,7 +109,7 @@ feature! {
pub mod signal;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
feature! {
#![feature = "signal"]
#[allow(missing_docs)]
@@ -155,15 +128,7 @@ feature! {
pub mod stat;
}
-#[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(linux_android, freebsdlike, apple_targets, target_os = "openbsd"))]
feature! {
#![feature = "fs"]
pub mod statfs;
@@ -174,8 +139,7 @@ feature! {
pub mod statvfs;
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub mod sysinfo;
@@ -203,13 +167,13 @@ feature! {
pub mod wait;
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
feature! {
#![feature = "inotify"]
pub mod inotify;
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
feature! {
#![feature = "time"]
pub mod timerfd;
@@ -218,7 +182,7 @@ feature! {
#[cfg(all(
any(
target_os = "freebsd",
- target_os = "illumos",
+ solarish,
target_os = "linux",
target_os = "netbsd"
),
diff --git a/third_party/rust/nix/src/sys/personality.rs b/third_party/rust/nix/src/sys/personality.rs
index 30231dd7b8..a4cfb5ef4f 100644
--- a/third_party/rust/nix/src/sys/personality.rs
+++ b/third_party/rust/nix/src/sys/personality.rs
@@ -21,7 +21,6 @@ libc_bitflags! {
ADDR_LIMIT_3GB;
/// User-space function pointers to signal handlers point to descriptors.
#[cfg(not(any(target_env = "musl", target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
FDPIC_FUNCPTRS;
/// Map page 0 as read-only.
MMAP_PAGE_ZERO;
@@ -43,7 +42,6 @@ libc_bitflags! {
///
/// [`uname(2)`]: https://man7.org/linux/man-pages/man2/uname.2.html
#[cfg(not(any(target_env = "musl", target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
UNAME26;
/// No effects.
WHOLE_SECONDS;
diff --git a/third_party/rust/nix/src/sys/prctl.rs b/third_party/rust/nix/src/sys/prctl.rs
index 995382cb0c..42324beab2 100644
--- a/third_party/rust/nix/src/sys/prctl.rs
+++ b/third_party/rust/nix/src/sys/prctl.rs
@@ -50,7 +50,9 @@ pub fn get_child_subreaper() -> Result<bool> {
// prctl writes into this var
let mut subreaper: c_int = 0;
- let res = unsafe { libc::prctl(libc::PR_GET_CHILD_SUBREAPER, &mut subreaper, 0, 0, 0) };
+ let res = unsafe {
+ libc::prctl(libc::PR_GET_CHILD_SUBREAPER, &mut subreaper, 0, 0, 0)
+ };
Errno::result(res).map(|_| subreaper != 0)
}
@@ -78,7 +80,9 @@ pub fn get_keepcaps() -> Result<bool> {
/// Clear the thread memory corruption kill policy and use the system-wide default
pub fn clear_mce_kill() -> Result<()> {
- let res = unsafe { libc::prctl(libc::PR_MCE_KILL, libc::PR_MCE_KILL_CLEAR, 0, 0, 0) };
+ let res = unsafe {
+ libc::prctl(libc::PR_MCE_KILL, libc::PR_MCE_KILL_CLEAR, 0, 0, 0)
+ };
Errno::result(res).map(drop)
}
@@ -151,10 +155,11 @@ pub fn get_name() -> Result<CString> {
let res = unsafe { libc::prctl(libc::PR_GET_NAME, &buf, 0, 0, 0) };
- let len = buf.iter().position(|&c| c == 0).unwrap_or(buf.len());
- let name = CStr::from_bytes_with_nul(&buf[..=len]).map_err(|_| Errno::EINVAL)?;
-
- Errno::result(res).map(|_| name.to_owned())
+ Errno::result(res).and_then(|_| {
+ CStr::from_bytes_until_nul(&buf)
+ .map(CStr::to_owned)
+ .map_err(|_| Errno::EINVAL)
+ })
}
/// Sets the timer slack value for the calling thread. Timer slack is used by the kernel to group
@@ -174,14 +179,16 @@ pub fn get_timerslack() -> Result<i32> {
/// Disable all performance counters attached to the calling process.
pub fn task_perf_events_disable() -> Result<()> {
- let res = unsafe { libc::prctl(libc::PR_TASK_PERF_EVENTS_DISABLE, 0, 0, 0, 0) };
+ let res =
+ unsafe { libc::prctl(libc::PR_TASK_PERF_EVENTS_DISABLE, 0, 0, 0, 0) };
Errno::result(res).map(drop)
}
/// Enable all performance counters attached to the calling process.
pub fn task_perf_events_enable() -> Result<()> {
- let res = unsafe { libc::prctl(libc::PR_TASK_PERF_EVENTS_ENABLE, 0, 0, 0, 0) };
+ let res =
+ unsafe { libc::prctl(libc::PR_TASK_PERF_EVENTS_ENABLE, 0, 0, 0, 0) };
Errno::result(res).map(drop)
}
diff --git a/third_party/rust/nix/src/sys/ptrace/bsd.rs b/third_party/rust/nix/src/sys/ptrace/bsd.rs
index ba267c6577..3dd486210c 100644
--- a/third_party/rust/nix/src/sys/ptrace/bsd.rs
+++ b/third_party/rust/nix/src/sys/ptrace/bsd.rs
@@ -9,10 +9,7 @@ use std::ptr;
pub type RequestType = c_int;
cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "openbsd"))] {
+ if #[cfg(any(freebsdlike, apple_targets, target_os = "openbsd"))] {
#[doc(hidden)]
pub type AddressType = *mut ::libc::c_char;
} else {
@@ -29,33 +26,26 @@ libc_enum! {
PT_TRACE_ME,
PT_READ_I,
PT_READ_D,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
PT_READ_U,
PT_WRITE_I,
PT_WRITE_D,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
PT_WRITE_U,
PT_CONTINUE,
PT_KILL,
- #[cfg(any(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos"),
+ #[cfg(any(any(freebsdlike, apple_targets),
all(target_os = "openbsd", target_arch = "x86_64"),
all(target_os = "netbsd", any(target_arch = "x86_64",
target_arch = "powerpc"))))]
PT_STEP,
PT_ATTACH,
PT_DETACH,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
PT_SIGEXC,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
PT_THUPDATE,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
PT_ATTACHEXC
}
}
@@ -66,13 +56,15 @@ unsafe fn ptrace_other(
addr: AddressType,
data: c_int,
) -> Result<c_int> {
- Errno::result(libc::ptrace(
- request as RequestType,
- libc::pid_t::from(pid),
- addr,
- data,
- ))
- .map(|_| 0)
+ unsafe {
+ Errno::result(libc::ptrace(
+ request as RequestType,
+ libc::pid_t::from(pid),
+ addr,
+ data,
+ ))
+ .map(|_| 0)
+ }
}
/// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)`
@@ -157,7 +149,7 @@ pub fn kill(pid: Pid) -> Result<()> {
/// }
/// ```
#[cfg(any(
- any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"),
+ any(freebsdlike, apple_targets),
all(target_os = "openbsd", target_arch = "x86_64"),
all(
target_os = "netbsd",
diff --git a/third_party/rust/nix/src/sys/ptrace/linux.rs b/third_party/rust/nix/src/sys/ptrace/linux.rs
index 8c134cf7ee..26544e134b 100644
--- a/third_party/rust/nix/src/sys/ptrace/linux.rs
+++ b/third_party/rust/nix/src/sys/ptrace/linux.rs
@@ -53,28 +53,36 @@ libc_enum! {
#[cfg(any(all(target_os = "android", target_pointer_width = "32"),
all(target_os = "linux", any(target_env = "musl",
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "x86_64",
target_pointer_width = "32"))))]
PTRACE_GETREGS,
#[cfg(any(all(target_os = "android", target_pointer_width = "32"),
all(target_os = "linux", any(target_env = "musl",
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "x86_64",
target_pointer_width = "32"))))]
PTRACE_SETREGS,
#[cfg(any(all(target_os = "android", target_pointer_width = "32"),
all(target_os = "linux", any(target_env = "musl",
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "x86_64",
target_pointer_width = "32"))))]
PTRACE_GETFPREGS,
#[cfg(any(all(target_os = "android", target_pointer_width = "32"),
all(target_os = "linux", any(target_env = "musl",
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "x86_64",
target_pointer_width = "32"))))]
PTRACE_SETFPREGS,
@@ -82,13 +90,17 @@ libc_enum! {
PTRACE_DETACH,
#[cfg(all(target_os = "linux", any(target_env = "musl",
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "x86",
target_arch = "x86_64")))]
PTRACE_GETFPXREGS,
#[cfg(all(target_os = "linux", any(target_env = "musl",
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "x86",
target_arch = "x86_64")))]
PTRACE_SETFPXREGS,
@@ -98,22 +110,28 @@ libc_enum! {
PTRACE_GETSIGINFO,
PTRACE_SETSIGINFO,
#[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6"))))]
PTRACE_GETREGSET,
#[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6"))))]
PTRACE_SETREGSET,
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
PTRACE_SEIZE,
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
PTRACE_INTERRUPT,
#[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6"))))]
PTRACE_LISTEN,
#[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6"))))]
PTRACE_PEEKSIGINFO,
#[cfg(all(target_os = "linux", target_env = "gnu",
any(target_arch = "x86", target_arch = "x86_64")))]
@@ -241,13 +259,13 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
/// and therefore use the data field to return values. This function handles these
/// requests.
fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
- let mut data = mem::MaybeUninit::uninit();
+ let mut data = mem::MaybeUninit::<T>::uninit();
let res = unsafe {
libc::ptrace(
request as RequestType,
libc::pid_t::from(pid),
ptr::null_mut::<T>(),
- data.as_mut_ptr() as *const _ as *const c_void,
+ data.as_mut_ptr(),
)
};
Errno::result(res)?;
@@ -260,13 +278,15 @@ unsafe fn ptrace_other(
addr: AddressType,
data: *mut c_void,
) -> Result<c_long> {
- Errno::result(libc::ptrace(
- request as RequestType,
- libc::pid_t::from(pid),
- addr,
- data,
- ))
- .map(|_| 0)
+ unsafe {
+ Errno::result(libc::ptrace(
+ request as RequestType,
+ libc::pid_t::from(pid),
+ addr,
+ data,
+ ))
+ .map(|_| 0)
+ }
}
/// Set options, as with `ptrace(PTRACE_SETOPTIONS, ...)`.
@@ -381,7 +401,6 @@ pub fn attach(pid: Pid) -> Result<()> {
///
/// Attaches to the process specified in pid, making it a tracee of the calling process.
#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn seize(pid: Pid, options: Options) -> Result<()> {
unsafe {
ptrace_other(
@@ -428,7 +447,6 @@ pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
///
/// This request is equivalent to `ptrace(PTRACE_INTERRUPT, ...)`
#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn interrupt(pid: Pid) -> Result<()> {
unsafe {
ptrace_other(
@@ -535,7 +553,7 @@ pub unsafe fn write(
addr: AddressType,
data: *mut c_void,
) -> Result<()> {
- ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
+ unsafe { ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop) }
}
/// Reads a word from a user area at `offset`, as with ptrace(PTRACE_PEEKUSER, ...).
@@ -556,5 +574,7 @@ pub unsafe fn write_user(
offset: AddressType,
data: *mut c_void,
) -> Result<()> {
- ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop)
+ unsafe {
+ ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop)
+ }
}
diff --git a/third_party/rust/nix/src/sys/ptrace/mod.rs b/third_party/rust/nix/src/sys/ptrace/mod.rs
index 88648acabc..c059797df9 100644
--- a/third_party/rust/nix/src/sys/ptrace/mod.rs
+++ b/third_party/rust/nix/src/sys/ptrace/mod.rs
@@ -1,25 +1,13 @@
//! Provides helpers for making ptrace system calls
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
mod linux;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
pub use self::linux::*;
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
+#[cfg(bsd)]
mod bsd;
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
+#[cfg(bsd)]
pub use self::bsd::*;
diff --git a/third_party/rust/nix/src/sys/quota.rs b/third_party/rust/nix/src/sys/quota.rs
index a32d07aa1e..2d12b858bf 100644
--- a/third_party/rust/nix/src/sys/quota.rs
+++ b/third_party/rust/nix/src/sys/quota.rs
@@ -264,7 +264,7 @@ pub fn quotactl_on<P: ?Sized + NixPath>(
) -> Result<()> {
quota_file.with_nix_path(|path| {
let mut path_copy = path.to_bytes_with_nul().to_owned();
- let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char;
+ let p: *mut c_char = path_copy.as_mut_ptr().cast();
quotactl(
QuotaCmd(QuotaSubCmd::Q_QUOTAON, which),
Some(special),
@@ -308,12 +308,12 @@ pub fn quotactl_get<P: ?Sized + NixPath>(
special: &P,
id: c_int,
) -> Result<Dqblk> {
- let mut dqblk = mem::MaybeUninit::uninit();
+ let mut dqblk = mem::MaybeUninit::<libc::dqblk>::uninit();
quotactl(
QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which),
Some(special),
id,
- dqblk.as_mut_ptr() as *mut c_char,
+ dqblk.as_mut_ptr().cast(),
)?;
Ok(unsafe { Dqblk(dqblk.assume_init()) })
}
diff --git a/third_party/rust/nix/src/sys/reboot.rs b/third_party/rust/nix/src/sys/reboot.rs
index 02d98162bd..2e4d888de4 100644
--- a/third_party/rust/nix/src/sys/reboot.rs
+++ b/third_party/rust/nix/src/sys/reboot.rs
@@ -1,48 +1,141 @@
-//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
+//! Reboot/shutdown
+//!
+//! On Linux, This can also be used to enable/disable Ctrl-Alt-Delete.
use crate::errno::Errno;
use crate::Result;
+use cfg_if::cfg_if;
use std::convert::Infallible;
-use std::mem::drop;
-
-libc_enum! {
- /// How exactly should the system be rebooted.
- ///
- /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
- /// enabling/disabling Ctrl-Alt-Delete.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum RebootMode {
- /// Halt the system.
- RB_HALT_SYSTEM,
- /// Execute a kernel that has been loaded earlier with
- /// [`kexec_load(2)`](https://man7.org/linux/man-pages/man2/kexec_load.2.html).
- RB_KEXEC,
- /// Stop the system and switch off power, if possible.
- RB_POWER_OFF,
- /// Restart the system.
- RB_AUTOBOOT,
- // we do not support Restart2.
- /// Suspend the system using software suspend.
- RB_SW_SUSPEND,
- }
-}
-/// Reboots or shuts down the system.
-pub fn reboot(how: RebootMode) -> Result<Infallible> {
- unsafe { libc::reboot(how as libc::c_int) };
- Err(Errno::last())
-}
+cfg_if! {
+ if #[cfg(target_os = "linux")] {
+ use std::mem::drop;
+
+ libc_enum! {
+ /// How exactly should the system be rebooted.
+ ///
+ /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
+ /// enabling/disabling Ctrl-Alt-Delete.
+ #[repr(i32)]
+ #[non_exhaustive]
+ pub enum RebootMode {
+ /// Halt the system.
+ RB_HALT_SYSTEM,
+ /// Execute a kernel that has been loaded earlier with
+ /// [`kexec_load(2)`](https://man7.org/linux/man-pages/man2/kexec_load.2.html).
+ RB_KEXEC,
+ /// Stop the system and switch off power, if possible.
+ RB_POWER_OFF,
+ /// Restart the system.
+ RB_AUTOBOOT,
+ // we do not support Restart2.
+ /// Suspend the system using software suspend.
+ RB_SW_SUSPEND,
+ }
+ }
+
+ /// Reboots or shuts down the system.
+ pub fn reboot(how: RebootMode) -> Result<Infallible> {
+ unsafe { libc::reboot(how as libc::c_int) };
+ Err(Errno::last())
+ }
-/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
-///
-/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
-pub fn set_cad_enabled(enable: bool) -> Result<()> {
- let cmd = if enable {
- libc::RB_ENABLE_CAD
- } else {
- libc::RB_DISABLE_CAD
- };
- let res = unsafe { libc::reboot(cmd) };
- Errno::result(res).map(drop)
+ /// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
+ ///
+ /// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
+ pub fn set_cad_enabled(enable: bool) -> Result<()> {
+ let cmd = if enable {
+ libc::RB_ENABLE_CAD
+ } else {
+ libc::RB_DISABLE_CAD
+ };
+ let res = unsafe { libc::reboot(cmd) };
+ Errno::result(res).map(drop)
+ }
+ } else if #[cfg(netbsdlike)] {
+ use libc::c_int;
+
+ libc_bitflags! {
+ /// How exactly should the system be rebooted.
+ pub struct RebootMode: c_int {
+ /// The default, causing the system to reboot in its usual fashion.
+ RB_AUTOBOOT;
+ /// Interpreted by the bootstrap program itself, causing it to
+ /// prompt on the console as to what file should be booted.
+ /// Normally, the system is booted from the file “xx(0,0)bsd”,
+ /// where xx is the default disk name, without prompting for
+ /// the file name.
+ RB_ASKNAME;
+ /// Dump kernel memory before rebooting; see `savecore(8)` for
+ /// more information.
+ RB_DUMP;
+ /// The processor is simply halted; no reboot takes place.
+ RB_HALT;
+ /// Power off the system if the system hardware supports the
+ /// function, otherwise it has no effect.
+ ///
+ /// Should be used in conjunction with `RB_HALT`.
+ RB_POWERDOWN;
+ /// By default, the system will halt if `reboot()` is called during
+ /// startup (before the system has finished autoconfiguration), even
+ /// if `RB_HALT` is not specified. This is because `panic(9)`s
+ /// during startup will probably just repeat on the next boot.
+ /// Use of this option implies that the user has requested the
+ /// action specified (for example, using the `ddb(4)` boot reboot
+ /// command), so the system will reboot if a halt is not explicitly
+ /// requested.
+ #[cfg(target_os = "openbsd")]
+ RB_USERREQ;
+ /// Load the symbol table and enable a built-in debugger in the
+ /// system. This option will have no useful function if the kernel
+ /// is not configured for debugging. Several other options have
+ /// different meaning if combined with this option, although their
+ /// use may not be possible via the `reboot()` call. See `ddb(4)` for
+ /// more information.
+ RB_KDB;
+ /// Normally, the disks are sync'd (see `sync(8)`) before the
+ /// processor is halted or rebooted. This option may be useful
+ /// if file system changes have been made manually or if the
+ /// processor is on fire.
+ RB_NOSYNC;
+ /// Normally, the reboot procedure involves an automatic disk
+ /// consistency check and then multi-user operations. `RB_SINGLE`
+ /// prevents this, booting the system with a single-user shell on
+ /// the console. `RB_SINGLE` is actually interpreted by the `init(8)`
+ /// program in the newly booted system.
+ ///
+ /// When no options are given (i.e., `RB_AUTOBOOT` is used), the
+ /// system is rebooted from file /bsd in the root file system of
+ /// unit 0 of a disk chosen in a processor specific way. An automatic
+ /// consistency check of the disks is normally performed (see `fsck(8)`).
+ RB_SINGLE;
+ /// Initially invoke the `userconf(4)` facility when the system
+ /// starts up again, if it has been compiled into the kernel
+ /// that is loaded.
+ #[cfg(target_os = "netbsd")]
+ RB_USERCONF;
+ /// Don't update the hardware clock from the system clock, presumably
+ /// because the system clock is suspect.
+ #[cfg(target_os = "openbsd")]
+ RB_TIMEBAD;
+ }
+ }
+
+ /// Reboot system or halt processor
+ ///
+ /// For more information, see the man pages:
+ ///
+ /// * [NetBSD](https://man.netbsd.org/reboot.2)
+ /// * [OpenBSD](https://man.openbsd.org/reboot.2)
+ #[cfg(netbsdlike)]
+ pub fn reboot(how: RebootMode) -> Result<Infallible> {
+ #[cfg(target_os = "openbsd")]
+ unsafe { libc::reboot(how.bits()) };
+ #[cfg(target_os = "netbsd")]
+ unsafe { libc::reboot(how.bits(), std::ptr::null_mut()) };
+
+ Err(Errno::last())
+ }
+ }
}
+
diff --git a/third_party/rust/nix/src/sys/resource.rs b/third_party/rust/nix/src/sys/resource.rs
index f42d32e3ca..71315072d4 100644
--- a/third_party/rust/nix/src/sys/resource.rs
+++ b/third_party/rust/nix/src/sys/resource.rs
@@ -10,16 +10,14 @@ pub use libc::RLIM_INFINITY;
use std::mem;
cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
+ if #[cfg(any(
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")),
+ target_os = "hurd"
+ ))]{
use libc::{__rlimit_resource_t, rlimit};
} else if #[cfg(any(
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "macos",
- target_os = "ios",
+ bsd,
target_os = "android",
- target_os = "dragonfly",
target_os = "aix",
all(target_os = "linux", not(target_env = "gnu"))
))]{
@@ -43,22 +41,19 @@ libc_enum! {
//
// https://gcc.gnu.org/legacy-ml/gcc/2015-08/msg00441.html
// https://github.com/rust-lang/libc/blob/master/src/unix/linux_like/linux/gnu/mod.rs
- #[cfg_attr(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")), repr(u32))]
#[cfg_attr(any(
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "macos",
- target_os = "ios",
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")),
+ target_os = "hurd"
+ ), repr(u32))]
+ #[cfg_attr(any(
+ bsd,
target_os = "android",
- target_os = "dragonfly",
target_os = "aix",
all(target_os = "linux", not(any(target_env = "gnu", target_env = "uclibc")))
), repr(i32))]
#[non_exhaustive]
pub enum Resource {
- #[cfg(not(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(target_os = "freebsd", netbsdlike)))]
/// The maximum amount (in bytes) of virtual memory the process is
/// allowed to map.
RLIMIT_AS,
@@ -77,102 +72,78 @@ libc_enum! {
RLIMIT_STACK,
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum number of kqueues this user id is allowed to create.
RLIMIT_KQUEUES,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
/// A limit on the combined number of flock locks and fcntl leases that
/// this process may establish.
RLIMIT_LOCKS,
- #[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "linux",
- target_os = "netbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "freebsd", netbsdlike))]
/// The maximum size (in bytes) which a process may lock into memory
/// using the mlock(2) system call.
RLIMIT_MEMLOCK,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
/// A limit on the number of bytes that can be allocated for POSIX
/// message queues for the real user ID of the calling process.
RLIMIT_MSGQUEUE,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
/// A ceiling to which the process's nice value can be raised using
/// setpriority or nice.
RLIMIT_NICE,
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "linux",
+ netbsdlike,
target_os = "aix",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum number of simultaneous processes for this user id.
RLIMIT_NPROC,
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum number of pseudo-terminals this user id is allowed to
/// create.
RLIMIT_NPTS,
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "linux",
+ netbsdlike,
target_os = "aix",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// When there is memory pressure and swap is available, prioritize
/// eviction of a process' resident pages beyond this amount (in bytes).
RLIMIT_RSS,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
/// A ceiling on the real-time priority that may be set for this process
/// using sched_setscheduler and sched_set‐ param.
RLIMIT_RTPRIO,
#[cfg(any(target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// A limit (in microseconds) on the amount of CPU time that a process
/// scheduled under a real-time scheduling policy may con‐ sume without
/// making a blocking system call.
RLIMIT_RTTIME,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
/// A limit on the number of signals that may be queued for the real
/// user ID of the calling process.
RLIMIT_SIGPENDING,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
/// The maximum size (in bytes) of socket buffer usage for this user.
RLIMIT_SBSIZE,
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum size (in bytes) of the swap space that may be reserved
/// or used by all of this user id's processes.
RLIMIT_SWAP,
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// An alias for RLIMIT_AS.
RLIMIT_VMEM,
}
@@ -206,7 +177,10 @@ pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> {
let mut old_rlim = mem::MaybeUninit::<rlimit>::uninit();
cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
+ if #[cfg(any(
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")),
+ target_os = "hurd"
+ ))] {
let res = unsafe { libc::getrlimit(resource as __rlimit_resource_t, old_rlim.as_mut_ptr()) };
} else {
let res = unsafe { libc::getrlimit(resource as c_int, old_rlim.as_mut_ptr()) };
@@ -259,7 +233,10 @@ pub fn setrlimit(
rlim_max: hard_limit,
};
cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
+ if #[cfg(any(
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")),
+ target_os = "hurd",
+ ))]{
let res = unsafe { libc::setrlimit(resource as __rlimit_resource_t, &new_rlim as *const rlimit) };
}else{
let res = unsafe { libc::setrlimit(resource as c_int, &new_rlim as *const rlimit) };
@@ -281,7 +258,6 @@ libc_enum! {
RUSAGE_CHILDREN,
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// Resource usage for the calling thread.
RUSAGE_THREAD,
}
@@ -420,28 +396,3 @@ pub fn getrusage(who: UsageWho) -> Result<Usage> {
Errno::result(res).map(|_| Usage(rusage.assume_init()))
}
}
-
-#[cfg(test)]
-mod test {
- use super::{getrusage, UsageWho};
-
- #[test]
- pub fn test_self_cpu_time() {
- // Make sure some CPU time is used.
- let mut numbers: Vec<i32> = (1..1_000_000).collect();
- numbers.iter_mut().for_each(|item| *item *= 2);
-
- // FIXME: this is here to help ensure the compiler does not optimize the whole
- // thing away. Replace the assert with test::black_box once stabilized.
- assert_eq!(numbers[100..200].iter().sum::<i32>(), 30_100);
-
- let usage = getrusage(UsageWho::RUSAGE_SELF)
- .expect("Failed to call getrusage for SELF");
- let rusage = usage.as_ref();
-
- let user = usage.user_time();
- assert!(user.tv_sec() > 0 || user.tv_usec() > 0);
- assert_eq!(user.tv_sec(), rusage.ru_utime.tv_sec);
- assert_eq!(user.tv_usec(), rusage.ru_utime.tv_usec);
- }
-}
diff --git a/third_party/rust/nix/src/sys/select.rs b/third_party/rust/nix/src/sys/select.rs
index 0e2193b130..64a8e258cf 100644
--- a/third_party/rust/nix/src/sys/select.rs
+++ b/third_party/rust/nix/src/sys/select.rs
@@ -7,7 +7,7 @@ use std::convert::TryFrom;
use std::iter::FusedIterator;
use std::mem;
use std::ops::Range;
-use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
+use std::os::unix::io::{AsRawFd, BorrowedFd, RawFd};
use std::ptr::{null, null_mut};
pub use libc::FD_SETSIZE;
@@ -41,21 +41,21 @@ impl<'fd> FdSet<'fd> {
}
/// Add a file descriptor to an `FdSet`
- pub fn insert<Fd: AsFd>(&mut self, fd: &'fd Fd) {
- assert_fd_valid(fd.as_fd().as_raw_fd());
- unsafe { libc::FD_SET(fd.as_fd().as_raw_fd(), &mut self.set) };
+ pub fn insert(&mut self, fd: BorrowedFd<'fd>) {
+ assert_fd_valid(fd.as_raw_fd());
+ unsafe { libc::FD_SET(fd.as_raw_fd(), &mut self.set) };
}
/// Remove a file descriptor from an `FdSet`
- pub fn remove<Fd: AsFd>(&mut self, fd: &'fd Fd) {
- assert_fd_valid(fd.as_fd().as_raw_fd());
- unsafe { libc::FD_CLR(fd.as_fd().as_raw_fd(), &mut self.set) };
+ pub fn remove(&mut self, fd: BorrowedFd<'fd>) {
+ assert_fd_valid(fd.as_raw_fd());
+ unsafe { libc::FD_CLR(fd.as_raw_fd(), &mut self.set) };
}
/// Test an `FdSet` for the presence of a certain file descriptor.
- pub fn contains<Fd: AsFd>(&self, fd: &'fd Fd) -> bool {
- assert_fd_valid(fd.as_fd().as_raw_fd());
- unsafe { libc::FD_ISSET(fd.as_fd().as_raw_fd(), &self.set) }
+ pub fn contains(&self, fd: BorrowedFd<'fd>) -> bool {
+ assert_fd_valid(fd.as_raw_fd());
+ unsafe { libc::FD_ISSET(fd.as_raw_fd(), &self.set) }
}
/// Remove all file descriptors from this `FdSet`.
@@ -77,8 +77,8 @@ impl<'fd> FdSet<'fd> {
/// let fd_four = unsafe {BorrowedFd::borrow_raw(4)};
/// let fd_nine = unsafe {BorrowedFd::borrow_raw(9)};
/// let mut set = FdSet::new();
- /// set.insert(&fd_four);
- /// set.insert(&fd_nine);
+ /// set.insert(fd_four);
+ /// set.insert(fd_nine);
/// assert_eq!(set.highest().map(|borrowed_fd|borrowed_fd.as_raw_fd()), Some(9));
/// ```
///
@@ -101,8 +101,8 @@ impl<'fd> FdSet<'fd> {
/// let mut set = FdSet::new();
/// let fd_four = unsafe {BorrowedFd::borrow_raw(4)};
/// let fd_nine = unsafe {BorrowedFd::borrow_raw(9)};
- /// set.insert(&fd_four);
- /// set.insert(&fd_nine);
+ /// set.insert(fd_four);
+ /// set.insert(fd_nine);
/// let fds: Vec<RawFd> = set.fds(None).map(|borrowed_fd|borrowed_fd.as_raw_fd()).collect();
/// assert_eq!(fds, vec![4, 9]);
/// ```
@@ -134,7 +134,7 @@ impl<'a, 'fd> Iterator for Fds<'a, 'fd> {
fn next(&mut self) -> Option<Self::Item> {
for i in &mut self.range {
let borrowed_i = unsafe { BorrowedFd::borrow_raw(i as RawFd) };
- if self.set.contains(&borrowed_i) {
+ if self.set.contains(borrowed_i) {
return Some(borrowed_i);
}
}
@@ -153,7 +153,7 @@ impl<'a, 'fd> DoubleEndedIterator for Fds<'a, 'fd> {
fn next_back(&mut self) -> Option<BorrowedFd<'fd>> {
while let Some(i) = self.range.next_back() {
let borrowed_i = unsafe { BorrowedFd::borrow_raw(i as RawFd) };
- if self.set.contains(&borrowed_i) {
+ if self.set.contains(borrowed_i) {
return Some(borrowed_i);
}
}
@@ -317,238 +317,3 @@ where
Errno::result(res)
}
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::sys::time::{TimeVal, TimeValLike};
- use crate::unistd::{close, pipe, write};
- use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
-
- #[test]
- fn fdset_insert() {
- let mut fd_set = FdSet::new();
-
- for i in 0..FD_SETSIZE {
- let borrowed_i = unsafe { BorrowedFd::borrow_raw(i as RawFd) };
- assert!(!fd_set.contains(&borrowed_i));
- }
-
- let fd_seven = unsafe { BorrowedFd::borrow_raw(7) };
- fd_set.insert(&fd_seven);
-
- assert!(fd_set.contains(&fd_seven));
- }
-
- #[test]
- fn fdset_remove() {
- let mut fd_set = FdSet::new();
-
- for i in 0..FD_SETSIZE {
- let borrowed_i = unsafe { BorrowedFd::borrow_raw(i as RawFd) };
- assert!(!fd_set.contains(&borrowed_i));
- }
-
- let fd_seven = unsafe { BorrowedFd::borrow_raw(7) };
- fd_set.insert(&fd_seven);
- fd_set.remove(&fd_seven);
-
- for i in 0..FD_SETSIZE {
- let borrowed_i = unsafe { BorrowedFd::borrow_raw(i as RawFd) };
- assert!(!fd_set.contains(&borrowed_i));
- }
- }
-
- #[test]
- #[allow(non_snake_case)]
- fn fdset_clear() {
- let mut fd_set = FdSet::new();
- let fd_one = unsafe { BorrowedFd::borrow_raw(1) };
- let fd_FD_SETSIZE_devided_by_two =
- unsafe { BorrowedFd::borrow_raw((FD_SETSIZE / 2) as RawFd) };
- let fd_FD_SETSIZE_minus_one =
- unsafe { BorrowedFd::borrow_raw((FD_SETSIZE - 1) as RawFd) };
- fd_set.insert(&fd_one);
- fd_set.insert(&fd_FD_SETSIZE_devided_by_two);
- fd_set.insert(&fd_FD_SETSIZE_minus_one);
-
- fd_set.clear();
-
- for i in 0..FD_SETSIZE {
- let borrowed_i = unsafe { BorrowedFd::borrow_raw(i as RawFd) };
- assert!(!fd_set.contains(&borrowed_i));
- }
- }
-
- #[test]
- fn fdset_highest() {
- let mut set = FdSet::new();
- assert_eq!(
- set.highest().map(|borrowed_fd| borrowed_fd.as_raw_fd()),
- None
- );
- let fd_zero = unsafe { BorrowedFd::borrow_raw(0) };
- let fd_ninety = unsafe { BorrowedFd::borrow_raw(90) };
- set.insert(&fd_zero);
- assert_eq!(
- set.highest().map(|borrowed_fd| borrowed_fd.as_raw_fd()),
- Some(0)
- );
- set.insert(&fd_ninety);
- assert_eq!(
- set.highest().map(|borrowed_fd| borrowed_fd.as_raw_fd()),
- Some(90)
- );
- set.remove(&fd_zero);
- assert_eq!(
- set.highest().map(|borrowed_fd| borrowed_fd.as_raw_fd()),
- Some(90)
- );
- set.remove(&fd_ninety);
- assert_eq!(
- set.highest().map(|borrowed_fd| borrowed_fd.as_raw_fd()),
- None
- );
-
- let fd_four = unsafe { BorrowedFd::borrow_raw(4) };
- let fd_five = unsafe { BorrowedFd::borrow_raw(5) };
- let fd_seven = unsafe { BorrowedFd::borrow_raw(7) };
- set.insert(&fd_four);
- set.insert(&fd_five);
- set.insert(&fd_seven);
- assert_eq!(
- set.highest().map(|borrowed_fd| borrowed_fd.as_raw_fd()),
- Some(7)
- );
- }
-
- #[test]
- fn fdset_fds() {
- let mut set = FdSet::new();
- let fd_zero = unsafe { BorrowedFd::borrow_raw(0) };
- let fd_ninety = unsafe { BorrowedFd::borrow_raw(90) };
- assert_eq!(
- set.fds(None)
- .map(|borrowed_fd| borrowed_fd.as_raw_fd())
- .collect::<Vec<_>>(),
- vec![]
- );
- set.insert(&fd_zero);
- assert_eq!(
- set.fds(None)
- .map(|borrowed_fd| borrowed_fd.as_raw_fd())
- .collect::<Vec<_>>(),
- vec![0]
- );
- set.insert(&fd_ninety);
- assert_eq!(
- set.fds(None)
- .map(|borrowed_fd| borrowed_fd.as_raw_fd())
- .collect::<Vec<_>>(),
- vec![0, 90]
- );
-
- // highest limit
- assert_eq!(
- set.fds(Some(89))
- .map(|borrowed_fd| borrowed_fd.as_raw_fd())
- .collect::<Vec<_>>(),
- vec![0]
- );
- assert_eq!(
- set.fds(Some(90))
- .map(|borrowed_fd| borrowed_fd.as_raw_fd())
- .collect::<Vec<_>>(),
- vec![0, 90]
- );
- }
-
- #[test]
- fn test_select() {
- let (r1, w1) = pipe().unwrap();
- let r1 = unsafe { OwnedFd::from_raw_fd(r1) };
- let w1 = unsafe { OwnedFd::from_raw_fd(w1) };
- let (r2, _w2) = pipe().unwrap();
- let r2 = unsafe { OwnedFd::from_raw_fd(r2) };
-
- write(w1.as_raw_fd(), b"hi!").unwrap();
- let mut fd_set = FdSet::new();
- fd_set.insert(&r1);
- fd_set.insert(&r2);
-
- let mut timeout = TimeVal::seconds(10);
- assert_eq!(
- 1,
- select(None, &mut fd_set, None, None, &mut timeout).unwrap()
- );
- assert!(fd_set.contains(&r1));
- assert!(!fd_set.contains(&r2));
- close(_w2).unwrap();
- }
-
- #[test]
- fn test_select_nfds() {
- let (r1, w1) = pipe().unwrap();
- let (r2, _w2) = pipe().unwrap();
- let r1 = unsafe { OwnedFd::from_raw_fd(r1) };
- let w1 = unsafe { OwnedFd::from_raw_fd(w1) };
- let r2 = unsafe { OwnedFd::from_raw_fd(r2) };
-
- write(w1.as_raw_fd(), b"hi!").unwrap();
- let mut fd_set = FdSet::new();
- fd_set.insert(&r1);
- fd_set.insert(&r2);
-
- let mut timeout = TimeVal::seconds(10);
- {
- assert_eq!(
- 1,
- select(
- Some(
- fd_set
- .highest()
- .map(|borrowed_fd| borrowed_fd.as_raw_fd())
- .unwrap()
- + 1
- ),
- &mut fd_set,
- None,
- None,
- &mut timeout
- )
- .unwrap()
- );
- }
- assert!(fd_set.contains(&r1));
- assert!(!fd_set.contains(&r2));
- close(_w2).unwrap();
- }
-
- #[test]
- fn test_select_nfds2() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
- let r1 = unsafe { OwnedFd::from_raw_fd(r1) };
- let r2 = unsafe { OwnedFd::from_raw_fd(r2) };
- let mut fd_set = FdSet::new();
- fd_set.insert(&r1);
- fd_set.insert(&r2);
-
- let mut timeout = TimeVal::seconds(10);
- assert_eq!(
- 1,
- select(
- std::cmp::max(r1.as_raw_fd(), r2.as_raw_fd()) + 1,
- &mut fd_set,
- None,
- None,
- &mut timeout
- )
- .unwrap()
- );
- assert!(fd_set.contains(&r1));
- assert!(!fd_set.contains(&r2));
- close(_w2).unwrap();
- }
-}
diff --git a/third_party/rust/nix/src/sys/sendfile.rs b/third_party/rust/nix/src/sys/sendfile.rs
index 9f3c333f97..d7452edd7c 100644
--- a/third_party/rust/nix/src/sys/sendfile.rs
+++ b/third_party/rust/nix/src/sys/sendfile.rs
@@ -20,9 +20,9 @@ use crate::Result;
///
/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket.
///
-/// 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())))]
+/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html) for Linux,
+/// see [the sendfile(2) man page.](https://docs.oracle.com/cd/E88353_01/html/E37843/sendfile-3c.html) for Solaris.
+#[cfg(any(linux_android, solarish))]
pub fn sendfile<F1: AsFd, F2: AsFd>(
out_fd: F1,
in_fd: F2,
@@ -56,7 +56,6 @@ pub fn sendfile<F1: AsFd, F2: AsFd>(
///
/// 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<F1: AsFd, F2: AsFd>(
out_fd: F1,
in_fd: F2,
@@ -78,46 +77,82 @@ pub fn sendfile64<F1: AsFd, F2: AsFd>(
}
cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))] {
+ if #[cfg(any(freebsdlike, apple_targets))] {
use std::io::IoSlice;
#[derive(Clone, Debug)]
- struct SendfileHeaderTrailer<'a>(
- libc::sf_hdtr,
- Option<Vec<IoSlice<'a>>>,
- Option<Vec<IoSlice<'a>>>,
- );
+ struct SendfileHeaderTrailer<'a> {
+ raw: libc::sf_hdtr,
+ _headers: Option<Vec<IoSlice<'a>>>,
+ _trailers: Option<Vec<IoSlice<'a>>>,
+ }
impl<'a> SendfileHeaderTrailer<'a> {
fn new(
headers: Option<&'a [&'a [u8]]>,
trailers: Option<&'a [&'a [u8]]>
) -> SendfileHeaderTrailer<'a> {
- let header_iovecs: Option<Vec<IoSlice<'_>>> =
+ let mut header_iovecs: Option<Vec<IoSlice<'_>>> =
headers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect());
- let trailer_iovecs: Option<Vec<IoSlice<'_>>> =
+ let mut trailer_iovecs: Option<Vec<IoSlice<'_>>> =
trailers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect());
- SendfileHeaderTrailer(
- libc::sf_hdtr {
+
+ SendfileHeaderTrailer {
+ raw: libc::sf_hdtr {
headers: {
header_iovecs
- .as_ref()
- .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
+ .as_mut()
+ .map_or(ptr::null_mut(), |v| v.as_mut_ptr())
+ .cast()
},
hdr_cnt: header_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32,
trailers: {
trailer_iovecs
- .as_ref()
- .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
+ .as_mut()
+ .map_or(ptr::null_mut(), |v| v.as_mut_ptr())
+ .cast()
},
trl_cnt: trailer_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32
},
- header_iovecs,
- trailer_iovecs,
- )
+ _headers: header_iovecs,
+ _trailers: trailer_iovecs,
+ }
+ }
+ }
+ } else if #[cfg(solarish)] {
+ use std::os::unix::io::BorrowedFd;
+ use std::marker::PhantomData;
+
+ #[derive(Debug, Copy, Clone)]
+ /// Mapping of the raw C sendfilevec_t struct
+ pub struct SendfileVec<'fd> {
+ raw: libc::sendfilevec_t,
+ phantom: PhantomData<BorrowedFd<'fd>>
+ }
+
+ impl<'fd> SendfileVec<'fd> {
+ /// initialises SendfileVec to send data directly from the process's address space
+ /// same in C with sfv_fd set to SFV_FD_SELF.
+ pub fn newself(
+ off: off_t,
+ len: usize
+ ) -> Self {
+ Self{raw: libc::sendfilevec_t{sfv_fd: libc::SFV_FD_SELF, sfv_flag: 0, sfv_off: off, sfv_len: len}, phantom: PhantomData}
+ }
+
+ /// initialises SendfileVec to send data from `fd`.
+ pub fn new(
+ fd: BorrowedFd<'fd>,
+ off: off_t,
+ len: usize
+ ) -> SendfileVec<'fd> {
+ Self{raw: libc::sendfilevec_t{sfv_fd: fd.as_raw_fd(), sfv_flag: 0, sfv_off:off, sfv_len: len}, phantom: PhantomData}
+ }
+ }
+
+ impl From<SendfileVec<'_>> for libc::sendfilevec_t {
+ fn from<'fd>(vec: SendfileVec) -> libc::sendfilevec_t {
+ vec.raw
}
}
}
@@ -187,7 +222,7 @@ cfg_if! {
let flags: u32 = (ra32 << 16) | (flags.bits() as u32);
let mut bytes_sent: off_t = 0;
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 hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.raw as *const libc::sf_hdtr);
let return_code = unsafe {
libc::sendfile(in_fd.as_fd().as_raw_fd(),
out_sock.as_fd().as_raw_fd(),
@@ -230,7 +265,7 @@ cfg_if! {
) -> (Result<()>, off_t) {
let mut bytes_sent: off_t = 0;
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 hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.raw as *const libc::sf_hdtr);
let return_code = unsafe {
libc::sendfile(in_fd.as_fd().as_raw_fd(),
out_sock.as_fd().as_raw_fd(),
@@ -242,7 +277,7 @@ cfg_if! {
};
(Errno::result(return_code).and(Ok(())), bytes_sent)
}
- } else if #[cfg(any(target_os = "ios", target_os = "macos"))] {
+ } else if #[cfg(apple_targets)] {
/// Read bytes from `in_fd` starting at `offset` and write up to `count` bytes to
/// `out_sock`.
///
@@ -276,7 +311,7 @@ cfg_if! {
) -> (Result<()>, off_t) {
let mut len = count.unwrap_or(0);
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 hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.raw as *const libc::sf_hdtr);
let return_code = unsafe {
libc::sendfile(in_fd.as_fd().as_raw_fd(),
out_sock.as_fd().as_raw_fd(),
@@ -287,5 +322,30 @@ cfg_if! {
};
(Errno::result(return_code).and(Ok(())), len)
}
+ } else if #[cfg(solarish)] {
+ /// Write data from the vec arrays to `out_sock` and returns a `Result` and a
+ /// count of bytes written.
+ ///
+ /// Each `SendfileVec` set needs to be instantiated either with `SendfileVec::new` or
+ /// `SendfileVec::newself`.
+ ///
+ /// The former allows to send data from a file descriptor through `fd`,
+ /// from an offset `off` and for a given amount of data `len`.
+ ///
+ /// The latter allows to send data from the process's address space, from an offset `off`
+ /// and for a given amount of data `len`.
+ ///
+ /// For more information, see
+ /// [the sendfilev(3) man page.](https://illumos.org/man/3EXT/sendfilev)
+ pub fn sendfilev<F: AsFd>(
+ out_sock: F,
+ vec: &[SendfileVec]
+ ) -> (Result<()>, usize) {
+ let mut len = 0usize;
+ let return_code = unsafe {
+ libc::sendfilev(out_sock.as_fd().as_raw_fd(), vec.as_ptr() as *const libc::sendfilevec_t, vec.len() as i32, &mut len)
+ };
+ (Errno::result(return_code).and(Ok(())), len)
+ }
}
}
diff --git a/third_party/rust/nix/src/sys/signal.rs b/third_party/rust/nix/src/sys/signal.rs
index c946e4a0b1..c9b593d0db 100644
--- a/third_party/rust/nix/src/sys/signal.rs
+++ b/third_party/rust/nix/src/sys/signal.rs
@@ -7,14 +7,17 @@ use crate::errno::Errno;
use crate::{Error, Result};
use cfg_if::cfg_if;
use std::fmt;
+use std::hash::{Hash, Hasher};
use std::mem;
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
+use std::ops::BitOr;
+#[cfg(freebsdlike)]
use std::os::unix::io::RawFd;
use std::ptr;
use std::str::FromStr;
#[cfg(not(any(
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "openbsd",
target_os = "redox"
)))]
@@ -63,9 +66,12 @@ libc_enum! {
/// Software termination signal from kill
SIGTERM,
/// Stack fault (obsolete)
- #[cfg(all(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux"),
- not(any(target_arch = "mips", target_arch = "mips64",
+ #[cfg(all(any(linux_android, target_os = "emscripten",
+ target_os = "fuchsia"),
+ not(any(target_arch = "mips",
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "sparc64"))))]
SIGSTKFLT,
/// To parent on child stop or exit
@@ -94,27 +100,21 @@ libc_enum! {
SIGWINCH,
/// Input/output possible signal
#[cfg(not(target_os = "haiku"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
SIGIO,
- #[cfg(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux",
- target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "emscripten",
+ target_os = "fuchsia", target_os = "aix"))]
/// Power failure imminent.
SIGPWR,
/// Bad system call
SIGSYS,
- #[cfg(not(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux",
+ #[cfg(not(any(linux_android, target_os = "emscripten",
+ target_os = "fuchsia",
target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
/// Emulator trap
SIGEMT,
- #[cfg(not(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux",
- target_os = "redox", target_os = "haiku",
- target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(linux_android, target_os = "emscripten",
+ target_os = "fuchsia", target_os = "redox",
+ target_os = "haiku", target_os = "aix")))]
/// Information request
SIGINFO,
}
@@ -143,14 +143,15 @@ impl FromStr for Signal {
"SIGTERM" => Signal::SIGTERM,
#[cfg(all(
any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux"
),
not(any(
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "sparc64"
))
))]
@@ -170,27 +171,24 @@ impl FromStr for Signal {
#[cfg(not(target_os = "haiku"))]
"SIGIO" => Signal::SIGIO,
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux"
))]
"SIGPWR" => Signal::SIGPWR,
"SIGSYS" => Signal::SIGSYS,
#[cfg(not(any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux",
target_os = "redox",
target_os = "haiku"
)))]
"SIGEMT" => Signal::SIGEMT,
#[cfg(not(any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux",
target_os = "redox",
target_os = "aix",
target_os = "haiku"
@@ -227,14 +225,15 @@ impl Signal {
Signal::SIGTERM => "SIGTERM",
#[cfg(all(
any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux"
),
not(any(
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "sparc64"
))
))]
@@ -254,28 +253,25 @@ impl Signal {
#[cfg(not(target_os = "haiku"))]
Signal::SIGIO => "SIGIO",
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
target_os = "aix",
- target_os = "linux"
))]
Signal::SIGPWR => "SIGPWR",
Signal::SIGSYS => "SIGSYS",
#[cfg(not(any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux",
target_os = "redox",
target_os = "haiku"
)))]
Signal::SIGEMT => "SIGEMT",
#[cfg(not(any(
- target_os = "android",
+ linux_android,
target_os = "emscripten",
target_os = "fuchsia",
- target_os = "linux",
target_os = "redox",
target_os = "aix",
target_os = "haiku"
@@ -319,15 +315,12 @@ const SIGNALS: [Signal; 28] = [
SIGPROF, SIGWINCH, SIGSYS,
];
#[cfg(all(
- any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia"
- ),
+ any(linux_android, target_os = "emscripten", target_os = "fuchsia"),
not(any(
target_arch = "mips",
+ target_arch = "mips32r6",
target_arch = "mips64",
+ target_arch = "mips64r6",
target_arch = "sparc64"
))
))]
@@ -339,13 +332,14 @@ const SIGNALS: [Signal; 31] = [
SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS,
];
#[cfg(all(
+ any(linux_android, target_os = "emscripten", target_os = "fuchsia"),
any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia"
- ),
- any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64")
+ target_arch = "mips",
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6",
+ target_arch = "sparc64"
+ )
))]
#[cfg(feature = "signal")]
const SIGNALS: [Signal; 30] = [
@@ -363,8 +357,7 @@ const SIGNALS: [Signal; 30] = [
SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, SIGTRAP,
];
#[cfg(not(any(
- target_os = "linux",
- target_os = "android",
+ linux_android,
target_os = "fuchsia",
target_os = "emscripten",
target_os = "aix",
@@ -439,6 +432,7 @@ libc_bitflags! {
SA_NOCLDSTOP;
/// When catching a [`Signal::SIGCHLD`] signal, the system will not
/// create zombie processes when children of the calling process exit.
+ #[cfg(not(target_os = "hurd"))]
SA_NOCLDWAIT;
/// Further occurrences of the delivered signal are not masked during
/// the execution of the handler.
@@ -486,7 +480,7 @@ use std::iter::IntoIterator;
// We are using `transparent` here to be super sure that `SigSet`
// is represented exactly like the `sigset_t` struct from C.
#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq)]
pub struct SigSet {
sigset: libc::sigset_t
}
@@ -577,7 +571,6 @@ impl SigSet {
/// Suspends execution of the calling thread until one of the signals in the
/// signal mask becomes pending, and returns the accepted signal.
#[cfg(not(target_os = "redox"))] // RedoxFS does not yet support sigwait
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn wait(&self) -> Result<Signal> {
use std::convert::TryFrom;
@@ -589,6 +582,35 @@ impl SigSet {
})
}
+ /// Wait for a signal
+ ///
+ /// # Return value
+ /// If `sigsuspend(2)` is interrupted (EINTR), this function returns `Ok`.
+ /// If `sigsuspend(2)` set other error, this function returns `Err`.
+ ///
+ /// For more information see the
+ /// [`sigsuspend(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html).
+ #[cfg(any(
+ bsd,
+ linux_android,
+ solarish,
+ target_os = "haiku",
+ target_os = "hurd",
+ target_os = "aix",
+ target_os = "fushsia"
+ ))]
+ #[doc(alias("sigsuspend"))]
+ pub fn suspend(&self) -> Result<()> {
+ let res = unsafe {
+ libc::sigsuspend(&self.sigset as *const libc::sigset_t)
+ };
+ match Errno::result(res).map(drop) {
+ Err(Errno::EINTR) => Ok(()),
+ Err(e) => Err(e),
+ Ok(_) => unreachable!("because this syscall always returns -1 if returns"),
+ }
+ }
+
/// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the
/// `libc::sigset_t` is already initialized.
///
@@ -603,6 +625,42 @@ impl SigSet {
}
}
+impl From<Signal> for SigSet {
+ fn from(signal: Signal) -> SigSet {
+ let mut sigset = SigSet::empty();
+ sigset.add(signal);
+ sigset
+ }
+}
+
+impl BitOr for Signal {
+ type Output = SigSet;
+
+ fn bitor(self, rhs: Self) -> Self::Output {
+ let mut sigset = SigSet::empty();
+ sigset.add(self);
+ sigset.add(rhs);
+ sigset
+ }
+}
+
+impl BitOr<Signal> for SigSet {
+ type Output = SigSet;
+
+ fn bitor(mut self, rhs: Signal) -> Self::Output {
+ self.add(rhs);
+ self
+ }
+}
+
+impl BitOr for SigSet {
+ type Output = Self;
+
+ fn bitor(self, rhs: Self) -> Self::Output {
+ self.iter().chain(rhs.iter()).collect()
+ }
+}
+
impl AsRef<libc::sigset_t> for SigSet {
fn as_ref(&self) -> &libc::sigset_t {
&self.sigset
@@ -628,6 +686,27 @@ impl FromIterator<Signal> for SigSet {
}
}
+impl PartialEq for SigSet {
+ fn eq(&self, other: &Self) -> bool {
+ for signal in Signal::iterator() {
+ if self.contains(signal) != other.contains(signal) {
+ return false;
+ }
+ }
+ true
+ }
+}
+
+impl Hash for SigSet {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ for signal in Signal::iterator() {
+ if self.contains(signal) {
+ signal.hash(state);
+ }
+ }
+ }
+}
+
/// Iterator for a [`SigSet`].
///
/// Call [`SigSet::iter`] to create an iterator.
@@ -670,7 +749,6 @@ pub enum SigHandler {
/// Use the given signal-catching function, which takes in the signal, information about how
/// the signal was generated, and a pointer to the threads `ucontext_t`.
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
SigAction(extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void))
}
@@ -689,23 +767,27 @@ impl SigAction {
pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction {
#[cfg(not(target_os = "aix"))]
unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) {
- (*p).sa_sigaction = match handler {
- SigHandler::SigDfl => libc::SIG_DFL,
- SigHandler::SigIgn => libc::SIG_IGN,
- SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
- #[cfg(not(target_os = "redox"))]
- SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
- };
+ unsafe {
+ (*p).sa_sigaction = match handler {
+ SigHandler::SigDfl => libc::SIG_DFL,
+ SigHandler::SigIgn => libc::SIG_IGN,
+ SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
+ #[cfg(not(target_os = "redox"))]
+ SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
+ };
+ }
}
#[cfg(target_os = "aix")]
unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) {
- (*p).sa_union.__su_sigaction = match handler {
- SigHandler::SigDfl => mem::transmute::<usize, extern "C" fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void)>(libc::SIG_DFL),
- SigHandler::SigIgn => mem::transmute::<usize, extern "C" fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void)>(libc::SIG_IGN),
- SigHandler::Handler(f) => mem::transmute::<extern "C" fn(i32), extern "C" fn(i32, *mut libc::siginfo_t, *mut libc::c_void)>(f),
- SigHandler::SigAction(f) => f,
- };
+ unsafe {
+ (*p).sa_union.__su_sigaction = match handler {
+ SigHandler::SigDfl => unsafe { mem::transmute::<usize, extern "C" fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void)>(libc::SIG_DFL) },
+ SigHandler::SigIgn => unsafe { mem::transmute::<usize, extern "C" fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void)>(libc::SIG_IGN) },
+ SigHandler::Handler(f) => unsafe { mem::transmute::<extern "C" fn(i32), extern "C" fn(i32, *mut libc::siginfo_t, *mut libc::c_void)>(f) },
+ SigHandler::SigAction(f) => f,
+ };
+ }
}
let mut s = mem::MaybeUninit::<libc::sigaction>::uninit();
@@ -810,11 +892,11 @@ impl SigAction {
pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
let mut oldact = mem::MaybeUninit::<libc::sigaction>::uninit();
- let res = libc::sigaction(signal as libc::c_int,
+ let res = unsafe { libc::sigaction(signal as libc::c_int,
&sigaction.sigaction as *const libc::sigaction,
- oldact.as_mut_ptr());
+ oldact.as_mut_ptr()) };
- Errno::result(res).map(|_| SigAction { sigaction: oldact.assume_init() })
+ Errno::result(res).map(|_| SigAction { sigaction: unsafe { oldact.assume_init() } })
}
/// Signal management (see [signal(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html))
@@ -872,9 +954,9 @@ pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigActi
pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler> {
let signal = signal as libc::c_int;
let res = match handler {
- SigHandler::SigDfl => libc::signal(signal, libc::SIG_DFL),
- SigHandler::SigIgn => libc::signal(signal, libc::SIG_IGN),
- SigHandler::Handler(handler) => libc::signal(signal, handler as libc::sighandler_t),
+ SigHandler::SigDfl => unsafe { libc::signal(signal, libc::SIG_DFL) },
+ SigHandler::SigIgn => unsafe { libc::signal(signal, libc::SIG_IGN) },
+ SigHandler::Handler(handler) => unsafe { libc::signal(signal, handler as libc::sighandler_t) },
#[cfg(not(target_os = "redox"))]
SigHandler::SigAction(_) => return Err(Errno::ENOTSUP),
};
@@ -883,9 +965,7 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
libc::SIG_DFL => SigHandler::SigDfl,
libc::SIG_IGN => SigHandler::SigIgn,
p => SigHandler::Handler(
- *(&p as *const usize
- as *const extern fn(libc::c_int))
- as extern fn(libc::c_int)),
+ unsafe { *(&p as *const usize as *const extern fn(libc::c_int)) } as extern fn(libc::c_int)),
}
})
}
@@ -1019,14 +1099,14 @@ feature! {
#[cfg(target_os = "freebsd")]
pub type type_of_thread_id = libc::lwpid_t;
/// Identifies a thread for [`SigevNotify::SigevThreadId`]
-#[cfg(any(target_env = "gnu", target_env = "uclibc"))]
+#[cfg(all(not(target_os = "hurd"), any(target_env = "gnu", target_env = "uclibc")))]
pub type type_of_thread_id = libc::pid_t;
/// Specifies the notification method used by a [`SigEvent`]
// sigval is actually a union of a int and a void*. But it's never really used
// as a pointer, because neither libc nor the kernel ever dereference it. nix
// therefore presents it as an intptr_t, which is how kevent uses it.
-#[cfg(not(any(target_os = "fuchsia", target_os = "openbsd", target_os = "redox")))]
+#[cfg(not(any(target_os = "fuchsia", target_os = "hurd", target_os = "openbsd", target_os = "redox")))]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SigevNotify {
/// No notification will be delivered
@@ -1041,8 +1121,7 @@ pub enum SigevNotify {
},
// Note: SIGEV_THREAD is not implemented, but could be if desired.
/// Notify by delivering an event to a kqueue.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
SigevKevent {
/// File descriptor of the kqueue to notify.
kq: RawFd,
@@ -1051,7 +1130,6 @@ pub enum SigevNotify {
},
/// Notify by delivering an event to a kqueue, with optional event flags set
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
#[cfg(feature = "event")]
SigevKeventFlags {
/// File descriptor of the kqueue to notify.
@@ -1067,7 +1145,6 @@ pub enum SigevNotify {
target_env = "gnu",
target_env = "uclibc",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
SigevThreadId {
/// Signal to send
signal: Signal,
@@ -1082,10 +1159,10 @@ pub enum SigevNotify {
#[cfg(not(any(
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "openbsd",
target_os = "redox"
)))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
mod sigevent {
feature! {
#![any(feature = "aio", feature = "signal")]
@@ -1251,7 +1328,7 @@ mod sigevent {
sev.sigev_signo = signal as libc::c_int;
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void
},
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
+ #[cfg(freebsdlike)]
SigevNotify::SigevKevent{kq, udata} => {
sev.sigev_notify = libc::SIGEV_KEVENT;
sev.sigev_signo = kq;
@@ -1331,227 +1408,3 @@ mod sigevent {
}
}
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[cfg(not(target_os = "redox"))]
- use std::thread;
-
- #[test]
- fn test_contains() {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- assert!(mask.contains(SIGUSR1));
- assert!(!mask.contains(SIGUSR2));
-
- let all = SigSet::all();
- assert!(all.contains(SIGUSR1));
- assert!(all.contains(SIGUSR2));
- }
-
- #[test]
- fn test_clear() {
- let mut set = SigSet::all();
- set.clear();
- for signal in Signal::iterator() {
- assert!(!set.contains(signal));
- }
- }
-
- #[test]
- fn test_from_str_round_trips() {
- for signal in Signal::iterator() {
- assert_eq!(signal.as_ref().parse::<Signal>().unwrap(), signal);
- assert_eq!(signal.to_string().parse::<Signal>().unwrap(), signal);
- }
- }
-
- #[test]
- fn test_from_str_invalid_value() {
- let errval = Err(Errno::EINVAL);
- assert_eq!("NOSIGNAL".parse::<Signal>(), errval);
- assert_eq!("kill".parse::<Signal>(), errval);
- assert_eq!("9".parse::<Signal>(), errval);
- }
-
- #[test]
- fn test_extend() {
- let mut one_signal = SigSet::empty();
- one_signal.add(SIGUSR1);
-
- let mut two_signals = SigSet::empty();
- two_signals.add(SIGUSR2);
- two_signals.extend(&one_signal);
-
- assert!(two_signals.contains(SIGUSR1));
- assert!(two_signals.contains(SIGUSR2));
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_set_mask() {
- thread::spawn(|| {
- let prev_mask = SigSet::thread_get_mask()
- .expect("Failed to get existing signal mask!");
-
- let mut test_mask = prev_mask;
- test_mask.add(SIGUSR1);
-
- test_mask.thread_set_mask().expect("assertion failed");
- let new_mask =
- SigSet::thread_get_mask().expect("Failed to get new mask!");
-
- assert!(new_mask.contains(SIGUSR1));
- assert!(!new_mask.contains(SIGUSR2));
-
- prev_mask
- .thread_set_mask()
- .expect("Failed to revert signal mask!");
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_block() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- mask.thread_block().expect("assertion failed");
-
- assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_unblock() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- mask.thread_unblock().expect("assertion failed");
-
- assert!(!SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_swap() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
- mask.thread_block().unwrap();
-
- assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
-
- let mut mask2 = SigSet::empty();
- mask2.add(SIGUSR2);
-
- let oldmask =
- mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK).unwrap();
-
- assert!(oldmask.contains(SIGUSR1));
- assert!(!oldmask.contains(SIGUSR2));
-
- assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2));
- })
- .join()
- .unwrap();
- }
-
- #[test]
- fn test_from_and_into_iterator() {
- let sigset = SigSet::from_iter(vec![Signal::SIGUSR1, Signal::SIGUSR2]);
- let signals = sigset.into_iter().collect::<Vec<Signal>>();
- assert_eq!(signals, [Signal::SIGUSR1, Signal::SIGUSR2]);
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_sigaction() {
- thread::spawn(|| {
- extern "C" fn test_sigaction_handler(_: libc::c_int) {}
- extern "C" fn test_sigaction_action(
- _: libc::c_int,
- _: *mut libc::siginfo_t,
- _: *mut libc::c_void,
- ) {
- }
-
- let handler_sig = SigHandler::Handler(test_sigaction_handler);
-
- let flags =
- SaFlags::SA_ONSTACK | SaFlags::SA_RESTART | SaFlags::SA_SIGINFO;
-
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- let action_sig = SigAction::new(handler_sig, flags, mask);
-
- assert_eq!(
- action_sig.flags(),
- SaFlags::SA_ONSTACK | SaFlags::SA_RESTART
- );
- assert_eq!(action_sig.handler(), handler_sig);
-
- mask = action_sig.mask();
- assert!(mask.contains(SIGUSR1));
- assert!(!mask.contains(SIGUSR2));
-
- let handler_act = SigHandler::SigAction(test_sigaction_action);
- let action_act = SigAction::new(handler_act, flags, mask);
- assert_eq!(action_act.handler(), handler_act);
-
- let action_dfl = SigAction::new(SigHandler::SigDfl, flags, mask);
- assert_eq!(action_dfl.handler(), SigHandler::SigDfl);
-
- let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask);
- assert_eq!(action_ign.handler(), SigHandler::SigIgn);
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_sigwait() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
- mask.add(SIGUSR2);
- mask.thread_block().unwrap();
-
- raise(SIGUSR1).unwrap();
- assert_eq!(mask.wait().unwrap(), SIGUSR1);
- })
- .join()
- .unwrap();
- }
-
- #[test]
- fn test_from_sigset_t_unchecked() {
- let src_set = SigSet::empty();
- let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) };
-
- for signal in Signal::iterator() {
- assert!(!set.contains(signal));
- }
-
- let src_set = SigSet::all();
- let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) };
-
- for signal in Signal::iterator() {
- assert!(set.contains(signal));
- }
- }
-}
diff --git a/third_party/rust/nix/src/sys/signalfd.rs b/third_party/rust/nix/src/sys/signalfd.rs
index 2b80ea643f..ccba774d1a 100644
--- a/third_party/rust/nix/src/sys/signalfd.rs
+++ b/third_party/rust/nix/src/sys/signalfd.rs
@@ -21,7 +21,7 @@ use crate::Result;
pub use libc::signalfd_siginfo as siginfo;
use std::mem;
-use std::os::unix::io::{AsRawFd, RawFd, FromRawFd, OwnedFd, AsFd, BorrowedFd};
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
libc_bitflags! {
pub struct SfdFlags: libc::c_int {
@@ -45,18 +45,23 @@ pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();
///
/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
#[deprecated(since = "0.27.0", note = "Use SignalFd instead")]
-pub fn signalfd<F: AsFd>(fd: Option<F>, mask: &SigSet, flags: SfdFlags) -> Result<OwnedFd> {
+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());
+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(
- raw_fd,
- mask.as_ref(),
- flags.bits(),
- )).map(|raw_fd|FromRawFd::from_raw_fd(raw_fd))
+ Errno::result(libc::signalfd(raw_fd, mask.as_ref(), flags.bits()))
+ .map(|raw_fd| FromRawFd::from_raw_fd(raw_fd))
}
}
@@ -101,7 +106,7 @@ impl SignalFd {
}
pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
- _signalfd(Some(self.0.as_fd()), mask, SfdFlags::empty()).map(drop)
+ self.update(mask, SfdFlags::empty())
}
pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
@@ -109,7 +114,7 @@ impl SignalFd {
let size = mem::size_of_val(&buffer);
let res = Errno::result(unsafe {
- libc::read(self.0.as_raw_fd(), buffer.as_mut_ptr() as *mut libc::c_void, size)
+ libc::read(self.0.as_raw_fd(), buffer.as_mut_ptr().cast(), size)
})
.map(|r| r as usize);
match res {
@@ -119,6 +124,14 @@ impl SignalFd {
Err(error) => Err(error),
}
}
+
+ fn update(&self, mask: &SigSet, flags: SfdFlags) -> Result<()> {
+ let raw_fd = self.0.as_raw_fd();
+ unsafe {
+ Errno::result(libc::signalfd(raw_fd, mask.as_ref(), flags.bits()))
+ .map(drop)
+ }
+ }
}
impl AsFd for SignalFd {
@@ -142,34 +155,3 @@ impl Iterator for SignalFd {
}
}
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn create_signalfd() {
- let mask = SigSet::empty();
- SignalFd::new(&mask).unwrap();
- }
-
- #[test]
- fn create_signalfd_with_opts() {
- let mask = SigSet::empty();
- SignalFd::with_flags(
- &mask,
- SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK,
- )
- .unwrap();
- }
-
- #[test]
- fn read_empty_signalfd() {
- let mask = SigSet::empty();
- let mut fd =
- SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
-
- let res = fd.read_signal();
- assert!(res.unwrap().is_none());
- }
-}
diff --git a/third_party/rust/nix/src/sys/socket/addr.rs b/third_party/rust/nix/src/sys/socket/addr.rs
index 1783531d49..f6800aa5d0 100644
--- a/third_party/rust/nix/src/sys/socket/addr.rs
+++ b/third_party/rust/nix/src/sys/socket/addr.rs
@@ -1,31 +1,22 @@
#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd",
+ bsd,
+ linux_android,
+ solarish,
target_os = "haiku",
target_os = "fuchsia",
target_os = "aix",
))]
#[cfg(feature = "net")]
pub use self::datalink::LinkAddr;
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+#[cfg(any(linux_android, apple_targets))]
pub use self::vsock::VsockAddr;
use super::sa_family_t;
use crate::errno::Errno;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
use crate::sys::socket::addr::alg::AlgAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
use crate::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
-))]
+#[cfg(all(feature = "ioctl", apple_targets))]
use crate::sys::socket::addr::sys_control::SysControlAddr;
use crate::{NixPath, Result};
use cfg_if::cfg_if;
@@ -33,6 +24,7 @@ use memoffset::offset_of;
use std::convert::TryInto;
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
+use std::net::{Ipv4Addr, Ipv6Addr};
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::{fmt, mem, net, ptr, slice};
@@ -41,7 +33,7 @@ use std::{fmt, mem, net, ptr, slice};
#[cfg(feature = "net")]
pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr {
libc::in_addr {
- s_addr: u32::from_ne_bytes(addr.octets())
+ s_addr: u32::from_ne_bytes(addr.octets()),
}
}
@@ -49,7 +41,7 @@ pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr {
#[cfg(feature = "net")]
pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr {
libc::in6_addr {
- s6_addr: addr.octets()
+ s6_addr: addr.octets(),
}
}
@@ -71,346 +63,188 @@ pub enum AddressFamily {
/// IPv6 Internet protocols (see [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html))
Inet6 = libc::AF_INET6,
/// Kernel user interface device (see [`netlink(7)`](https://man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Netlink = libc::AF_NETLINK,
/// Kernel interface for interacting with the routing table
- #[cfg(not(any(
- target_os = "redox",
- target_os = "linux",
- target_os = "android"
- )))]
+ #[cfg(not(any(linux_android, target_os = "redox")))]
Route = libc::PF_ROUTE,
/// Low level packet interface (see [`packet(7)`](https://man7.org/linux/man-pages/man7/packet.7.html))
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "illumos",
- target_os = "fuchsia",
- target_os = "solaris"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, solarish, target_os = "fuchsia"))]
Packet = libc::AF_PACKET,
/// KEXT Controls and Notifications
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
System = libc::AF_SYSTEM,
/// Amateur radio AX.25 protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Ax25 = libc::AF_AX25,
/// IPX - Novell protocols
#[cfg(not(any(target_os = "aix", target_os = "redox")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Ipx = libc::AF_IPX,
/// AppleTalk
#[cfg(not(target_os = "redox"))]
AppleTalk = libc::AF_APPLETALK,
/// AX.25 packet layer protocol.
/// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetRom = libc::AF_NETROM,
/// Can't be used for creating sockets; mostly used for bridge
/// links in
/// [rtnetlink(7)](https://man7.org/linux/man-pages/man7/rtnetlink.7.html)
/// protocol commands.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Bridge = libc::AF_BRIDGE,
/// Access to raw ATM PVCs
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AtmPvc = libc::AF_ATMPVC,
/// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](https://man7.org/linux/man-pages/man7/x25.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
X25 = libc::AF_X25,
/// RATS (Radio Amateur Telecommunications Society) Open
/// Systems environment (ROSE) AX.25 packet layer protocol.
/// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Rose = libc::AF_ROSE,
/// DECet protocol sockets.
#[cfg(not(any(target_os = "haiku", target_os = "redox")))]
Decnet = libc::AF_DECnet,
/// Reserved for "802.2LLC project"; never used.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetBeui = libc::AF_NETBEUI,
/// This was a short-lived (between Linux 2.1.30 and
/// 2.1.99pre2) protocol family for firewall upcalls.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Security = libc::AF_SECURITY,
/// Key management protocol.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Key = libc::AF_KEY,
#[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Ash = libc::AF_ASH,
/// Acorn Econet protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Econet = libc::AF_ECONET,
/// Access to ATM Switched Virtual Circuits
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AtmSvc = libc::AF_ATMSVC,
/// Reliable Datagram Sockets (RDS) protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Rds = libc::AF_RDS,
/// IBM SNA
#[cfg(not(any(target_os = "haiku", target_os = "redox")))]
Sna = libc::AF_SNA,
/// Socket interface over IrDA
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Irda = libc::AF_IRDA,
/// Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE)
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Pppox = libc::AF_PPPOX,
/// Legacy protocol for wide area network (WAN) connectivity that was used
/// by Sangoma WAN cards
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Wanpipe = libc::AF_WANPIPE,
/// Logical link control (IEEE 802.2 LLC) protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Llc = libc::AF_LLC,
/// InfiniBand native addressing
#[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Ib = libc::AF_IB,
/// Multiprotocol Label Switching
#[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Mpls = libc::AF_MPLS,
/// Controller Area Network automotive bus protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Can = libc::AF_CAN,
/// TIPC, "cluster domain sockets" protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Tipc = libc::AF_TIPC,
/// Bluetooth low-level socket protocol
#[cfg(not(any(
target_os = "aix",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "solaris",
+ solarish,
+ apple_targets,
+ target_os = "hurd",
target_os = "redox",
)))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Bluetooth = libc::AF_BLUETOOTH,
/// IUCV (inter-user communication vehicle) z/VM protocol for
/// hypervisor-guest interaction
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Iucv = libc::AF_IUCV,
/// Rx, Andrew File System remote procedure call protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
RxRpc = libc::AF_RXRPC,
/// New "modular ISDN" driver interface protocol
#[cfg(not(any(
target_os = "aix",
- target_os = "illumos",
- target_os = "solaris",
+ solarish,
target_os = "haiku",
+ target_os = "hurd",
target_os = "redox",
)))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Isdn = libc::AF_ISDN,
/// Nokia cellular modem IPC/RPC interface
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Phonet = libc::AF_PHONET,
/// IEEE 802.15.4 WPAN (wireless personal area network) raw packet protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Ieee802154 = libc::AF_IEEE802154,
/// Ericsson's Communication CPU to Application CPU interface (CAIF)
/// protocol.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Caif = libc::AF_CAIF,
/// Interface to kernel crypto API
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Alg = libc::AF_ALG,
/// Near field communication
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Nfc = libc::AF_NFC,
/// VMWare VSockets protocol for hypervisor-guest interaction.
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
Vsock = libc::AF_VSOCK,
/// ARPANet IMP addresses
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
ImpLink = libc::AF_IMPLINK,
/// PUP protocols, e.g. BSP
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Pup = libc::AF_PUP,
/// MIT CHAOS protocols
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Chaos = libc::AF_CHAOS,
/// Novell and Xerox protocol
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(apple_targets, netbsdlike))]
Ns = libc::AF_NS,
#[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Iso = libc::AF_ISO,
/// Bell Labs virtual circuit switch ?
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Datakit = libc::AF_DATAKIT,
/// CCITT protocols, X.25 etc
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Ccitt = libc::AF_CCITT,
/// DEC Direct data link interface
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Dli = libc::AF_DLI,
#[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Lat = libc::AF_LAT,
/// NSC Hyperchannel
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Hylink = libc::AF_HYLINK,
/// Link layer interface
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(bsd, solarish))]
Link = libc::AF_LINK,
/// connection-oriented IP, aka ST II
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Coip = libc::AF_COIP,
/// Computer Network Technology
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Cnt = libc::AF_CNT,
/// Native ATM access
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Natm = libc::AF_NATM,
/// Unspecified address family, (see [`getaddrinfo(3)`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Unspec = libc::AF_UNSPEC,
}
@@ -425,29 +259,17 @@ impl AddressFamily {
libc::AF_UNIX => Some(AddressFamily::Unix),
libc::AF_INET => Some(AddressFamily::Inet),
libc::AF_INET6 => Some(AddressFamily::Inet6),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_NETLINK => Some(AddressFamily::Netlink),
- #[cfg(any(target_os = "macos", target_os = "macos"))]
+ #[cfg(apple_targets)]
libc::AF_SYSTEM => Some(AddressFamily::System),
- #[cfg(not(any(
- target_os = "redox",
- target_os = "linux",
- target_os = "android"
- )))]
+ #[cfg(not(any(linux_android, target_os = "redox")))]
libc::PF_ROUTE => Some(AddressFamily::Route),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_PACKET => Some(AddressFamily::Packet),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
libc::AF_LINK => Some(AddressFamily::Link),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
libc::AF_VSOCK => Some(AddressFamily::Vsock),
_ => None,
}
@@ -463,13 +285,7 @@ pub struct UnixAddr {
/// The length of the valid part of `sun`, including the sun_family field
/// but excluding any trailing nul.
// On the BSDs, this field is built into sun
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
- target_os = "redox",
- ))]
+ #[cfg(not(any(bsd, target_os = "haiku", target_os = "hurd")))]
sun_len: u8,
}
@@ -483,12 +299,12 @@ pub struct UnixAddr {
enum UnixAddrKind<'a> {
Pathname(&'a Path),
Unnamed,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
Abstract(&'a [u8]),
}
impl<'a> UnixAddrKind<'a> {
/// Safety: sun & sun_len must be valid
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
unsafe fn get(sun: &'a libc::sockaddr_un, sun_len: u8) -> Self {
assert!(sun_len as usize >= offset_of!(libc::sockaddr_un, sun_path));
let path_len =
@@ -496,16 +312,19 @@ impl<'a> UnixAddrKind<'a> {
if path_len == 0 {
return Self::Unnamed;
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
if sun.sun_path[0] == 0 {
- let name = slice::from_raw_parts(
- sun.sun_path.as_ptr().add(1) as *const u8,
- path_len - 1,
- );
+ let name = unsafe {
+ slice::from_raw_parts(
+ sun.sun_path.as_ptr().add(1).cast(),
+ path_len - 1,
+ )
+ };
return Self::Abstract(name);
}
- let pathname =
- slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len);
+ let pathname = unsafe {
+ slice::from_raw_parts(sun.sun_path.as_ptr().cast(), path_len)
+ };
if pathname.last() == Some(&0) {
// A trailing NUL is not considered part of the path, and it does
// not need to be included in the addrlen passed to functions like
@@ -525,7 +344,7 @@ impl<'a> UnixAddrKind<'a> {
impl UnixAddr {
/// Create a new sockaddr_un representing a filesystem path.
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
pub fn new<P: ?Sized + NixPath>(path: &P) -> Result<UnixAddr> {
path.with_nix_path(|cstr| unsafe {
let mut ret = libc::sockaddr_un {
@@ -544,20 +363,13 @@ impl UnixAddr {
.try_into()
.unwrap();
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, target_os = "haiku", target_os = "hurd"))]
{
ret.sun_len = sun_len;
}
ptr::copy_nonoverlapping(
bytes.as_ptr(),
- ret.sun_path.as_mut_ptr() as *mut u8,
+ ret.sun_path.as_mut_ptr().cast(),
bytes.len(),
);
@@ -571,9 +383,8 @@ impl UnixAddr {
/// thus the input `path` is expected to be the bare name, not NUL-prefixed.
/// This is a Linux-specific extension, primarily used to allow chrooted
/// processes to communicate with processes having a different filesystem view.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
+ #[cfg(linux_android)]
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
pub fn new_abstract(path: &[u8]) -> Result<UnixAddr> {
unsafe {
let mut ret = libc::sockaddr_un {
@@ -593,7 +404,7 @@ impl UnixAddr {
// b'\0', so copy starting one byte in.
ptr::copy_nonoverlapping(
path.as_ptr(),
- ret.sun_path.as_mut_ptr().offset(1) as *mut u8,
+ ret.sun_path.as_mut_ptr().offset(1).cast(),
path.len(),
);
@@ -602,8 +413,7 @@ impl UnixAddr {
}
/// Create a new `sockaddr_un` representing an "unnamed" unix socket address.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
pub fn new_unnamed() -> UnixAddr {
let ret = libc::sockaddr_un {
sun_family: AddressFamily::Unix as sa_family_t,
@@ -632,10 +442,9 @@ impl UnixAddr {
sun_len: u8,
) -> UnixAddr {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))]
{
@@ -664,8 +473,7 @@ impl UnixAddr {
///
/// For abstract sockets only the bare name is returned, without the
/// leading NUL byte. `None` is returned for unnamed or path-backed sockets.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
pub fn as_abstract(&self) -> Option<&[u8]> {
match self.kind() {
UnixAddrKind::Abstract(name) => Some(name),
@@ -674,8 +482,7 @@ impl UnixAddr {
}
/// Check if this address is an "unnamed" unix socket address.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
#[inline]
pub fn is_unnamed(&self) -> bool {
matches!(self.kind(), UnixAddrKind::Unnamed)
@@ -699,10 +506,9 @@ impl UnixAddr {
fn sun_len(&self) -> u8 {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))]
{
@@ -717,10 +523,10 @@ impl UnixAddr {
impl private::SockaddrLikePriv for UnixAddr {}
impl SockaddrLike for UnixAddr {
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
+ target_os = "redox"
))]
fn len(&self) -> libc::socklen_t {
self.sun_len.into()
@@ -740,27 +546,26 @@ impl SockaddrLike for UnixAddr {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_UNIX {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_UNIX } {
return None;
}
- let mut su: libc::sockaddr_un = mem::zeroed();
+ let mut su: libc::sockaddr_un = unsafe { mem::zeroed() };
let sup = &mut su as *mut libc::sockaddr_un as *mut u8;
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))] {
let su_len = len.unwrap_or(
mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
);
} else {
- let su_len = len.unwrap_or((*addr).sa_len as libc::socklen_t);
+ let su_len = unsafe { len.unwrap_or((*addr).sa_len as libc::socklen_t) };
}
- };
- ptr::copy(addr as *const u8, sup, su_len as usize);
- Some(Self::from_raw_parts(su, su_len as u8))
+ }
+ unsafe { ptr::copy(addr as *const u8, sup, su_len as usize) };
+ Some(unsafe { Self::from_raw_parts(su, su_len as u8) })
}
fn size() -> libc::socklen_t
@@ -770,14 +575,16 @@ impl SockaddrLike for UnixAddr {
mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
}
- unsafe fn set_length(&mut self, new_length: usize) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
+ unsafe fn set_length(
+ &mut self,
+ new_length: usize,
+ ) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
// `new_length` is only used on some platforms, so it must be provided even when not used
#![allow(unused_variables)]
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))] {
self.sun_len = new_length as u8;
@@ -793,7 +600,7 @@ impl AsRef<libc::sockaddr_un> for UnixAddr {
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
fn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Write;
f.write_str("@\"")?;
@@ -810,7 +617,7 @@ impl fmt::Display for UnixAddr {
match self.kind() {
UnixAddrKind::Pathname(path) => path.display().fmt(f),
UnixAddrKind::Unnamed => f.pad("<unbound UNIX socket>"),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
UnixAddrKind::Abstract(name) => fmt_abstract(name, f),
}
}
@@ -894,12 +701,7 @@ pub trait SockaddrLike: private::SockaddrLikePriv {
}
cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))] {
+ if #[cfg(bsd)] {
/// Return the length of valid data in the sockaddr structure.
///
/// For fixed-size sockaddrs, this should be the size of the
@@ -946,7 +748,10 @@ pub trait SockaddrLike: private::SockaddrLikePriv {
/// `new_length` must be a valid length for this type of address. Specifically, reads of that
/// length from `self` must be valid.
#[doc(hidden)]
- unsafe fn set_length(&mut self, _new_length: usize) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
+ unsafe fn set_length(
+ &mut self,
+ _new_length: usize,
+ ) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
Err(SocketAddressLengthNotDynamic)
}
}
@@ -1006,22 +811,20 @@ pub struct SockaddrIn(libc::sockaddr_in);
impl SockaddrIn {
/// Returns the IP address associated with this socket address, in native
/// endian.
- pub const fn ip(&self) -> libc::in_addr_t {
- u32::from_be(self.0.sin_addr.s_addr)
+ pub const fn ip(&self) -> net::Ipv4Addr {
+ let bytes = self.0.sin_addr.s_addr.to_ne_bytes();
+ let (a, b, c, d) = (bytes[0], bytes[1], bytes[2], bytes[3]);
+ Ipv4Addr::new(a, b, c, d)
}
/// Creates a new socket address from IPv4 octets and a port number.
pub fn new(a: u8, b: u8, c: u8, d: u8, port: u16) -> Self {
Self(libc::sockaddr_in {
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
+ bsd,
target_os = "aix",
target_os = "haiku",
- target_os = "openbsd"
+ target_os = "hurd"
))]
sin_len: Self::size() as u8,
sin_family: AddressFamily::Inet as sa_family_t,
@@ -1056,10 +859,10 @@ impl SockaddrLike for SockaddrIn {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_INET {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_INET } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1092,14 +895,10 @@ impl From<net::SocketAddrV4> for SockaddrIn {
fn from(addr: net::SocketAddrV4) -> Self {
Self(libc::sockaddr_in {
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
+ bsd,
target_os = "haiku",
target_os = "hermit",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
+ target_os = "hurd"
))]
sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
sin_family: AddressFamily::Inet as sa_family_t,
@@ -1143,8 +942,19 @@ impl SockaddrIn6 {
}
/// Returns the IP address associated with this socket address.
- pub fn ip(&self) -> net::Ipv6Addr {
- net::Ipv6Addr::from(self.0.sin6_addr.s6_addr)
+ pub const fn ip(&self) -> net::Ipv6Addr {
+ let bytes = self.0.sin6_addr.s6_addr;
+ let (a, b, c, d, e, f, g, h) = (
+ ((bytes[0] as u16) << 8) | bytes[1] as u16,
+ ((bytes[2] as u16) << 8) | bytes[3] as u16,
+ ((bytes[4] as u16) << 8) | bytes[5] as u16,
+ ((bytes[6] as u16) << 8) | bytes[7] as u16,
+ ((bytes[8] as u16) << 8) | bytes[9] as u16,
+ ((bytes[10] as u16) << 8) | bytes[11] as u16,
+ ((bytes[12] as u16) << 8) | bytes[13] as u16,
+ ((bytes[14] as u16) << 8) | bytes[15] as u16,
+ );
+ Ipv6Addr::new(a, b, c, d, e, f, g, h)
}
/// Returns the port number associated with this socket address, in native
@@ -1175,10 +985,10 @@ impl SockaddrLike for SockaddrIn6 {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_INET6 {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_INET6 } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1210,14 +1020,10 @@ impl From<net::SocketAddrV6> for SockaddrIn6 {
#[allow(clippy::needless_update)] // It isn't needless on Illumos
Self(libc::sockaddr_in6 {
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
+ bsd,
target_os = "haiku",
target_os = "hermit",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
+ target_os = "hurd"
))]
sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8,
sin6_family: AddressFamily::Inet6 as sa_family_t,
@@ -1273,18 +1079,17 @@ impl std::str::FromStr for SockaddrIn6 {
#[derive(Clone, Copy, Eq)]
#[repr(C)]
pub union SockaddrStorage {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
alg: AlgAddr,
- #[cfg(all(feature = "net", not(target_os = "redox")))]
+ #[cfg(all(
+ feature = "net",
+ not(any(target_os = "hurd", target_os = "redox"))
+ ))]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
dl: LinkAddr,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
nl: NetlinkAddr,
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
+ #[cfg(all(feature = "ioctl", apple_targets))]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
sctl: SysControlAddr,
#[cfg(feature = "net")]
@@ -1293,8 +1098,7 @@ pub union SockaddrStorage {
sin6: SockaddrIn6,
ss: libc::sockaddr_storage,
su: UnixAddr,
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos" ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
vsock: VsockAddr,
}
impl private::SockaddrLikePriv for SockaddrStorage {}
@@ -1316,21 +1120,22 @@ impl SockaddrLike for SockaddrStorage {
{
None
} else {
- let mut ss: libc::sockaddr_storage = mem::zeroed();
+ let mut ss: libc::sockaddr_storage = unsafe { mem::zeroed() };
let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8;
- ptr::copy(addr as *const u8, ssp, len as usize);
+ unsafe { ptr::copy(addr as *const u8, ssp, len as usize) };
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
))]
if i32::from(ss.ss_family) == libc::AF_UNIX {
// Safe because we UnixAddr is strictly smaller than
// SockaddrStorage, and we just initialized the structure.
- (*(&mut ss as *mut libc::sockaddr_storage
- as *mut UnixAddr))
- .sun_len = len as u8;
+ unsafe {
+ (*(&mut ss as *mut libc::sockaddr_storage
+ as *mut UnixAddr))
+ .sun_len = len as u8;
+ }
}
Some(Self { ss })
}
@@ -1338,68 +1143,47 @@ impl SockaddrLike for SockaddrStorage {
// If length is not available and addr is of a fixed-length type,
// copy it. If addr is of a variable length type and len is not
// available, then there's nothing we can do.
- match (*addr).sa_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_ALG => {
+ match unsafe { (*addr).sa_family as i32 } {
+ #[cfg(linux_android)]
+ libc::AF_ALG => unsafe {
AlgAddr::from_raw(addr, l).map(|alg| Self { alg })
- }
+ },
#[cfg(feature = "net")]
- libc::AF_INET => {
+ libc::AF_INET => unsafe {
SockaddrIn::from_raw(addr, l).map(|sin| Self { sin })
- }
+ },
#[cfg(feature = "net")]
- libc::AF_INET6 => {
+ libc::AF_INET6 => unsafe {
SockaddrIn6::from_raw(addr, l).map(|sin6| Self { sin6 })
- }
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
- ))]
+ },
+ #[cfg(any(bsd, solarish, target_os = "haiku"))]
#[cfg(feature = "net")]
- libc::AF_LINK => {
+ libc::AF_LINK => unsafe {
LinkAddr::from_raw(addr, l).map(|dl| Self { dl })
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => {
+ },
+ #[cfg(linux_android)]
+ libc::AF_NETLINK => unsafe {
NetlinkAddr::from_raw(addr, l).map(|nl| Self { nl })
- }
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ },
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
- libc::AF_PACKET => {
+ libc::AF_PACKET => unsafe {
LinkAddr::from_raw(addr, l).map(|dl| Self { dl })
- }
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- libc::AF_SYSTEM => {
+ },
+ #[cfg(all(feature = "ioctl", apple_targets))]
+ libc::AF_SYSTEM => unsafe {
SysControlAddr::from_raw(addr, l).map(|sctl| Self { sctl })
- }
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos" ))]
- libc::AF_VSOCK => {
+ },
+ #[cfg(any(linux_android, apple_targets))]
+ libc::AF_VSOCK => unsafe {
VsockAddr::from_raw(addr, l).map(|vsock| Self { vsock })
- }
+ },
_ => None,
}
}
}
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia", solarish))]
fn len(&self) -> libc::socklen_t {
match self.as_unix_addr() {
// The UnixAddr type knows its own length
@@ -1409,11 +1193,12 @@ impl SockaddrLike for SockaddrStorage {
}
}
- unsafe fn set_length(&mut self, new_length: usize) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
+ unsafe fn set_length(
+ &mut self,
+ new_length: usize,
+ ) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
match self.as_unix_addr_mut() {
- Some(addr) => {
- addr.set_length(new_length)
- },
+ Some(addr) => unsafe { addr.set_length(new_length) },
None => Err(SocketAddressLengthNotDynamic),
}
}
@@ -1457,10 +1242,9 @@ impl SockaddrStorage {
/// Downcast to an immutable `[UnixAddr]` reference.
pub fn as_unix_addr(&self) -> Option<&UnixAddr> {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
))]
{
let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
@@ -1487,10 +1271,9 @@ impl SockaddrStorage {
/// Downcast to a mutable `[UnixAddr]` reference.
pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
))]
{
let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
@@ -1514,29 +1297,17 @@ impl SockaddrStorage {
}
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
accessors! {as_alg_addr, as_alg_addr_mut, AlgAddr,
AddressFamily::Alg, libc::sockaddr_alg, alg}
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
accessors! {
as_link_addr, as_link_addr_mut, LinkAddr,
AddressFamily::Packet, libc::sockaddr_ll, dl}
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
accessors! {
as_link_addr, as_link_addr_mut, LinkAddr,
@@ -1552,17 +1323,16 @@ impl SockaddrStorage {
as_sockaddr_in6, as_sockaddr_in6_mut, SockaddrIn6,
AddressFamily::Inet6, libc::sockaddr_in6, sin6}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
accessors! {as_netlink_addr, as_netlink_addr_mut, NetlinkAddr,
AddressFamily::Netlink, libc::sockaddr_nl, nl}
- #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))]
+ #[cfg(all(feature = "ioctl", apple_targets))]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
accessors! {as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr,
AddressFamily::System, libc::sockaddr_ctl, sctl}
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
accessors! {as_vsock_addr, as_vsock_addr_mut, VsockAddr,
AddressFamily::Vsock, libc::sockaddr_vm, vsock}
}
@@ -1581,37 +1351,25 @@ impl fmt::Display for SockaddrStorage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe {
match self.ss.ss_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_ALG => self.alg.fmt(f),
#[cfg(feature = "net")]
libc::AF_INET => self.sin.fmt(f),
#[cfg(feature = "net")]
libc::AF_INET6 => self.sin6.fmt(f),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
libc::AF_LINK => self.dl.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_NETLINK => self.nl.fmt(f),
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "fuchsia"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
libc::AF_PACKET => self.dl.fmt(f),
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
libc::AF_SYSTEM => self.sctl.fmt(f),
libc::AF_UNIX => self.su.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
libc::AF_VSOCK => self.vsock.fmt(f),
_ => "<Address family unspecified>".fmt(f),
}
@@ -1655,37 +1413,25 @@ impl Hash for SockaddrStorage {
fn hash<H: Hasher>(&self, s: &mut H) {
unsafe {
match self.ss.ss_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_ALG => self.alg.hash(s),
#[cfg(feature = "net")]
libc::AF_INET => self.sin.hash(s),
#[cfg(feature = "net")]
libc::AF_INET6 => self.sin6.hash(s),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
libc::AF_LINK => self.dl.hash(s),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_NETLINK => self.nl.hash(s),
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "fuchsia"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
libc::AF_PACKET => self.dl.hash(s),
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
libc::AF_SYSTEM => self.sctl.hash(s),
libc::AF_UNIX => self.su.hash(s),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
libc::AF_VSOCK => self.vsock.hash(s),
_ => self.ss.hash(s),
}
@@ -1697,37 +1443,25 @@ impl PartialEq for SockaddrStorage {
fn eq(&self, other: &Self) -> bool {
unsafe {
match (self.ss.ss_family as i32, other.ss.ss_family as i32) {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
(libc::AF_ALG, libc::AF_ALG) => self.alg == other.alg,
#[cfg(feature = "net")]
(libc::AF_INET, libc::AF_INET) => self.sin == other.sin,
#[cfg(feature = "net")]
(libc::AF_INET6, libc::AF_INET6) => self.sin6 == other.sin6,
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
(libc::AF_LINK, libc::AF_LINK) => self.dl == other.dl,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
(libc::AF_NETLINK, libc::AF_NETLINK) => self.nl == other.nl,
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
(libc::AF_PACKET, libc::AF_PACKET) => self.dl == other.dl,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
(libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl,
(libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su,
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
(libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock,
_ => false,
}
@@ -1751,8 +1485,7 @@ pub(super) mod private {
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(linux_android)]
pub mod netlink {
use super::*;
use crate::sys::socket::addr::AddressFamily;
@@ -1805,10 +1538,10 @@ pub mod netlink {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_NETLINK {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_NETLINK } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1825,11 +1558,10 @@ pub mod netlink {
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(linux_android)]
pub mod alg {
use super::*;
- use libc::{c_char, sockaddr_alg, AF_ALG};
+ use libc::{sockaddr_alg, AF_ALG};
use std::ffi::CStr;
use std::hash::{Hash, Hasher};
use std::{fmt, mem, str};
@@ -1854,10 +1586,10 @@ pub mod alg {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_ALG {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_ALG } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1918,16 +1650,12 @@ pub mod alg {
/// Return the socket's cipher type, for example `hash` or `aead`.
pub fn alg_type(&self) -> &CStr {
- unsafe {
- CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char)
- }
+ unsafe { CStr::from_ptr(self.0.salg_type.as_ptr().cast()) }
}
/// Return the socket's cipher name, for example `sha1`.
pub fn alg_name(&self) -> &CStr {
- unsafe {
- CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char)
- }
+ unsafe { CStr::from_ptr(self.0.salg_name.as_ptr().cast()) }
}
}
@@ -1951,7 +1679,7 @@ pub mod alg {
feature! {
#![feature = "ioctl"]
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(apple_targets)]
pub mod sys_control {
use crate::sys::socket::addr::AddressFamily;
use libc::{self, c_uchar};
@@ -1994,10 +1722,10 @@ pub mod sys_control {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_SYSTEM {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_SYSTEM } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) } ))
}
}
@@ -2058,8 +1786,7 @@ pub mod sys_control {
}
}
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
mod datalink {
feature! {
#![feature = "net"]
@@ -2136,10 +1863,10 @@ mod datalink {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_PACKET {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_PACKET } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -2152,18 +1879,7 @@ mod datalink {
}
}
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "aix",
- target_os = "openbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(bsd, solarish, target_os = "haiku", target_os = "aix"))]
mod datalink {
feature! {
#![feature = "net"]
@@ -2261,10 +1977,10 @@ mod datalink {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_LINK {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_LINK } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -2276,8 +1992,7 @@ mod datalink {
}
}
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(linux_android, apple_targets))]
pub mod vsock {
use super::*;
use crate::sys::socket::addr::AddressFamily;
@@ -2308,10 +2023,10 @@ pub mod vsock {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_VSOCK {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_VSOCK } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ unsafe { Some(Self(ptr::read_unaligned(addr as *const _))) }
}
}
@@ -2322,32 +2037,47 @@ pub mod vsock {
}
impl PartialEq for VsockAddr {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
fn eq(&self, other: &Self) -> bool {
let (inner, other) = (self.0, other.0);
(inner.svm_family, inner.svm_cid, inner.svm_port)
== (other.svm_family, other.svm_cid, other.svm_port)
}
- #[cfg(target_os = "macos")]
+ #[cfg(apple_targets)]
fn eq(&self, other: &Self) -> bool {
let (inner, other) = (self.0, other.0);
- (inner.svm_family, inner.svm_cid, inner.svm_port, inner.svm_len)
- == (other.svm_family, other.svm_cid, other.svm_port, inner.svm_len)
+ (
+ inner.svm_family,
+ inner.svm_cid,
+ inner.svm_port,
+ inner.svm_len,
+ ) == (
+ other.svm_family,
+ other.svm_cid,
+ other.svm_port,
+ inner.svm_len,
+ )
}
}
impl Eq for VsockAddr {}
impl Hash for VsockAddr {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
fn hash<H: Hasher>(&self, s: &mut H) {
let inner = self.0;
(inner.svm_family, inner.svm_cid, inner.svm_port).hash(s);
}
- #[cfg(target_os = "macos")]
+ #[cfg(apple_targets)]
fn hash<H: Hasher>(&self, s: &mut H) {
let inner = self.0;
- (inner.svm_family, inner.svm_cid, inner.svm_port, inner.svm_len).hash(s);
+ (
+ inner.svm_family,
+ inner.svm_cid,
+ inner.svm_port,
+ inner.svm_len,
+ )
+ .hash(s);
}
}
@@ -2363,9 +2093,9 @@ pub mod vsock {
addr.svm_cid = cid;
addr.svm_port = port;
- #[cfg(target_os = "macos")]
+ #[cfg(apple_targets)]
{
- addr.svm_len = std::mem::size_of::<sockaddr_vm>() as u8;
+ addr.svm_len = std::mem::size_of::<sockaddr_vm>() as u8;
}
VsockAddr(addr)
}
@@ -2419,27 +2149,16 @@ mod tests {
}
}
- #[cfg(not(target_os = "redox"))]
+ #[cfg(not(any(target_os = "hurd", target_os = "redox")))]
mod link {
#![allow(clippy::cast_ptr_alignment)]
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos"
- ))]
+ #[cfg(any(apple_targets, solarish))]
use super::super::super::socklen_t;
use super::*;
/// Don't panic when trying to display an empty datalink address
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(bsd)]
#[test]
fn test_datalink_display() {
use super::super::LinkAddr;
@@ -2459,11 +2178,7 @@ mod tests {
}
#[cfg(all(
- any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ),
+ any(linux_android, target_os = "fuchsia"),
target_endian = "little"
))]
#[test]
@@ -2474,7 +2189,7 @@ mod tests {
let bytes = Raw([
17u8, 0, 0, 0, 1, 0, 0, 0, 4, 3, 0, 6, 1, 2, 3, 4, 5, 6, 0, 0,
]);
- let sa = bytes.0.as_ptr() as *const libc::sockaddr;
+ let sa = bytes.0.as_ptr().cast();
let len = None;
let sock_addr =
unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap();
@@ -2485,12 +2200,12 @@ mod tests {
}
}
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[test]
fn macos_loopback() {
let bytes =
[20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0];
- let sa = bytes.as_ptr() as *const libc::sockaddr;
+ let sa = bytes.as_ptr().cast();
let len = Some(bytes.len() as socklen_t);
let sock_addr =
unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap();
@@ -2503,7 +2218,7 @@ mod tests {
}
}
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[test]
fn macos_tap() {
let bytes = [
@@ -2525,9 +2240,9 @@ mod tests {
}
}
- #[cfg(target_os = "illumos")]
+ #[cfg(solarish)]
#[test]
- fn illumos_tap() {
+ fn solarish_tap() {
let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176];
let ptr = bytes.as_ptr();
let sa = ptr as *const libc::sockaddr;
@@ -2548,23 +2263,9 @@ mod tests {
#[test]
fn size() {
- #[cfg(any(
- target_os = "aix",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd",
- target_os = "haiku"
- ))]
+ #[cfg(any(bsd, target_os = "aix", solarish, target_os = "haiku"))]
let l = mem::size_of::<libc::sockaddr_dl>();
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
let l = mem::size_of::<libc::sockaddr_ll>();
assert_eq!(LinkAddr::size() as usize, l);
}
@@ -2588,6 +2289,13 @@ mod tests {
SockaddrIn::size() as usize
);
}
+
+ #[test]
+ fn ip() {
+ let s = "127.0.0.1:8082";
+ let ip = SockaddrIn::from_str(s).unwrap().ip();
+ assert_eq!("127.0.0.1", format!("{ip}"));
+ }
}
mod sockaddr_in6 {
@@ -2610,6 +2318,13 @@ mod tests {
}
#[test]
+ fn ip() {
+ let s = "[1234:5678:90ab:cdef::1111:2222]:8080";
+ let ip = SockaddrIn6::from_str(s).unwrap().ip();
+ assert_eq!("1234:5678:90ab:cdef::1111:2222", format!("{ip}"));
+ }
+
+ #[test]
// Ensure that we can convert to-and-from std::net variants without change.
fn to_and_from() {
let s = "[1234:5678:90ab:cdef::1111:2222]:8080";
@@ -2628,28 +2343,28 @@ mod tests {
#[test]
fn from_sockaddr_un_named() {
let ua = UnixAddr::new("/var/run/mysock").unwrap();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ptr = ua.as_ptr().cast();
let ss = unsafe { SockaddrStorage::from_raw(ptr, Some(ua.len())) }
.unwrap();
assert_eq!(ss.len(), ua.len());
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[test]
fn from_sockaddr_un_abstract_named() {
let name = String::from("nix\0abstract\0test");
let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ptr = ua.as_ptr().cast();
let ss = unsafe { SockaddrStorage::from_raw(ptr, Some(ua.len())) }
.unwrap();
assert_eq!(ss.len(), ua.len());
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[test]
fn from_sockaddr_un_abstract_unnamed() {
let ua = UnixAddr::new_unnamed();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ptr = ua.as_ptr().cast();
let ss = unsafe { SockaddrStorage::from_raw(ptr, Some(ua.len())) }
.unwrap();
assert_eq!(ss.len(), ua.len());
@@ -2659,7 +2374,7 @@ mod tests {
mod unixaddr {
use super::*;
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[test]
fn abstract_sun_path() {
let name = String::from("nix\0abstract\0test");
diff --git a/third_party/rust/nix/src/sys/socket/mod.rs b/third_party/rust/nix/src/sys/socket/mod.rs
index 78dd617c55..3d1651bd3f 100644
--- a/third_party/rust/nix/src/sys/socket/mod.rs
+++ b/third_party/rust/nix/src/sys/socket/mod.rs
@@ -1,7 +1,7 @@
//! Socket interface functions
//!
//! [Further reading](https://man7.org/linux/man-pages/man7/socket.7.html)
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "freebsd", linux_android))]
#[cfg(feature = "uio")]
use crate::sys::time::TimeSpec;
#[cfg(not(target_os = "redox"))]
@@ -9,16 +9,16 @@ use crate::sys::time::TimeSpec;
use crate::sys::time::TimeVal;
use crate::{errno::Errno, Result};
use cfg_if::cfg_if;
-use libc::{self, c_int, c_void, size_t, socklen_t};
+use libc::{self, c_int, size_t, socklen_t};
#[cfg(all(feature = "uio", not(target_os = "redox")))]
use libc::{
- iovec, CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE,
+ c_void, iovec, CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE,
};
#[cfg(not(target_os = "redox"))]
use std::io::{IoSlice, IoSliceMut};
#[cfg(feature = "net")]
use std::net;
-use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, RawFd, OwnedFd};
+use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::{mem, ptr};
#[deny(missing_docs)]
@@ -34,35 +34,25 @@ pub mod sockopt;
pub use self::addr::{SockaddrLike, SockaddrStorage};
-#[cfg(any(target_os = "illumos", target_os = "solaris"))]
+#[cfg(solarish)]
pub use self::addr::{AddressFamily, UnixAddr};
-#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
+#[cfg(not(solarish))]
pub use self::addr::{AddressFamily, UnixAddr};
-#[cfg(not(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku",
- target_os = "redox",
-)))]
+#[cfg(not(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox")))]
#[cfg(feature = "net")]
pub use self::addr::{LinkAddr, SockaddrIn, SockaddrIn6};
-#[cfg(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku",
- target_os = "redox",
-))]
+#[cfg(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox"))]
#[cfg(feature = "net")]
pub use self::addr::{SockaddrIn, SockaddrIn6};
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
pub use crate::sys::socket::addr::alg::AlgAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
pub use crate::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
pub use crate::sys::socket::addr::sys_control::SysControlAddr;
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+#[cfg(any(linux_android, apple_targets))]
pub use crate::sys::socket::addr::vsock::VsockAddr;
#[cfg(all(feature = "uio", not(target_os = "redox")))]
@@ -132,121 +122,108 @@ pub enum SockProtocol {
Udp = libc::IPPROTO_UDP,
/// Raw sockets ([raw(7)](https://man7.org/linux/man-pages/man7/raw.7.html))
Raw = libc::IPPROTO_RAW,
- /// Allows applications and other KEXTs to be notified when certain kernel events occur
- /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- KextEvent = libc::SYSPROTO_EVENT,
/// Allows applications to configure and control a KEXT
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
KextControl = libc::SYSPROTO_CONTROL,
/// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link
// parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkRoute = libc::NETLINK_ROUTE,
/// Reserved for user-mode socket protocols
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkUserSock = libc::NETLINK_USERSOCK,
/// Query information about sockets of various protocol families from the kernel
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkSockDiag = libc::NETLINK_SOCK_DIAG,
/// Netfilter/iptables ULOG.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkNFLOG = libc::NETLINK_NFLOG,
/// SELinux event notifications.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkSELinux = libc::NETLINK_SELINUX,
/// Open-iSCSI
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkISCSI = libc::NETLINK_ISCSI,
/// Auditing
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkAudit = libc::NETLINK_AUDIT,
/// Access to FIB lookup from user space
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP,
/// Netfilter subsystem
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkNetFilter = libc::NETLINK_NETFILTER,
/// SCSI Transports
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT,
/// Infiniband RDMA
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkRDMA = libc::NETLINK_RDMA,
/// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkIPv6Firewall = libc::NETLINK_IP6_FW,
/// DECnet routing messages
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG,
/// Kernel messages to user space
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT,
/// Generic netlink family for simplified netlink usage.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkGeneric = libc::NETLINK_GENERIC,
/// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow
/// configuration of the kernel crypto API.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetlinkCrypto = libc::NETLINK_CRYPTO,
/// Non-DIX type protocol number defined for the Ethernet IEEE 802.3 interface that allows packets of all protocols
/// defined in the interface to be received.
/// ([ref](https://man7.org/linux/man-pages/man7/packet.7.html))
// The protocol number is fed into the socket syscall in network byte order.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
EthAll = (libc::ETH_P_ALL as u16).to_be() as i32,
+ /// ICMP protocol ([icmp(7)](https://man7.org/linux/man-pages/man7/icmp.7.html))
+ Icmp = libc::IPPROTO_ICMP,
+ /// ICMPv6 protocol (ICMP over IPv6)
+ IcmpV6 = libc::IPPROTO_ICMPV6,
+}
+
+impl SockProtocol {
/// The Controller Area Network raw socket protocol
/// ([ref](https://docs.kernel.org/networking/can.html#how-to-use-socketcan))
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CanRaw = libc::CAN_RAW,
-}
+ #[allow(non_upper_case_globals)]
+ pub const CanRaw: SockProtocol = SockProtocol::Icmp; // Matches libc::CAN_RAW
-impl SockProtocol {
/// The Controller Area Network broadcast manager protocol
/// ([ref](https://docs.kernel.org/networking/can.html#how-to-use-socketcan))
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
#[allow(non_upper_case_globals)]
pub const CanBcm: SockProtocol = SockProtocol::NetlinkUserSock; // Matches libc::CAN_BCM
+
+ /// Allows applications and other KEXTs to be notified when certain kernel events occur
+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
+ #[cfg(apple_targets)]
+ #[allow(non_upper_case_globals)]
+ pub const KextEvent: SockProtocol = SockProtocol::Icmp; // Matches libc::SYSPROTO_EVENT
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
libc_bitflags! {
/// Configuration flags for `SO_TIMESTAMPING` interface
///
@@ -276,33 +253,23 @@ libc_bitflags! {
/// Additional socket options
pub struct SockFlag: c_int {
/// Set non-blocking mode on the new socket
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android,
+ freebsdlike,
+ netbsdlike,
+ solarish))]
SOCK_NONBLOCK;
/// Set close-on-exec on the new descriptor
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android,
+ freebsdlike,
+ netbsdlike,
+ solarish))]
SOCK_CLOEXEC;
/// Return `EPIPE` instead of raising `SIGPIPE`
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
SOCK_NOSIGPIPE;
/// For domains `AF_INET(6)`, only allow `connect(2)`, `sendto(2)`, or `sendmsg(2)`
/// to the DNS port (typically 53)
#[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
SOCK_DNS;
}
}
@@ -333,7 +300,6 @@ libc_bitflags! {
/// the calling process and as well as other processes that hold
/// file descriptors referring to the same open file description.
#[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MSG_DONTWAIT;
/// Receive flags: Control Data was discarded (buffer too small)
MSG_CTRUNC;
@@ -352,8 +318,7 @@ libc_bitflags! {
/// This flag specifies that queued errors should be received from
/// the socket error queue. (For more details, see
/// [recvfrom(2)](https://linux.die.net/man/2/recvfrom))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MSG_ERRQUEUE;
/// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain
/// file descriptor using the `SCM_RIGHTS` operation (described in
@@ -362,44 +327,48 @@ libc_bitflags! {
/// [open(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html).
///
/// Only used in [`recvmsg`](fn.recvmsg.html) function.
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, freebsdlike, netbsdlike))]
MSG_CMSG_CLOEXEC;
/// Requests not to send `SIGPIPE` errors when the other end breaks the connection.
/// (For more details, see [send(2)](https://linux.die.net/man/2/send)).
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
+ #[cfg(any(linux_android,
+ freebsdlike,
+ solarish,
+ netbsdlike,
target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ target_os = "haiku"))]
MSG_NOSIGNAL;
/// Turns on [`MSG_DONTWAIT`] after the first message has been received (only for
/// `recvmmsg()`).
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
+ netbsdlike,
target_os = "fuchsia",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ target_os = "freebsd"))]
MSG_WAITFORONE;
}
}
+#[cfg(target_os = "freebsd")]
+libc_enum! {
+ /// A selector for which clock to use when generating packet timestamps.
+ /// Used when setting [`TsClock`](crate::sys::socket::sockopt::TsClock) on a socket.
+ /// (For more details, see [setsockopt(2)](https://man.freebsd.org/cgi/man.cgi?setsockopt)).
+ #[repr(i32)]
+ #[non_exhaustive]
+ pub enum SocketTimestamp {
+ /// Microsecond resolution, realtime. This is the default.
+ SO_TS_REALTIME_MICRO,
+ /// Sub-nanosecond resolution, realtime.
+ SO_TS_BINTIME,
+ /// Nanosecond resolution, realtime.
+ SO_TS_REALTIME,
+ /// Nanosecond resolution, monotonic.
+ SO_TS_MONOTONIC,
+ }
+}
+
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(linux_android)] {
/// Unix credentials of the sending process.
///
/// This struct is used with the `SO_PEERCRED` ancillary message
@@ -454,7 +423,7 @@ cfg_if! {
uc.0
}
}
- } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] {
+ } else if #[cfg(freebsdlike)] {
/// Unix credentials of the sending process.
///
/// This struct is used with the `SCM_CREDS` ancillary message for UNIX sockets.
@@ -487,7 +456,7 @@ cfg_if! {
pub fn groups(&self) -> &[libc::gid_t] {
unsafe {
std::slice::from_raw_parts(
- self.0.cmcred_groups.as_ptr() as *const libc::gid_t,
+ self.0.cmcred_groups.as_ptr(),
self.0.cmcred_ngroups as _
)
}
@@ -503,12 +472,7 @@ cfg_if! {
}
cfg_if! {
- if #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
- ))] {
+ if #[cfg(any(freebsdlike, apple_targets))] {
/// Return type of [`LocalPeerCred`](crate::sys::socket::sockopt::LocalPeerCred)
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -603,8 +567,6 @@ feature! {
/// let _ = cmsg_space!(RawFd, TimeVal);
/// # }
/// ```
-// Unfortunately, CMSG_SPACE isn't a const_fn, or else we could return a
-// stack-allocated array.
#[macro_export]
macro_rules! cmsg_space {
( $( $x:ty ),* ) => {
@@ -617,7 +579,7 @@ macro_rules! cmsg_space {
#[inline]
#[doc(hidden)]
-pub fn cmsg_space<T>() -> usize {
+pub const fn cmsg_space<T>() -> usize {
// SAFETY: CMSG_SPACE is always safe
unsafe { libc::CMSG_SPACE(mem::size_of::<T>() as libc::c_uint) as usize }
}
@@ -677,7 +639,7 @@ impl<'a> Iterator for CmsgIterator<'a> {
}
/// A type-safe wrapper around a single control message, as used with
-/// [`recvmsg`](#fn.recvmsg).
+/// [`recvmsg`].
///
/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html)
// Nix version 0.13.0 and earlier used ControlMessage for both recvmsg and
@@ -692,12 +654,10 @@ pub enum ControlMessageOwned {
/// Received version of [`ControlMessage::ScmRights`]
ScmRights(Vec<RawFd>),
/// Received version of [`ControlMessage::ScmCredentials`]
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ScmCredentials(UnixCredentials),
/// Received version of [`ControlMessage::ScmCreds`]
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
ScmCreds(UnixCredentials),
/// A message of type `SCM_TIMESTAMP`, containing the time the
/// packet was received by the kernel.
@@ -760,62 +720,44 @@ pub enum ControlMessageOwned {
/// A set of nanosecond resolution timestamps
///
/// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ScmTimestampsns(Timestamps),
/// Nanoseconds resolution timestamp
///
/// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ScmTimestampns(TimeSpec),
- #[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- ))]
+ /// Realtime clock timestamp
+ ///
+ /// [Further reading](https://man.freebsd.org/cgi/man.cgi?setsockopt)
+ #[cfg(target_os = "freebsd")]
+ ScmRealtime(TimeSpec),
+ /// Monotonic clock timestamp
+ ///
+ /// [Further reading](https://man.freebsd.org/cgi/man.cgi?setsockopt)
+ #[cfg(target_os = "freebsd")]
+ ScmMonotonic(TimeSpec),
+ #[cfg(any(linux_android, apple_targets, target_os = "netbsd"))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4PacketInfo(libc::in_pktinfo),
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "openbsd",
- target_os = "netbsd",
- ))]
+ #[cfg(any(linux_android, bsd))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv6PacketInfo(libc::in6_pktinfo),
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(bsd)]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4RecvIf(libc::sockaddr_dl),
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(bsd)]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4RecvDstAddr(libc::in_addr),
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+ #[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4OrigDstAddr(libc::sockaddr_in),
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+ #[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv6OrigDstAddr(libc::sockaddr_in6),
@@ -841,28 +783,31 @@ pub enum ControlMessageOwned {
///
/// `RxqOvfl` socket option should be enabled on a socket
/// to allow receiving the drop counter.
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
RxqOvfl(u32),
/// Socket error queue control messages read with the `MSG_ERRQUEUE` flag.
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4RecvErr(libc::sock_extended_err, Option<sockaddr_in>),
/// Socket error queue control messages read with the `MSG_ERRQUEUE` flag.
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv6RecvErr(libc::sock_extended_err, Option<sockaddr_in6>),
+ /// `SOL_TLS` messages of type `TLS_GET_RECORD_TYPE`
+ #[cfg(any(target_os = "linux"))]
+ TlsGetRecordType(TlsGetRecordType),
+
/// Catch-all variant for unimplemented cmsg types.
#[doc(hidden)]
Unknown(UnknownCmsg),
}
/// For representing packet timestamps via `SO_TIMESTAMPING` interface
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Timestamps {
/// software based timestamp, usually one containing data
@@ -873,6 +818,33 @@ pub struct Timestamps {
pub hw_raw: TimeSpec,
}
+/// These constants correspond to TLS 1.2 message types, as defined in
+/// RFC 5246, Appendix A.1
+#[cfg(any(target_os = "linux"))]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[repr(u8)]
+#[non_exhaustive]
+pub enum TlsGetRecordType {
+ ChangeCipherSpec ,
+ Alert,
+ Handshake,
+ ApplicationData,
+ Unknown(u8),
+}
+
+#[cfg(any(target_os = "linux"))]
+impl From<u8> for TlsGetRecordType {
+ fn from(x: u8) -> Self {
+ match x {
+ 20 => TlsGetRecordType::ChangeCipherSpec,
+ 21 => TlsGetRecordType::Alert,
+ 22 => TlsGetRecordType::Handshake,
+ 23 => TlsGetRecordType::ApplicationData,
+ _ => TlsGetRecordType::Unknown(x),
+ }
+ }
+}
+
impl ControlMessageOwned {
/// Decodes a `ControlMessageOwned` from raw bytes.
///
@@ -885,7 +857,7 @@ impl ControlMessageOwned {
#[allow(clippy::cast_ptr_alignment)]
unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned
{
- let p = CMSG_DATA(header);
+ let p = unsafe { CMSG_DATA(header) };
// The cast is not unnecessary on all platforms.
#[allow(clippy::unnecessary_cast)]
let len = header as *const _ as usize + header.cmsg_len as usize
@@ -895,158 +867,151 @@ impl ControlMessageOwned {
let n = len / mem::size_of::<RawFd>();
let mut fds = Vec::with_capacity(n);
for i in 0..n {
- let fdp = (p as *const RawFd).add(i);
- fds.push(ptr::read_unaligned(fdp));
+ unsafe {
+ let fdp = (p as *const RawFd).add(i);
+ fds.push(ptr::read_unaligned(fdp));
+ }
}
ControlMessageOwned::ScmRights(fds)
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
(libc::SOL_SOCKET, libc::SCM_CREDENTIALS) => {
- let cred: libc::ucred = ptr::read_unaligned(p as *const _);
+ let cred: libc::ucred = unsafe { ptr::read_unaligned(p as *const _) };
ControlMessageOwned::ScmCredentials(cred.into())
}
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
(libc::SOL_SOCKET, libc::SCM_CREDS) => {
- let cred: libc::cmsgcred = ptr::read_unaligned(p as *const _);
+ let cred: libc::cmsgcred = unsafe { ptr::read_unaligned(p as *const _) };
ControlMessageOwned::ScmCreds(cred.into())
}
#[cfg(not(any(target_os = "aix", target_os = "haiku")))]
(libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => {
- let tv: libc::timeval = ptr::read_unaligned(p as *const _);
+ let tv: libc::timeval = unsafe { ptr::read_unaligned(p as *const _) };
ControlMessageOwned::ScmTimestamp(TimeVal::from(tv))
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
(libc::SOL_SOCKET, libc::SCM_TIMESTAMPNS) => {
- let ts: libc::timespec = ptr::read_unaligned(p as *const _);
+ let ts: libc::timespec = unsafe { ptr::read_unaligned(p as *const _) };
ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts))
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(target_os = "freebsd")]
+ (libc::SOL_SOCKET, libc::SCM_REALTIME) => {
+ let ts: libc::timespec = unsafe { ptr::read_unaligned(p as *const _) };
+ ControlMessageOwned::ScmRealtime(TimeSpec::from(ts))
+ }
+ #[cfg(target_os = "freebsd")]
+ (libc::SOL_SOCKET, libc::SCM_MONOTONIC) => {
+ let ts: libc::timespec = unsafe { ptr::read_unaligned(p as *const _) };
+ ControlMessageOwned::ScmMonotonic(TimeSpec::from(ts))
+ }
+ #[cfg(linux_android)]
(libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => {
let tp = p as *const libc::timespec;
- let ts: libc::timespec = ptr::read_unaligned(tp);
+ let ts: libc::timespec = unsafe { ptr::read_unaligned(tp) };
let system = TimeSpec::from(ts);
- let ts: libc::timespec = ptr::read_unaligned(tp.add(1));
+ let ts: libc::timespec = unsafe { ptr::read_unaligned(tp.add(1)) };
let hw_trans = TimeSpec::from(ts);
- let ts: libc::timespec = ptr::read_unaligned(tp.add(2));
+ let ts: libc::timespec = unsafe { ptr::read_unaligned(tp.add(2)) };
let hw_raw = TimeSpec::from(ts);
let timestamping = Timestamps { system, hw_trans, hw_raw };
ControlMessageOwned::ScmTimestampsns(timestamping)
}
- #[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"
- ))]
+ #[cfg(any(target_os = "freebsd", linux_android, apple_targets))]
#[cfg(feature = "net")]
(libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => {
- let info = ptr::read_unaligned(p as *const libc::in6_pktinfo);
+ let info = unsafe { ptr::read_unaligned(p as *const libc::in6_pktinfo) };
ControlMessageOwned::Ipv6PacketInfo(info)
}
- #[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- ))]
+ #[cfg(any(linux_android, apple_targets, target_os = "netbsd"))]
#[cfg(feature = "net")]
(libc::IPPROTO_IP, libc::IP_PKTINFO) => {
- let info = ptr::read_unaligned(p as *const libc::in_pktinfo);
+ let info = unsafe { ptr::read_unaligned(p as *const libc::in_pktinfo) };
ControlMessageOwned::Ipv4PacketInfo(info)
}
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(bsd)]
#[cfg(feature = "net")]
(libc::IPPROTO_IP, libc::IP_RECVIF) => {
- let dl = ptr::read_unaligned(p as *const libc::sockaddr_dl);
+ let dl = unsafe { ptr::read_unaligned(p as *const libc::sockaddr_dl) };
ControlMessageOwned::Ipv4RecvIf(dl)
},
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(bsd)]
#[cfg(feature = "net")]
(libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => {
- let dl = ptr::read_unaligned(p as *const libc::in_addr);
+ let dl = unsafe { ptr::read_unaligned(p as *const libc::in_addr) };
ControlMessageOwned::Ipv4RecvDstAddr(dl)
},
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+ #[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
(libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {
- let dl = ptr::read_unaligned(p as *const libc::sockaddr_in);
+ let dl = unsafe { ptr::read_unaligned(p as *const libc::sockaddr_in) };
ControlMessageOwned::Ipv4OrigDstAddr(dl)
},
#[cfg(target_os = "linux")]
#[cfg(feature = "net")]
(libc::SOL_UDP, libc::UDP_GRO) => {
- let gso_size: u16 = ptr::read_unaligned(p as *const _);
+ let gso_size: u16 = unsafe { ptr::read_unaligned(p as *const _) };
ControlMessageOwned::UdpGroSegments(gso_size)
},
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
(libc::SOL_SOCKET, libc::SO_RXQ_OVFL) => {
- let drop_counter = ptr::read_unaligned(p as *const u32);
+ let drop_counter = unsafe { ptr::read_unaligned(p as *const u32) };
ControlMessageOwned::RxqOvfl(drop_counter)
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[cfg(feature = "net")]
(libc::IPPROTO_IP, libc::IP_RECVERR) => {
- let (err, addr) = Self::recv_err_helper::<sockaddr_in>(p, len);
+ let (err, addr) = unsafe { Self::recv_err_helper::<sockaddr_in>(p, len) };
ControlMessageOwned::Ipv4RecvErr(err, addr)
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[cfg(feature = "net")]
(libc::IPPROTO_IPV6, libc::IPV6_RECVERR) => {
- let (err, addr) = Self::recv_err_helper::<sockaddr_in6>(p, len);
+ let (err, addr) = unsafe { Self::recv_err_helper::<sockaddr_in6>(p, len) };
ControlMessageOwned::Ipv6RecvErr(err, addr)
},
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+ #[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
(libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {
- let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6);
+ let dl = unsafe { ptr::read_unaligned(p as *const libc::sockaddr_in6) };
ControlMessageOwned::Ipv6OrigDstAddr(dl)
},
+ #[cfg(any(target_os = "linux"))]
+ (libc::SOL_TLS, libc::TLS_GET_RECORD_TYPE) => {
+ let content_type = unsafe { ptr::read_unaligned(p as *const u8) };
+ ControlMessageOwned::TlsGetRecordType(content_type.into())
+ },
(_, _) => {
- let sl = std::slice::from_raw_parts(p, len);
+ let sl = unsafe { std::slice::from_raw_parts(p, len) };
let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(sl));
ControlMessageOwned::Unknown(ucmsg)
}
}
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[cfg(feature = "net")]
#[allow(clippy::cast_ptr_alignment)] // False positive
unsafe fn recv_err_helper<T>(p: *mut libc::c_uchar, len: usize) -> (libc::sock_extended_err, Option<T>) {
let ee = p as *const libc::sock_extended_err;
- let err = ptr::read_unaligned(ee);
+ let err = unsafe { ptr::read_unaligned(ee) };
// For errors originating on the network, SO_EE_OFFENDER(ee) points inside the p[..len]
// CMSG_DATA buffer. For local errors, there is no address included in the control
// message, and SO_EE_OFFENDER(ee) points beyond the end of the buffer. So, we need to
// validate that the address object is in-bounds before we attempt to copy it.
- let addrp = libc::SO_EE_OFFENDER(ee) as *const T;
+ let addrp = unsafe { libc::SO_EE_OFFENDER(ee) as *const T };
- if addrp.offset(1) as usize - (p as usize) > len {
+ if unsafe { addrp.offset(1) } as usize - (p as usize) > len {
(err, None)
} else {
- (err, Some(ptr::read_unaligned(addrp)))
+ (err, Some(unsafe { ptr::read_unaligned(addrp) }))
}
}
}
-/// A type-safe zero-copy wrapper around a single control message, as used wih
-/// [`sendmsg`](#fn.sendmsg). More types may be added to this enum; do not
-/// exhaustively pattern-match it.
+/// A type-safe zero-copy wrapper around a single control message, as used with
+/// [`sendmsg`]. More types may be added to this enum; do not exhaustively
+/// pattern-match it.
///
/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html)
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -1074,8 +1039,7 @@ pub enum ControlMessage<'a> {
///
/// For further information, please refer to the
/// [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html) man page.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ScmCredentials(&'a UnixCredentials),
/// A message of type `SCM_CREDS`, containing the pid, uid, euid, gid and groups of
/// a process connected to the socket.
@@ -1089,41 +1053,28 @@ pub enum ControlMessage<'a> {
///
/// For further information, please refer to the
/// [`unix(4)`](https://www.freebsd.org/cgi/man.cgi?query=unix) man page.
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
ScmCreds,
/// Set IV for `AF_ALG` crypto API.
///
/// For further information, please refer to the
/// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AlgSetIv(&'a [u8]),
/// Set crypto operation for `AF_ALG` crypto API. It may be one of
/// `ALG_OP_ENCRYPT` or `ALG_OP_DECRYPT`
///
/// For further information, please refer to the
/// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AlgSetOp(&'a libc::c_int),
/// Set the length of associated authentication data (AAD) (applicable only to AEAD algorithms)
/// for `AF_ALG` crypto API.
///
/// For further information, please refer to the
/// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AlgSetAeadAssoclen(&'a u32),
/// UDP GSO makes it possible for applications to generate network packets
@@ -1139,51 +1090,52 @@ pub enum ControlMessage<'a> {
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
UdpGsoSegments(&'a u16),
- /// Configure the sending addressing and interface for v4
+ /// Configure the sending addressing and interface for v4.
///
/// For further information, please refer to the
/// [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html) man page.
- #[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "android",
- target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd", apple_targets))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4PacketInfo(&'a libc::in_pktinfo),
- /// Configure the sending addressing and interface for v6
+ /// Configure the sending addressing and interface for v6.
///
/// For further information, please refer to the
/// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page.
- #[cfg(any(target_os = "linux",
- target_os = "macos",
+ #[cfg(any(linux_android,
target_os = "netbsd",
target_os = "freebsd",
- target_os = "android",
- target_os = "ios",))]
+ apple_targets))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv6PacketInfo(&'a libc::in6_pktinfo),
/// Configure the IPv4 source address with `IP_SENDSRCADDR`.
- #[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- ))]
+ #[cfg(any(freebsdlike, netbsdlike))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Ipv4SendSrcAddr(&'a libc::in_addr),
+ /// Configure the hop limit for v6 multicast traffic.
+ ///
+ /// Set the IPv6 hop limit for this message. The argument is an integer
+ /// between 0 and 255. A value of -1 will set the hop limit to the route
+ /// default if possible on the interface. Without this cmsg, packets sent
+ /// with sendmsg have a hop limit of 1 and will not leave the local network.
+ /// For further information, please refer to the
+ /// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page.
+ #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))]
+ #[cfg(feature = "net")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ Ipv6HopLimit(&'a libc::c_int),
+
/// SO_RXQ_OVFL indicates that an unsigned 32 bit value
/// ancilliary msg (cmsg) should be attached to recieved
/// skbs indicating the number of packets dropped by the
/// socket between the last recieved packet and this
/// received packet.
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
RxqOvfl(&'a u32),
/// Configure the transmission time of packets.
@@ -1227,18 +1179,18 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmRights(fds) => {
fds as *const _ as *const u8
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::ScmCredentials(creds) => {
&creds.0 as *const libc::ucred as *const u8
}
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
ControlMessage::ScmCreds => {
// The kernel overwrites the data, we just zero it
// to make sure it's not uninitialized memory
unsafe { ptr::write_bytes(cmsg_data, 0, self.len()) };
return
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetIv(iv) => {
#[allow(deprecated)] // https://github.com/rust-lang/libc/issues/1501
let af_alg_iv = libc::af_alg_iv {
@@ -1263,11 +1215,11 @@ impl<'a> ControlMessage<'a> {
return
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetOp(op) => {
op as *const _ as *const u8
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetAeadAssoclen(len) => {
len as *const _ as *const u8
},
@@ -1276,21 +1228,20 @@ impl<'a> ControlMessage<'a> {
ControlMessage::UdpGsoSegments(gso_size) => {
gso_size as *const _ as *const u8
},
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd",
+ target_os = "freebsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8,
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
+ #[cfg(any(freebsdlike, netbsdlike))]
#[cfg(feature = "net")]
ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8,
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))]
+ #[cfg(feature = "net")]
+ ControlMessage::Ipv6HopLimit(limit) => limit as *const _ as *const u8,
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
ControlMessage::RxqOvfl(drop_count) => {
drop_count as *const _ as *const u8
},
@@ -1314,23 +1265,23 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmRights(fds) => {
mem::size_of_val(fds)
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::ScmCredentials(creds) => {
mem::size_of_val(creds)
}
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
ControlMessage::ScmCreds => {
mem::size_of::<libc::cmsgcred>()
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetIv(iv) => {
mem::size_of::<&[u8]>() + iv.len()
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetOp(op) => {
mem::size_of_val(op)
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetAeadAssoclen(len) => {
mem::size_of_val(len)
},
@@ -1339,21 +1290,22 @@ impl<'a> ControlMessage<'a> {
ControlMessage::UdpGsoSegments(gso_size) => {
mem::size_of_val(gso_size)
},
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info),
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd",
+ target_os = "freebsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info),
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
+ #[cfg(any(freebsdlike, netbsdlike))]
#[cfg(feature = "net")]
ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr),
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))]
+ #[cfg(feature = "net")]
+ ControlMessage::Ipv6HopLimit(limit) => {
+ mem::size_of_val(limit)
+ },
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
ControlMessage::RxqOvfl(drop_count) => {
mem::size_of_val(drop_count)
},
@@ -1368,31 +1320,30 @@ impl<'a> ControlMessage<'a> {
fn cmsg_level(&self) -> libc::c_int {
match *self {
ControlMessage::ScmRights(_) => libc::SOL_SOCKET,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
ControlMessage::ScmCreds => libc::SOL_SOCKET,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) |
ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG,
#[cfg(target_os = "linux")]
#[cfg(feature = "net")]
ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd",
+ target_os = "freebsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6,
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
+ #[cfg(any(freebsdlike, netbsdlike))]
#[cfg(feature = "net")]
ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP,
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))]
+ #[cfg(feature = "net")]
+ ControlMessage::Ipv6HopLimit(_) => libc::IPPROTO_IPV6,
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET,
#[cfg(target_os = "linux")]
ControlMessage::TxTime(_) => libc::SOL_SOCKET,
@@ -1403,19 +1354,19 @@ impl<'a> ControlMessage<'a> {
fn cmsg_type(&self) -> libc::c_int {
match *self {
ControlMessage::ScmRights(_) => libc::SCM_RIGHTS,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
ControlMessage::ScmCreds => libc::SCM_CREDS,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetIv(_) => {
libc::ALG_SET_IV
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetOp(_) => {
libc::ALG_SET_OP
},
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
ControlMessage::AlgSetAeadAssoclen(_) => {
libc::ALG_SET_AEAD_ASSOCLEN
},
@@ -1424,21 +1375,20 @@ impl<'a> ControlMessage<'a> {
ControlMessage::UdpGsoSegments(_) => {
libc::UDP_SEGMENT
},
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
+ #[cfg(any(linux_android, target_os = "netbsd",
+ target_os = "freebsd", apple_targets))]
#[cfg(feature = "net")]
ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO,
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
+ #[cfg(any(freebsdlike, netbsdlike))]
#[cfg(feature = "net")]
ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR,
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))]
+ #[cfg(feature = "net")]
+ ControlMessage::Ipv6HopLimit(_) => libc::IPV6_HOPLIMIT,
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
ControlMessage::RxqOvfl(_) => {
libc::SO_RXQ_OVFL
},
@@ -1452,10 +1402,12 @@ impl<'a> ControlMessage<'a> {
// Unsafe: cmsg must point to a valid cmsghdr with enough space to
// encode self.
unsafe fn encode_into(&self, cmsg: *mut cmsghdr) {
- (*cmsg).cmsg_level = self.cmsg_level();
- (*cmsg).cmsg_type = self.cmsg_type();
- (*cmsg).cmsg_len = self.cmsg_len();
- self.copy_to_cmsg_data(CMSG_DATA(cmsg));
+ unsafe {
+ (*cmsg).cmsg_level = self.cmsg_level();
+ (*cmsg).cmsg_type = self.cmsg_type();
+ (*cmsg).cmsg_len = self.cmsg_len();
+ self.copy_to_cmsg_data( CMSG_DATA(cmsg) );
+ }
}
}
@@ -1479,7 +1431,7 @@ impl<'a> ControlMessage<'a> {
/// let (r, w) = pipe().unwrap();
///
/// let iov = [IoSlice::new(b"hello")];
-/// let fds = [r];
+/// let fds = [r.as_raw_fd()];
/// let cmsg = ControlMessage::ScmRights(&fds);
/// sendmsg::<()>(fd1.as_raw_fd(), &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
/// ```
@@ -1496,7 +1448,7 @@ impl<'a> ControlMessage<'a> {
/// let (r, w) = pipe().unwrap();
///
/// let iov = [IoSlice::new(b"hello")];
-/// let fds = [r];
+/// let fds = [r.as_raw_fd()];
/// let cmsg = ControlMessage::ScmRights(&fds);
/// sendmsg(fd.as_raw_fd(), &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
/// ```
@@ -1535,12 +1487,7 @@ pub fn sendmsg<S>(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage],
///
/// # References
/// [`sendmsg`](fn.sendmsg.html)
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
pub fn sendmmsg<'a, XS, AS, C, I, S>(
fd: RawFd,
data: &'a mut MultiHeaders<S>,
@@ -1556,7 +1503,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
AS: AsRef<[Option<S>]>,
I: AsRef<[IoSlice<'a>]> + 'a,
C: AsRef<[ControlMessage<'a>]> + 'a,
- S: SockaddrLike + 'a
+ S: SockaddrLike + 'a,
{
let mut count = 0;
@@ -1564,11 +1511,11 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
for (i, ((slice, addr), mmsghdr)) in slices.into_iter().zip(addrs.as_ref()).zip(data.items.iter_mut() ).enumerate() {
let p = &mut mmsghdr.msg_hdr;
- p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec;
+ p.msg_iov = slice.as_ref().as_ptr().cast_mut().cast();
p.msg_iovlen = slice.as_ref().len() as _;
p.msg_namelen = addr.as_ref().map_or(0, S::len);
- p.msg_name = addr.as_ref().map_or(ptr::null(), S::as_ptr) as _;
+ p.msg_name = addr.as_ref().map_or(ptr::null(), S::as_ptr).cast_mut().cast();
// Encode each cmsg. This must happen after initializing the header because
// CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields.
@@ -1583,9 +1530,16 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
pmhdr = unsafe { CMSG_NXTHDR(p, pmhdr) };
}
- count = i+1;
+ // Doing an unchecked addition is alright here, as the only way to obtain an instance of `MultiHeaders`
+ // is through the `preallocate` function, which takes an `usize` as an argument to define its size,
+ // which also provides an upper bound for the size of this zipped iterator. Thus, `i < usize::MAX` or in
+ // other words: `count` doesn't overflow
+ count = i + 1;
}
+ // SAFETY: all pointers are guaranteed to be valid for the scope of this function. `count` does represent the
+ // maximum number of messages that can be sent safely (i.e. `count` is the minimum of the sizes of `slices`,
+ // `data.items` and `addrs`)
let sent = Errno::result(unsafe {
libc::sendmmsg(
fd,
@@ -1604,12 +1558,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
}
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
#[derive(Debug)]
/// Preallocated structures needed for [`recvmmsg`] and [`sendmmsg`] functions
pub struct MultiHeaders<S> {
@@ -1622,12 +1571,7 @@ pub struct MultiHeaders<S> {
msg_controllen: usize,
}
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
impl<S> MultiHeaders<S> {
/// Preallocate structure used by [`recvmmsg`] and [`sendmmsg`] takes number of headers to preallocate
///
@@ -1652,7 +1596,7 @@ impl<S> MultiHeaders<S> {
.enumerate()
.map(|(ix, address)| {
let (ptr, cap) = match &mut cmsg_buffers {
- Some(v) => ((&mut v[ix * msg_controllen] as *mut u8), msg_controllen),
+ Some(v) => (&mut v[ix * msg_controllen] as *mut u8, msg_controllen),
None => (std::ptr::null_mut(), 0),
};
let msg_hdr = unsafe { pack_mhdr_to_receive(std::ptr::null_mut(), 0, ptr, cap, address.as_mut_ptr()) };
@@ -1697,12 +1641,7 @@ impl<S> MultiHeaders<S> {
// always produce the desired results - see https://github.com/nix-rust/nix/pull/1744 for more
// details
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
pub fn recvmmsg<'a, XS, S, I>(
fd: RawFd,
data: &'a mut MultiHeaders<S>,
@@ -1711,14 +1650,19 @@ pub fn recvmmsg<'a, XS, S, I>(
mut timeout: Option<crate::sys::time::TimeSpec>,
) -> crate::Result<MultiResults<'a, S>>
where
- XS: IntoIterator<Item = &'a I>,
- I: AsRef<[IoSliceMut<'a>]> + 'a,
+ XS: IntoIterator<Item = &'a mut I>,
+ I: AsMut<[IoSliceMut<'a>]> + 'a,
{
let mut count = 0;
for (i, (slice, mmsghdr)) in slices.into_iter().zip(data.items.iter_mut()).enumerate() {
let p = &mut mmsghdr.msg_hdr;
- p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec;
- p.msg_iovlen = slice.as_ref().len() as _;
+ p.msg_iov = slice.as_mut().as_mut_ptr().cast();
+ p.msg_iovlen = slice.as_mut().len() as _;
+
+ // Doing an unchecked addition is alright here, as the only way to obtain an instance of `MultiHeaders`
+ // is through the `preallocate` function, which takes an `usize` as an argument to define its size,
+ // which also provides an upper bound for the size of this zipped iterator. Thus, `i < usize::MAX` or in
+ // other words: `count` doesn't overflow
count = i + 1;
}
@@ -1726,6 +1670,8 @@ where
.as_mut()
.map_or_else(std::ptr::null_mut, |t| t as *mut _ as *mut libc::timespec);
+ // SAFETY: all pointers are guaranteed to be valid for the scope of this function. `count` does represent the
+ // maximum number of messages that can be received safely (i.e. `count` is the minimum of the sizes of `slices` and `data.items`)
let received = Errno::result(unsafe {
libc::recvmmsg(
fd,
@@ -1743,16 +1689,9 @@ where
})
}
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-#[derive(Debug)]
/// Iterator over results of [`recvmmsg`]/[`sendmmsg`]
-///
-///
+#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
+#[derive(Debug)]
pub struct MultiResults<'a, S> {
// preallocated structures
rmm: &'a MultiHeaders<S>,
@@ -1760,12 +1699,7 @@ pub struct MultiResults<'a, S> {
received: usize,
}
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
impl<'a, S> Iterator for MultiResults<'a, S>
where
S: Copy + SockaddrLike,
@@ -1838,108 +1772,6 @@ impl<'a> Iterator for IoSliceIterator<'a> {
}
}
-// test contains both recvmmsg and timestaping which is linux only
-// there are existing tests for recvmmsg only in tests/
-#[cfg(target_os = "linux")]
-#[cfg(test)]
-mod test {
- use crate::sys::socket::{AddressFamily, ControlMessageOwned};
- use crate::*;
- use std::str::FromStr;
- use std::os::unix::io::AsRawFd;
-
- #[cfg_attr(qemu, ignore)]
- #[test]
- fn test_recvmm2() -> crate::Result<()> {
- use crate::sys::socket::{
- sendmsg, setsockopt, socket, sockopt::Timestamping, MsgFlags, SockFlag, SockType,
- SockaddrIn, TimestampingFlag,
- };
- use std::io::{IoSlice, IoSliceMut};
-
- let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap();
-
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )?;
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::SOCK_NONBLOCK,
- None,
- )?;
-
- crate::sys::socket::bind(rsock.as_raw_fd(), &sock_addr)?;
-
- setsockopt(&rsock, Timestamping, &TimestampingFlag::all())?;
-
- let sbuf = (0..400).map(|i| i as u8).collect::<Vec<_>>();
-
- let mut recv_buf = vec![0; 1024];
-
- let mut recv_iovs = Vec::new();
- let mut pkt_iovs = Vec::new();
-
- for (ix, chunk) in recv_buf.chunks_mut(256).enumerate() {
- pkt_iovs.push(IoSliceMut::new(chunk));
- if ix % 2 == 1 {
- recv_iovs.push(pkt_iovs);
- pkt_iovs = Vec::new();
- }
- }
- drop(pkt_iovs);
-
- let flags = MsgFlags::empty();
- let iov1 = [IoSlice::new(&sbuf)];
-
- let cmsg = cmsg_space!(crate::sys::socket::Timestamps);
- sendmsg(ssock.as_raw_fd(), &iov1, &[], flags, Some(&sock_addr)).unwrap();
-
- let mut data = super::MultiHeaders::<()>::preallocate(recv_iovs.len(), Some(cmsg));
-
- let t = sys::time::TimeSpec::from_duration(std::time::Duration::from_secs(10));
-
- let recv = super::recvmmsg(rsock.as_raw_fd(), &mut data, recv_iovs.iter(), flags, Some(t))?;
-
- for rmsg in recv {
- #[cfg(not(any(qemu, target_arch = "aarch64")))]
- let mut saw_time = false;
- let mut recvd = 0;
- for cmsg in rmsg.cmsgs() {
- if let ControlMessageOwned::ScmTimestampsns(timestamps) = cmsg {
- let ts = timestamps.system;
-
- let sys_time =
- crate::time::clock_gettime(crate::time::ClockId::CLOCK_REALTIME)?;
- let diff = if ts > sys_time {
- ts - sys_time
- } else {
- sys_time - ts
- };
- assert!(std::time::Duration::from(diff).as_secs() < 60);
- #[cfg(not(any(qemu, target_arch = "aarch64")))]
- {
- saw_time = true;
- }
- }
- }
-
- #[cfg(not(any(qemu, target_arch = "aarch64")))]
- assert!(saw_time);
-
- for iov in rmsg.iovs() {
- recvd += iov.len();
- }
- assert_eq!(recvd, 400);
- }
-
- Ok(())
- }
-}
unsafe fn read_mhdr<'a, 'i, S>(
mhdr: msghdr,
r: isize,
@@ -1951,19 +1783,23 @@ unsafe fn read_mhdr<'a, 'i, S>(
// The cast is not unnecessary on all platforms.
#[allow(clippy::unnecessary_cast)]
let cmsghdr = {
- if mhdr.msg_controllen > 0 {
+ let ptr = if mhdr.msg_controllen > 0 {
debug_assert!(!mhdr.msg_control.is_null());
debug_assert!(msg_controllen >= mhdr.msg_controllen as usize);
- CMSG_FIRSTHDR(&mhdr as *const msghdr)
+ unsafe { CMSG_FIRSTHDR(&mhdr as *const msghdr) }
} else {
ptr::null()
- }.as_ref()
+ };
+
+ unsafe {
+ ptr.as_ref()
+ }
};
// Ignore errors if this socket address has statically-known length
//
// This is to ensure that unix socket addresses have their length set appropriately.
- let _ = address.set_length(mhdr.msg_namelen as usize);
+ let _ = unsafe { address.set_length(mhdr.msg_namelen as usize) };
RecvMsg {
bytes: r as usize,
@@ -2000,14 +1836,16 @@ unsafe fn pack_mhdr_to_receive<S>(
// initialize it.
let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
let p = mhdr.as_mut_ptr();
- (*p).msg_name = address as *mut c_void;
- (*p).msg_namelen = S::size();
- (*p).msg_iov = iov_buffer as *mut iovec;
- (*p).msg_iovlen = iov_buffer_len as _;
- (*p).msg_control = cmsg_buffer as *mut c_void;
- (*p).msg_controllen = cmsg_capacity as _;
- (*p).msg_flags = 0;
- mhdr.assume_init()
+ unsafe {
+ (*p).msg_name = address as *mut c_void;
+ (*p).msg_namelen = S::size();
+ (*p).msg_iov = iov_buffer as *mut iovec;
+ (*p).msg_iovlen = iov_buffer_len as _;
+ (*p).msg_control = cmsg_buffer as *mut c_void;
+ (*p).msg_controllen = cmsg_capacity as _;
+ (*p).msg_flags = 0;
+ mhdr.assume_init()
+ }
}
fn pack_mhdr_to_send<'a, I, C, S>(
@@ -2025,7 +1863,7 @@ fn pack_mhdr_to_send<'a, I, C, S>(
// The message header must be initialized before the individual cmsgs.
let cmsg_ptr = if capacity > 0 {
- cmsg_buffer.as_mut_ptr() as *mut c_void
+ cmsg_buffer.as_mut_ptr().cast()
} else {
ptr::null_mut()
};
@@ -2035,11 +1873,11 @@ fn pack_mhdr_to_send<'a, I, C, S>(
// initialize it.
let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
let p = mhdr.as_mut_ptr();
- (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()) as *mut _;
+ (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()).cast_mut().cast();
(*p).msg_namelen = addr.map(S::len).unwrap_or(0);
// transmute iov into a mutable pointer. sendmsg doesn't really mutate
// the buffer, but the standard says that it takes a mutable pointer
- (*p).msg_iov = iov.as_ref().as_ptr() as *mut _;
+ (*p).msg_iov = iov.as_ref().as_ptr().cast_mut().cast();
(*p).msg_iovlen = iov.as_ref().len() as _;
(*p).msg_control = cmsg_ptr;
(*p).msg_controllen = capacity as _;
@@ -2166,17 +2004,51 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
Errno::result(res)?;
// Safe because socketpair returned success.
- unsafe {
- Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])))
+ unsafe { Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1]))) }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct Backlog(i32);
+
+impl Backlog {
+ /// Sets the listen queue size to system `SOMAXCONN` value
+ pub const MAXCONN: Self = Self(libc::SOMAXCONN);
+ /// Sets the listen queue size to -1 for system supporting it
+ #[cfg(any(target_os = "linux", target_os = "freebsd"))]
+ pub const MAXALLOWABLE: Self = Self(-1);
+
+ /// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid.
+ pub fn new<I: Into<i32>>(val: I) -> Result<Self> {
+ cfg_if! {
+ if #[cfg(any(target_os = "linux", target_os = "freebsd"))] {
+ const MIN: i32 = -1;
+ } else {
+ const MIN: i32 = 0;
+ }
+ }
+
+ let val = val.into();
+
+ if !(MIN..Self::MAXCONN.0).contains(&val) {
+ return Err(Errno::EINVAL);
+ }
+
+ Ok(Self(val))
+ }
+}
+
+impl From<Backlog> for i32 {
+ fn from(backlog: Backlog) -> Self {
+ backlog.0
}
}
/// Listen for connections on a socket
///
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
-pub fn listen<F: AsFd>(sock: &F, backlog: usize) -> Result<()> {
+pub fn listen<F: AsFd>(sock: &F, backlog: Backlog) -> Result<()> {
let fd = sock.as_fd().as_raw_fd();
- let res = unsafe { libc::listen(fd, backlog as c_int) };
+ let res = unsafe { libc::listen(fd, backlog.into()) };
Errno::result(res).map(drop)
}
@@ -2211,14 +2083,12 @@ pub fn accept(sockfd: RawFd) -> Result<RawFd> {
target_arch = "x86_64"
)
),
- target_os = "dragonfly",
+ freebsdlike,
+ netbsdlike,
target_os = "emscripten",
- target_os = "freebsd",
target_os = "fuchsia",
- target_os = "illumos",
+ solarish,
target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"
))]
pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> {
let res = unsafe {
@@ -2245,7 +2115,7 @@ pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
unsafe {
let ret = libc::recv(
sockfd,
- buf.as_mut_ptr() as *mut c_void,
+ buf.as_mut_ptr().cast(),
buf.len() as size_t,
flags.bits(),
);
@@ -2269,20 +2139,14 @@ pub fn recvfrom<T: SockaddrLike>(
let ret = Errno::result(libc::recvfrom(
sockfd,
- buf.as_mut_ptr() as *mut c_void,
+ buf.as_mut_ptr().cast(),
buf.len() as size_t,
0,
- addr.as_mut_ptr() as *mut sockaddr,
+ addr.as_mut_ptr().cast(),
&mut len as *mut socklen_t,
))? as usize;
- Ok((
- ret,
- T::from_raw(
- addr.assume_init().as_ptr(),
- Some(len),
- ),
- ))
+ Ok((ret, T::from_raw(addr.assume_init().as_ptr(), Some(len))))
}
}
@@ -2298,7 +2162,7 @@ pub fn sendto(
let ret = unsafe {
libc::sendto(
fd,
- buf.as_ptr() as *const c_void,
+ buf.as_ptr().cast(),
buf.len() as size_t,
flags.bits(),
addr.as_ptr(),
@@ -2314,12 +2178,7 @@ pub fn sendto(
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html)
pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
let ret = unsafe {
- libc::send(
- fd,
- buf.as_ptr() as *const c_void,
- buf.len() as size_t,
- flags.bits(),
- )
+ libc::send(fd, buf.as_ptr().cast(), buf.len() as size_t, flags.bits())
};
Errno::result(ret).map(|r| r as usize)
@@ -2386,8 +2245,7 @@ pub fn getpeername<T: SockaddrLike>(fd: RawFd) -> Result<T> {
let mut addr = mem::MaybeUninit::<T>::uninit();
let mut len = T::size();
- let ret =
- libc::getpeername(fd, addr.as_mut_ptr() as *mut sockaddr, &mut len);
+ let ret = libc::getpeername(fd, addr.as_mut_ptr().cast(), &mut len);
Errno::result(ret)?;
@@ -2403,8 +2261,7 @@ pub fn getsockname<T: SockaddrLike>(fd: RawFd) -> Result<T> {
let mut addr = mem::MaybeUninit::<T>::uninit();
let mut len = T::size();
- let ret =
- libc::getsockname(fd, addr.as_mut_ptr() as *mut sockaddr, &mut len);
+ let ret = libc::getsockname(fd, addr.as_mut_ptr().cast(), &mut len);
Errno::result(ret)?;
@@ -2439,27 +2296,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
}
}
-#[cfg(test)]
-mod tests {
- #[cfg(not(target_os = "redox"))]
- #[test]
- fn can_use_cmsg_space() {
- let _ = cmsg_space!(u8);
- }
-
- #[cfg(not(any(
- target_os = "redox",
- target_os = "linux",
- target_os = "android"
- )))]
- #[test]
- fn can_open_routing_socket() {
- let _ = super::socket(
- super::AddressFamily::Route,
- super::SockType::Raw,
- super::SockFlag::empty(),
- None,
- )
- .expect("Failed to open routing socket");
- }
-}
diff --git a/third_party/rust/nix/src/sys/socket/sockopt.rs b/third_party/rust/nix/src/sys/socket/sockopt.rs
index 44f3ebbc1d..4357695f56 100644
--- a/third_party/rust/nix/src/sys/socket/sockopt.rs
+++ b/third_party/rust/nix/src/sys/socket/sockopt.rs
@@ -7,7 +7,6 @@ use cfg_if::cfg_if;
use libc::{self, c_int, c_void, socklen_t};
use std::ffi::{OsStr, OsString};
use std::mem::{self, MaybeUninit};
-#[cfg(target_family = "unix")]
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsFd, AsRawFd};
@@ -128,7 +127,7 @@ macro_rules! getsockopt_impl {
/// both of them.
/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for.
/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets*
-/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
+/// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
/// and more. Please refer to your system manual for more options. Will be passed as the second
/// argument (`level`) to the `getsockopt`/`setsockopt` call.
/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
@@ -261,7 +260,7 @@ sockopt_impl!(
libc::SO_REUSEADDR,
bool
);
-#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
+#[cfg(not(solarish))]
sockopt_impl!(
/// Permits multiple AF_INET or AF_INET6 sockets to be bound to an
/// identical socket address.
@@ -318,7 +317,7 @@ sockopt_impl!(
super::IpMembershipRequest
);
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(linux_android)] {
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -329,14 +328,7 @@ cfg_if! {
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
/// Leave an IPv6 multicast group.
Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest);
- } else if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))] {
+ } else if #[cfg(any(bsd, solarish))] {
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -365,6 +357,17 @@ sockopt_impl!(
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// Set or read the hop limit value of outgoing IPv6 multicast packets for
+ /// this socket.
+ Ipv6MulticastHops,
+ Both,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_MULTICAST_HOPS,
+ libc::c_int
+);
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
/// Set or read a boolean integer argument that determines whether sent
/// multicast packets should be looped back to the local sockets.
IpMulticastLoop,
@@ -408,7 +411,7 @@ sockopt_impl!(
libc::IPV6_TCLASS,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -420,6 +423,20 @@ sockopt_impl!(
libc::IP_FREEBIND,
bool
);
+#[cfg(linux_android)]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// If enabled, the kernel will not reserve an ephemeral port when binding
+ /// socket with a port number of 0. The port will later be automatically
+ /// chosen at connect time, in a way that allows sharing a source port as
+ /// long as the 4-tuple is unique.
+ IpBindAddressNoPort,
+ Both,
+ libc::IPPROTO_IP,
+ libc::IP_BIND_ADDRESS_NO_PORT,
+ bool
+);
sockopt_impl!(
/// Specify the receiving timeout until reporting an error.
ReceiveTimeout,
@@ -477,12 +494,7 @@ sockopt_impl!(
libc::SO_KEEPALIVE,
bool
);
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
-))]
+#[cfg(any(freebsdlike, apple_targets))]
sockopt_impl!(
/// Get the credentials of the peer process of a connected unix domain
/// socket.
@@ -492,7 +504,7 @@ sockopt_impl!(
libc::LOCAL_PEERCRED,
super::XuCred
);
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(apple_targets)]
sockopt_impl!(
/// Get the PID of the peer process of a connected unix domain socket.
LocalPeerPid,
@@ -501,7 +513,7 @@ sockopt_impl!(
libc::LOCAL_PEERPID,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Return the credentials of the foreign process connected to this socket.
PeerCredentials,
@@ -510,7 +522,18 @@ sockopt_impl!(
libc::SO_PEERCRED,
super::UnixCredentials
);
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(target_os = "freebsd")]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// Get backlog limit of the socket
+ ListenQLimit,
+ GetOnly,
+ libc::SOL_SOCKET,
+ libc::SO_LISTENQLIMIT,
+ u32
+);
+#[cfg(apple_targets)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -522,12 +545,7 @@ sockopt_impl!(
libc::TCP_KEEPALIVE,
u32
);
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
-))]
+#[cfg(any(freebsdlike, linux_android))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -540,7 +558,7 @@ sockopt_impl!(
u32
);
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(linux_android)] {
sockopt_impl!(
/// The maximum segment size for outgoing TCP packets.
TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
@@ -550,7 +568,11 @@ cfg_if! {
TcpMaxSeg, GetOnly, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
}
}
-#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(
+ target_os = "openbsd",
+ target_os = "haiku",
+ target_os = "redox"
+)))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -562,7 +584,7 @@ sockopt_impl!(
libc::TCP_KEEPCNT,
u32
);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
@@ -572,7 +594,11 @@ sockopt_impl!(
libc::TCP_REPAIR,
u32
);
-#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(
+ target_os = "openbsd",
+ target_os = "haiku",
+ target_os = "redox"
+)))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -596,6 +622,26 @@ sockopt_impl!(
libc::TCP_USER_TIMEOUT,
u32
);
+#[cfg(linux_android)]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// Enables TCP Fast Open (RFC 7413) on a connecting socket. If a fast open
+ /// cookie is not available (first attempt to connect), `connect` syscall
+ /// will behave as usual, except for internally trying to solicit a cookie
+ /// from remote peer. When cookie is available, the next `connect` syscall
+ /// will immediately succeed without actually establishing TCP connection.
+ /// The connection establishment will be defered till the next `write` or
+ /// `sendmsg` syscalls on the socket, allowing TCP prtocol to establish
+ /// connection and send data in the same packets. Note: calling `read` right
+ /// after `connect` without `write` on the socket will cause the blocking
+ /// socket to be blocked forever.
+ TcpFastOpenConnect,
+ Both,
+ libc::IPPROTO_TCP,
+ libc::TCP_FASTOPEN_CONNECT,
+ bool
+);
sockopt_impl!(
/// Sets or gets the maximum socket receive buffer in bytes.
RcvBuf,
@@ -612,7 +658,7 @@ sockopt_impl!(
libc::SO_SNDBUF,
usize
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
/// perform the same task as `SO_RCVBUF`, but the `rmem_max limit` can be
@@ -623,7 +669,7 @@ sockopt_impl!(
libc::SO_RCVBUFFORCE,
usize
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
/// perform the same task as `SO_SNDBUF`, but the `wmem_max` limit can be
@@ -652,7 +698,7 @@ sockopt_impl!(
libc::SO_ACCEPTCONN,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Bind this socket to a particular device like “eth0”.
BindToDevice,
@@ -661,7 +707,7 @@ sockopt_impl!(
libc::SO_BINDTODEVICE,
OsString<[u8; libc::IFNAMSIZ]>
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -673,7 +719,7 @@ sockopt_impl!(
libc::SO_ORIGINAL_DST,
libc::sockaddr_in
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
@@ -683,7 +729,7 @@ sockopt_impl!(
libc::IP6T_SO_ORIGINAL_DST,
libc::sockaddr_in6
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Specifies exact type of timestamping information collected by the kernel
/// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
@@ -693,7 +739,7 @@ sockopt_impl!(
libc::SO_TIMESTAMPING,
super::TimestampingFlag
);
-#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "hurd", target_os = "redox")))]
sockopt_impl!(
/// Enable or disable the receiving of the `SO_TIMESTAMP` control message.
ReceiveTimestamp,
@@ -702,7 +748,7 @@ sockopt_impl!(
libc::SO_TIMESTAMP,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Enable or disable the receiving of the `SO_TIMESTAMPNS` control message.
ReceiveTimestampns,
@@ -719,9 +765,9 @@ sockopt_impl!(
Both,
libc::SOL_SOCKET,
libc::SO_TS_CLOCK,
- i32
+ super::SocketTimestamp
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -806,7 +852,7 @@ sockopt_impl!(
libc::SO_MARK,
u32
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Enable or disable the receiving of the `SCM_CREDENTIALS` control
/// message.
@@ -828,13 +874,7 @@ sockopt_impl!(
libc::TCP_CONGESTION,
OsString<[u8; TCP_CA_NAME_MAX]>
);
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
-))]
+#[cfg(any(linux_android, apple_targets, target_os = "netbsd"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -846,15 +886,7 @@ sockopt_impl!(
libc::IP_PKTINFO,
bool
);
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", apple_targets, netbsdlike))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -866,13 +898,7 @@ sockopt_impl!(
libc::IPV6_RECVPKTINFO,
bool
);
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(bsd)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -884,13 +910,7 @@ sockopt_impl!(
libc::IP_RECVIF,
bool
);
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(bsd)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -902,7 +922,7 @@ sockopt_impl!(
libc::IP_RECVDSTADDR,
bool
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -948,7 +968,7 @@ sockopt_impl!(
libc::SO_TXTIME,
libc::sock_txtime
);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
sockopt_impl!(
/// Indicates that an unsigned 32-bit value ancillary message (cmsg) should
/// be attached to received skbs indicating the number of packets dropped by
@@ -969,7 +989,7 @@ sockopt_impl!(
libc::IPV6_V6ONLY,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Enable extended reliable error message passing.
Ipv4RecvErr,
@@ -978,7 +998,7 @@ sockopt_impl!(
libc::IP_RECVERR,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Control receiving of asynchronous error options.
Ipv6RecvErr,
@@ -987,7 +1007,7 @@ sockopt_impl!(
libc::IPV6_RECVERR,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Fetch the current system-estimated Path MTU.
IpMtu,
@@ -996,7 +1016,7 @@ sockopt_impl!(
libc::IP_MTU,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
sockopt_impl!(
/// Set or retrieve the current time-to-live field that is used in every
/// packet sent from this socket.
@@ -1006,7 +1026,7 @@ sockopt_impl!(
libc::IP_TTL,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
sockopt_impl!(
/// Set the unicast hop limit for the socket.
Ipv6Ttl,
@@ -1015,7 +1035,7 @@ sockopt_impl!(
libc::IPV6_UNICAST_HOPS,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -1027,7 +1047,7 @@ sockopt_impl!(
libc::IPV6_ORIGDSTADDR,
bool
);
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(apple_targets)]
sockopt_impl!(
/// Set "don't fragment packet" flag on the IP packet.
IpDontFrag,
@@ -1036,12 +1056,7 @@ sockopt_impl!(
libc::IP_DONTFRAG,
bool
);
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
-))]
+#[cfg(any(linux_android, apple_targets))]
sockopt_impl!(
/// Set "don't fragment packet" flag on the IPv6 packet.
Ipv6DontFrag,
@@ -1053,13 +1068,13 @@ sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[derive(Copy, Clone, Debug)]
pub struct AlgSetAeadAuthSize;
// ALG_SET_AEAD_AUTH_SIZE read the length from passed `option_len`
// See https://elixir.bootlin.com/linux/v4.4/source/crypto/af_alg.c#L222
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
impl SetSockOpt for AlgSetAeadAuthSize {
type Val = usize;
@@ -1079,18 +1094,18 @@ impl SetSockOpt for AlgSetAeadAuthSize {
#[allow(missing_docs)]
// Not documented by Linux!
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[derive(Clone, Debug)]
pub struct AlgSetKey<T>(::std::marker::PhantomData<T>);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
impl<T> Default for AlgSetKey<T> {
fn default() -> Self {
AlgSetKey(Default::default())
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
impl<T> SetSockOpt for AlgSetKey<T>
where
T: AsRef<[u8]> + Clone,
@@ -1103,7 +1118,54 @@ where
fd.as_fd().as_raw_fd(),
libc::SOL_ALG,
libc::ALG_SET_KEY,
- val.as_ref().as_ptr() as *const _,
+ val.as_ref().as_ptr().cast(),
+ val.as_ref().len() as libc::socklen_t,
+ );
+ Errno::result(res).map(drop)
+ }
+ }
+}
+
+/// Set the Upper Layer Protocol (ULP) on the TCP socket.
+///
+/// For example, to enable the TLS ULP on a socket, the C function call would be:
+///
+/// ```c
+/// setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
+/// ```
+///
+/// ... and the `nix` equivalent is:
+///
+/// ```ignore,rust
+/// setsockopt(sock, TcpUlp::default(), b"tls");
+/// ```
+///
+/// Note that the ULP name does not need a trailing NUL terminator (`\0`).
+#[cfg(linux_android)]
+#[derive(Clone, Debug)]
+pub struct TcpUlp<T>(::std::marker::PhantomData<T>);
+
+#[cfg(linux_android)]
+impl<T> Default for TcpUlp<T> {
+ fn default() -> Self {
+ TcpUlp(Default::default())
+ }
+}
+
+#[cfg(linux_android)]
+impl<T> SetSockOpt for TcpUlp<T>
+where
+ T: AsRef<[u8]> + Clone,
+{
+ type Val = T;
+
+ fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
+ unsafe {
+ let res = libc::setsockopt(
+ fd.as_fd().as_raw_fd(),
+ libc::SOL_TCP,
+ libc::TCP_ULP,
+ val.as_ref().as_ptr().cast(),
val.as_ref().len() as libc::socklen_t,
);
Errno::result(res).map(drop)
@@ -1111,6 +1173,113 @@ where
}
}
+/// Value used with the [`TcpTlsTx`] and [`TcpTlsRx`] socket options.
+#[cfg(target_os = "linux")]
+#[derive(Copy, Clone, Debug)]
+pub enum TlsCryptoInfo {
+ /// AES-128-GCM
+ Aes128Gcm(libc::tls12_crypto_info_aes_gcm_128),
+
+ /// AES-256-GCM
+ Aes256Gcm(libc::tls12_crypto_info_aes_gcm_256),
+
+ /// CHACHA20-POLY1305
+ Chacha20Poly1305(libc::tls12_crypto_info_chacha20_poly1305),
+}
+
+/// Set the Kernel TLS write parameters on the TCP socket.
+///
+/// For example, the C function call would be:
+///
+/// ```c
+/// setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
+/// ```
+///
+/// ... and the `nix` equivalent is:
+///
+/// ```ignore,rust
+/// setsockopt(sock, TcpTlsTx, &crypto_info);
+/// ```
+#[cfg(target_os = "linux")]
+#[derive(Copy, Clone, Debug)]
+pub struct TcpTlsTx;
+
+#[cfg(target_os = "linux")]
+impl SetSockOpt for TcpTlsTx {
+ type Val = TlsCryptoInfo;
+
+ fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
+ let (ffi_ptr, ffi_len) = match val {
+ TlsCryptoInfo::Aes128Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Aes256Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Chacha20Poly1305(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ };
+ unsafe {
+ let res = libc::setsockopt(
+ fd.as_fd().as_raw_fd(),
+ libc::SOL_TLS,
+ libc::TLS_TX,
+ ffi_ptr,
+ ffi_len as libc::socklen_t,
+ );
+ Errno::result(res).map(drop)
+ }
+ }
+}
+
+/// Set the Kernel TLS read parameters on the TCP socket.
+///
+/// For example, the C function call would be:
+///
+/// ```c
+/// setsockopt(sock, SOL_TLS, TLS_RX, &crypto_info, sizeof(crypto_info));
+/// ```
+///
+/// ... and the `nix` equivalent is:
+///
+/// ```ignore,rust
+/// setsockopt(sock, TcpTlsRx, &crypto_info);
+/// ```
+#[cfg(target_os = "linux")]
+#[derive(Copy, Clone, Debug)]
+pub struct TcpTlsRx;
+
+#[cfg(target_os = "linux")]
+impl SetSockOpt for TcpTlsRx {
+ type Val = TlsCryptoInfo;
+
+ fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
+ let (ffi_ptr, ffi_len) = match val {
+ TlsCryptoInfo::Aes128Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Aes256Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Chacha20Poly1305(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ };
+ unsafe {
+ let res = libc::setsockopt(
+ fd.as_fd().as_raw_fd(),
+ libc::SOL_TLS,
+ libc::TLS_RX,
+ ffi_ptr,
+ ffi_len as libc::socklen_t,
+ );
+ Errno::result(res).map(drop)
+ }
+ }
+}
+
+
/*
*
* ===== Accessor helpers =====
@@ -1158,7 +1327,7 @@ impl<T> Get<T> for GetStruct<T> {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1171,7 +1340,7 @@ impl<T> Get<T> for GetStruct<T> {
mem::size_of::<T>(),
"invalid getsockopt implementation"
);
- self.val.assume_init()
+ unsafe { self.val.assume_init() }
}
}
@@ -1209,7 +1378,7 @@ impl Get<bool> for GetBool {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1222,7 +1391,7 @@ impl Get<bool> for GetBool {
mem::size_of::<c_int>(),
"invalid getsockopt implementation"
);
- self.val.assume_init() != 0
+ unsafe { self.val.assume_init() != 0 }
}
}
@@ -1243,7 +1412,7 @@ impl<'a> Set<'a, bool> for SetBool {
}
fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
+ mem::size_of_val(&self.val) as socklen_t
}
}
@@ -1262,7 +1431,7 @@ impl Get<u8> for GetU8 {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1275,7 +1444,7 @@ impl Get<u8> for GetU8 {
mem::size_of::<u8>(),
"invalid getsockopt implementation"
);
- self.val.assume_init()
+ unsafe { self.val.assume_init() }
}
}
@@ -1294,7 +1463,7 @@ impl<'a> Set<'a, u8> for SetU8 {
}
fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
+ mem::size_of_val(&self.val) as socklen_t
}
}
@@ -1313,7 +1482,7 @@ impl Get<usize> for GetUsize {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1326,7 +1495,7 @@ impl Get<usize> for GetUsize {
mem::size_of::<c_int>(),
"invalid getsockopt implementation"
);
- self.val.assume_init() as usize
+ unsafe { self.val.assume_init() as usize }
}
}
@@ -1345,7 +1514,7 @@ impl<'a> Set<'a, usize> for SetUsize {
}
fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
+ mem::size_of_val(&self.val) as socklen_t
}
}
@@ -1364,7 +1533,7 @@ impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1373,7 +1542,7 @@ impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
unsafe fn assume_init(self) -> OsString {
let len = self.len as usize;
- let mut v = self.val.assume_init();
+ let mut v = unsafe { self.val.assume_init() };
OsStr::from_bytes(&v.as_mut()[0..len]).to_owned()
}
}
@@ -1391,7 +1560,7 @@ impl<'a> Set<'a, OsString> for SetOsString<'a> {
}
fn ffi_ptr(&self) -> *const c_void {
- self.val.as_bytes().as_ptr() as *const c_void
+ self.val.as_bytes().as_ptr().cast()
}
fn ffi_len(&self) -> socklen_t {
@@ -1399,72 +1568,3 @@ impl<'a> Set<'a, OsString> for SetOsString<'a> {
}
}
-#[cfg(test)]
-mod test {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[test]
- fn can_get_peercred_on_unix_socket() {
- use super::super::*;
-
- let (a, b) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let a_cred = getsockopt(&a, super::PeerCredentials).unwrap();
- let b_cred = getsockopt(&b, super::PeerCredentials).unwrap();
- assert_eq!(a_cred, b_cred);
- assert_ne!(a_cred.pid(), 0);
- }
-
- #[test]
- fn is_socket_type_unix() {
- use super::super::*;
-
- let (a, _b) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let a_type = getsockopt(&a, super::SockType).unwrap();
- assert_eq!(a_type, SockType::Stream);
- }
-
- #[test]
- fn is_socket_type_dgram() {
- use super::super::*;
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let s_type = getsockopt(&s, super::SockType).unwrap();
- assert_eq!(s_type, SockType::Datagram);
- }
-
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- #[test]
- fn can_get_listen_on_tcp_socket() {
- use super::super::*;
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let s_listening = getsockopt(&s, super::AcceptConn).unwrap();
- assert!(!s_listening);
- listen(&s, 10).unwrap();
- let s_listening2 = getsockopt(&s, super::AcceptConn).unwrap();
- assert!(s_listening2);
- }
-}
diff --git a/third_party/rust/nix/src/sys/stat.rs b/third_party/rust/nix/src/sys/stat.rs
index 7e51c03a3f..c5854eec01 100644
--- a/third_party/rust/nix/src/sys/stat.rs
+++ b/third_party/rust/nix/src/sys/stat.rs
@@ -1,10 +1,6 @@
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))]
+#[cfg(any(apple_targets, target_os = "openbsd"))]
pub use libc::c_uint;
-#[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
+#[cfg(any(target_os = "netbsd", freebsdlike))]
pub use libc::c_ulong;
pub use libc::stat as FileStat;
pub use libc::{dev_t, mode_t};
@@ -43,7 +39,7 @@ libc_bitflags! {
S_IXUSR;
/// Read write and execute for group.
S_IRWXG;
- /// Read fr group.
+ /// Read for group.
S_IRGRP;
/// Write for group.
S_IWGRP;
@@ -65,26 +61,14 @@ libc_bitflags! {
}
}
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))]
+#[cfg(any(apple_targets, target_os = "openbsd"))]
pub type type_of_file_flag = c_uint;
-#[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
+#[cfg(any(freebsdlike, target_os = "netbsd"))]
pub type type_of_file_flag = c_ulong;
-#[cfg(any(
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "macos",
- target_os = "ios"
-))]
+#[cfg(bsd)]
libc_bitflags! {
/// File flags.
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub struct FileFlag: type_of_file_flag {
/// The file may only be appended to.
SF_APPEND;
@@ -101,7 +85,7 @@ libc_bitflags! {
#[cfg(any(target_os = "dragonfly"))]
SF_NOHISTORY;
/// The file may not be renamed or deleted.
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
SF_NOUNLINK;
/// Mask of superuser changeable flags
SF_SETTABLE;
@@ -121,14 +105,13 @@ libc_bitflags! {
#[cfg(any(target_os = "dragonfly"))]
UF_CACHE;
/// File is compressed at the file system level.
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
UF_COMPRESSED;
/// The file may be hidden from directory listings at the application's
/// discretion.
#[cfg(any(
target_os = "freebsd",
- target_os = "macos",
- target_os = "ios",
+ apple_targets,
))]
UF_HIDDEN;
/// The file may not be changed.
@@ -138,7 +121,7 @@ libc_bitflags! {
#[cfg(any(target_os = "dragonfly"))]
UF_NOHISTORY;
/// The file may not be renamed or deleted.
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+ #[cfg(freebsdlike)]
UF_NOUNLINK;
/// The file is offline, or has the Windows and CIFS
/// `FILE_ATTRIBUTE_OFFLINE` attribute.
@@ -162,7 +145,7 @@ libc_bitflags! {
#[cfg(any(target_os = "freebsd"))]
UF_SYSTEM;
/// File renames and deletes are tracked.
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
UF_TRACKED;
#[cfg(any(target_os = "dragonfly"))]
UF_XLINK;
@@ -184,20 +167,15 @@ pub fn mknod<P: ?Sized + NixPath>(
}
/// Create a special or ordinary file, relative to a given directory.
-#[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "redox",
- target_os = "haiku"
-)))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(not(any(apple_targets, target_os = "redox", target_os = "haiku")))]
pub fn mknodat<P: ?Sized + NixPath>(
- dirfd: RawFd,
+ dirfd: Option<RawFd>,
path: &P,
kind: SFlag,
perm: Mode,
dev: dev_t,
) -> Result<()> {
+ let dirfd = at_rawfd(dirfd);
let res = path.with_nix_path(|cstr| unsafe {
libc::mknodat(
dirfd,
@@ -211,19 +189,16 @@ pub fn mknodat<P: ?Sized + NixPath>(
}
#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub const fn major(dev: dev_t) -> u64 {
((dev >> 32) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)
}
#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub const fn minor(dev: dev_t) -> u64 {
((dev >> 12) & 0xffff_ff00) | ((dev) & 0x0000_00ff)
}
#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub const fn makedev(major: u64, minor: u64) -> dev_t {
((major & 0xffff_f000) << 32)
| ((major & 0x0000_0fff) << 8)
@@ -268,12 +243,12 @@ pub fn fstat(fd: RawFd) -> Result<FileStat> {
}
#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn fstatat<P: ?Sized + NixPath>(
- dirfd: RawFd,
+ dirfd: Option<RawFd>,
pathname: &P,
f: AtFlags,
) -> Result<FileStat> {
+ let dirfd = at_rawfd(dirfd);
let mut dst = mem::MaybeUninit::uninit();
let res = pathname.with_nix_path(|cstr| unsafe {
libc::fstatat(
@@ -324,7 +299,6 @@ pub enum FchmodatFlags {
///
/// [fchmodat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html).
#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn fchmodat<P: ?Sized + NixPath>(
dirfd: Option<RawFd>,
path: &P,
@@ -383,12 +357,10 @@ pub fn utimes<P: ?Sized + NixPath>(
#[cfg(any(
target_os = "linux",
target_os = "haiku",
- target_os = "ios",
- target_os = "macos",
+ apple_targets,
target_os = "freebsd",
target_os = "netbsd"
))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn lutimes<P: ?Sized + NixPath>(
path: &P,
atime: &TimeVal,
@@ -404,6 +376,9 @@ pub fn lutimes<P: ?Sized + NixPath>(
/// Change the access and modification times of the file specified by a file descriptor.
///
+/// If you want to set the timestamp to now, use `TimeSpec::UTIME_NOW`. Use
+/// `TimeSpec::UTIME_OMIT` if you don't want to change it.
+///
/// # References
///
/// [futimens(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html).
@@ -436,11 +411,13 @@ pub enum UtimensatFlags {
/// `utimes(path, times)`. The latter is a deprecated API so prefer using the
/// former if the platforms you care about support it.
///
+/// If you want to set the timestamp to now, use `TimeSpec::UTIME_NOW`. Use
+/// `TimeSpec::UTIME_OMIT` if you don't want to change it.
+///
/// # References
///
/// [utimensat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html).
#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn utimensat<P: ?Sized + NixPath>(
dirfd: Option<RawFd>,
path: &P,
@@ -466,12 +443,12 @@ pub fn utimensat<P: ?Sized + NixPath>(
}
#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn mkdirat<P: ?Sized + NixPath>(
- fd: RawFd,
+ fd: Option<RawFd>,
path: &P,
mode: Mode,
) -> Result<()> {
+ let fd = at_rawfd(fd);
let res = path.with_nix_path(|cstr| unsafe {
libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t)
})?;
diff --git a/third_party/rust/nix/src/sys/statfs.rs b/third_party/rust/nix/src/sys/statfs.rs
index 5111df2e6e..b2315f4ceb 100644
--- a/third_party/rust/nix/src/sys/statfs.rs
+++ b/third_party/rust/nix/src/sys/statfs.rs
@@ -1,7 +1,7 @@
//! Get filesystem statistics, non-portably
//!
//! See [`statvfs`](crate::sys::statvfs) for a portable alternative.
-#[cfg(not(any(target_os = "linux", target_os = "android")))]
+#[cfg(not(linux_android))]
use std::ffi::CStr;
use std::fmt::{self, Debug};
use std::mem;
@@ -9,16 +9,7 @@ use std::os::unix::io::{AsFd, AsRawFd};
use cfg_if::cfg_if;
-#[cfg(all(
- feature = "mount",
- any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )
-))]
+#[cfg(all(feature = "mount", bsd))]
use crate::mount::MntFlags;
#[cfg(target_os = "linux")]
use crate::sys::statvfs::FsFlags;
@@ -26,15 +17,13 @@ use crate::{errno::Errno, NixPath, Result};
/// Identifies a mounted file system
#[cfg(target_os = "android")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub type fsid_t = libc::__fsid_t;
/// Identifies a mounted file system
#[cfg(not(target_os = "android"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub type fsid_t = libc::fsid_t;
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] {
+ if #[cfg(any(linux_android, target_os = "fuchsia"))] {
type type_of_statfs = libc::statfs64;
const LIBC_FSTATFS: unsafe extern fn
(fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
@@ -62,10 +51,12 @@ pub struct Statfs(type_of_statfs);
type fs_type_t = u32;
#[cfg(target_os = "android")]
type fs_type_t = libc::c_ulong;
-#[cfg(all(target_os = "linux", target_arch = "s390x"))]
+#[cfg(all(target_os = "linux", target_arch = "s390x", not(target_env = "musl")))]
type fs_type_t = libc::c_uint;
#[cfg(all(target_os = "linux", target_env = "musl"))]
type fs_type_t = libc::c_ulong;
+#[cfg(all(target_os = "linux", target_env = "ohos"))]
+type fs_type_t = libc::c_ulong;
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
type fs_type_t = libc::c_int;
#[cfg(all(
@@ -73,6 +64,7 @@ type fs_type_t = libc::c_int;
not(any(
target_arch = "s390x",
target_env = "musl",
+ target_env = "ohos",
target_env = "uclibc"
))
))]
@@ -84,6 +76,7 @@ type fs_type_t = libc::__fsword_t;
target_os = "android",
all(target_os = "linux", target_arch = "s390x"),
all(target_os = "linux", target_env = "musl"),
+ all(target_os = "linux", target_env = "ohos"),
all(
target_os = "linux",
not(any(target_arch = "s390x", target_env = "musl"))
@@ -94,206 +87,203 @@ pub struct FsType(pub fs_type_t);
// These constants are defined without documentation in the Linux headers, so we
// can't very well document them here.
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const ADFS_SUPER_MAGIC: FsType =
FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const AFFS_SUPER_MAGIC: FsType =
FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const AFS_SUPER_MAGIC: FsType = FsType(libc::AFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const AUTOFS_SUPER_MAGIC: FsType =
FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const BPF_FS_MAGIC: FsType = FsType(libc::BPF_FS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const BTRFS_SUPER_MAGIC: FsType =
FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const CGROUP2_SUPER_MAGIC: FsType =
FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const CGROUP_SUPER_MAGIC: FsType =
FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const CODA_SUPER_MAGIC: FsType =
FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const DEBUGFS_MAGIC: FsType = FsType(libc::DEBUGFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const DEVPTS_SUPER_MAGIC: FsType =
FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const ECRYPTFS_SUPER_MAGIC: FsType =
FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const EXT2_SUPER_MAGIC: FsType =
FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const EXT3_SUPER_MAGIC: FsType =
FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const EXT4_SUPER_MAGIC: FsType =
FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const F2FS_SUPER_MAGIC: FsType =
FsType(libc::F2FS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const FUSE_SUPER_MAGIC: FsType =
FsType(libc::FUSE_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const FUTEXFS_SUPER_MAGIC: FsType =
FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const HOSTFS_SUPER_MAGIC: FsType =
FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const HPFS_SUPER_MAGIC: FsType =
FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const ISOFS_SUPER_MAGIC: FsType =
FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const JFFS2_SUPER_MAGIC: FsType =
FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const MINIX2_SUPER_MAGIC2: FsType =
FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const MINIX2_SUPER_MAGIC: FsType =
FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const MINIX3_SUPER_MAGIC: FsType =
FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const MINIX_SUPER_MAGIC2: FsType =
FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const MINIX_SUPER_MAGIC: FsType =
FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const MSDOS_SUPER_MAGIC: FsType =
FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const NILFS_SUPER_MAGIC: FsType =
FsType(libc::NILFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const OCFS2_SUPER_MAGIC: FsType =
FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const OPENPROM_SUPER_MAGIC: FsType =
FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const OVERLAYFS_SUPER_MAGIC: FsType =
FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const PROC_SUPER_MAGIC: FsType =
FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const QNX4_SUPER_MAGIC: FsType =
FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const QNX6_SUPER_MAGIC: FsType =
FsType(libc::QNX6_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const RDTGROUP_SUPER_MAGIC: FsType =
FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const REISERFS_SUPER_MAGIC: FsType =
FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const SECURITYFS_MAGIC: FsType =
FsType(libc::SECURITYFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const SELINUX_MAGIC: FsType = FsType(libc::SELINUX_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const SMACK_MAGIC: FsType = FsType(libc::SMACK_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const SYSFS_MAGIC: FsType = FsType(libc::SYSFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const TRACEFS_MAGIC: FsType = FsType(libc::TRACEFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const UDF_SUPER_MAGIC: FsType = FsType(libc::UDF_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const USBDEVICE_SUPER_MAGIC: FsType =
FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const XENFS_SUPER_MAGIC: FsType =
FsType(libc::XENFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(linux_android)]
#[allow(missing_docs)]
pub const NSFS_MAGIC: FsType = FsType(libc::NSFS_MAGIC as fs_type_t);
-#[cfg(all(
- any(target_os = "linux", target_os = "android"),
- not(target_env = "musl")
-))]
+#[cfg(all(linux_android, not(target_env = "musl"), not(target_env = "ohos")))]
#[allow(missing_docs)]
pub const XFS_SUPER_MAGIC: FsType = FsType(libc::XFS_SUPER_MAGIC as fs_type_t);
@@ -302,39 +292,33 @@ impl Statfs {
#[cfg(not(any(
target_os = "openbsd",
target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos"
+ apple_targets,
)))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn filesystem_type(&self) -> FsType {
FsType(self.0.f_type)
}
/// Magic code defining system type
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(linux_android))]
pub fn filesystem_type_name(&self) -> &str {
let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) };
c_str.to_str().unwrap()
}
/// Optimal transfer block size
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
pub fn optimal_transfer_size(&self) -> i32 {
self.0.f_iosize
}
/// Optimal transfer block size
#[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn optimal_transfer_size(&self) -> u32 {
self.0.f_iosize
}
/// Optimal transfer block size
- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(all(target_os = "linux", target_arch = "s390x", not(target_env = "musl")))]
pub fn optimal_transfer_size(&self) -> u32 {
self.0.f_bsize
}
@@ -342,9 +326,9 @@ impl Statfs {
/// Optimal transfer block size
#[cfg(any(
target_os = "android",
- all(target_os = "linux", target_env = "musl")
+ all(target_os = "linux", target_env = "musl"),
+ all(target_os = "linux", target_env = "ohos")
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn optimal_transfer_size(&self) -> libc::c_ulong {
self.0.f_bsize
}
@@ -355,46 +339,41 @@ impl Statfs {
not(any(
target_arch = "s390x",
target_env = "musl",
+ target_env = "ohos",
target_env = "uclibc"
))
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn optimal_transfer_size(&self) -> libc::__fsword_t {
self.0.f_bsize
}
/// Optimal transfer block size
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn optimal_transfer_size(&self) -> libc::c_int {
self.0.f_bsize
}
/// Optimal transfer block size
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn optimal_transfer_size(&self) -> libc::c_long {
self.0.f_iosize
}
/// Optimal transfer block size
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn optimal_transfer_size(&self) -> u64 {
self.0.f_iosize
}
/// Size of a block
- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(apple_targets, target_os = "openbsd"))]
pub fn block_size(&self) -> u32 {
self.0.f_bsize
}
/// Size of a block
// f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(all(target_os = "linux", target_arch = "s390x", not(target_env = "musl")))]
pub fn block_size(&self) -> u32 {
self.0.f_bsize
}
@@ -402,7 +381,13 @@ impl Statfs {
/// Size of a block
// f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
#[cfg(all(target_os = "linux", target_env = "musl"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ pub fn block_size(&self) -> libc::c_ulong {
+ self.0.f_bsize
+ }
+
+ /// Size of a block
+ // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
+ #[cfg(all(target_os = "linux", target_env = "ohos"))]
pub fn block_size(&self) -> libc::c_ulong {
self.0.f_bsize
}
@@ -410,7 +395,6 @@ impl Statfs {
/// Size of a block
// f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn block_size(&self) -> libc::c_int {
self.0.f_bsize
}
@@ -422,47 +406,34 @@ impl Statfs {
not(any(
target_arch = "s390x",
target_env = "musl",
+ target_env = "ohos",
target_env = "uclibc"
))
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn block_size(&self) -> libc::__fsword_t {
self.0.f_bsize
}
/// Size of a block
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn block_size(&self) -> u64 {
self.0.f_bsize
}
/// Size of a block
#[cfg(target_os = "android")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn block_size(&self) -> libc::c_ulong {
self.0.f_bsize
}
/// Size of a block
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn block_size(&self) -> libc::c_long {
self.0.f_bsize
}
/// Get the mount flags
- #[cfg(all(
- feature = "mount",
- any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(all(feature = "mount", bsd))]
#[allow(clippy::unnecessary_cast)] // Not unnecessary on all arches
pub fn flags(&self) -> MntFlags {
MntFlags::from_bits_truncate(self.0.f_flags as i32)
@@ -472,35 +443,30 @@ impl Statfs {
// The f_flags field exists on Android and Fuchsia too, but without man
// pages I can't tell if it can be cast to FsFlags.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn flags(&self) -> FsFlags {
FsFlags::from_bits_truncate(self.0.f_flags as libc::c_ulong)
}
/// Maximum length of filenames
#[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn maximum_name_length(&self) -> u32 {
self.0.f_namemax
}
/// Maximum length of filenames
- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(all(target_os = "linux", target_arch = "s390x", not(target_env = "musl")))]
pub fn maximum_name_length(&self) -> u32 {
self.0.f_namelen
}
/// Maximum length of filenames
#[cfg(all(target_os = "linux", target_env = "musl"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn maximum_name_length(&self) -> libc::c_ulong {
self.0.f_namelen
}
/// Maximum length of filenames
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn maximum_name_length(&self) -> libc::c_int {
self.0.f_namelen
}
@@ -511,173 +477,141 @@ impl Statfs {
not(any(
target_arch = "s390x",
target_env = "musl",
+ target_env = "ohos",
target_env = "uclibc"
))
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn maximum_name_length(&self) -> libc::__fsword_t {
self.0.f_namelen
}
/// Maximum length of filenames
#[cfg(target_os = "android")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn maximum_name_length(&self) -> libc::c_ulong {
self.0.f_namelen
}
/// Total data blocks in filesystem
#[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
+ apple_targets,
+ linux_android,
target_os = "freebsd",
target_os = "fuchsia",
target_os = "openbsd",
- target_os = "linux",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks(&self) -> u64 {
self.0.f_blocks
}
/// Total data blocks in filesystem
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks(&self) -> libc::c_long {
self.0.f_blocks
}
/// Total data blocks in filesystem
#[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks(&self) -> u32 {
self.0.f_blocks
}
/// Free blocks in filesystem
#[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
+ apple_targets,
+ linux_android,
target_os = "freebsd",
target_os = "fuchsia",
target_os = "openbsd",
- target_os = "linux",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_free(&self) -> u64 {
self.0.f_bfree
}
/// Free blocks in filesystem
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_free(&self) -> libc::c_long {
self.0.f_bfree
}
/// Free blocks in filesystem
#[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_free(&self) -> u32 {
self.0.f_bfree
}
/// Free blocks available to unprivileged user
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(apple_targets, linux_android, target_os = "fuchsia"))]
pub fn blocks_available(&self) -> u64 {
self.0.f_bavail
}
/// Free blocks available to unprivileged user
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_available(&self) -> libc::c_long {
self.0.f_bavail
}
/// Free blocks available to unprivileged user
#[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_available(&self) -> i64 {
self.0.f_bavail
}
/// Free blocks available to unprivileged user
#[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_available(&self) -> u32 {
self.0.f_bavail
}
/// Total file nodes in filesystem
#[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
+ apple_targets,
+ linux_android,
target_os = "freebsd",
target_os = "fuchsia",
target_os = "openbsd",
- target_os = "linux",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files(&self) -> u64 {
self.0.f_files
}
/// Total file nodes in filesystem
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files(&self) -> libc::c_long {
self.0.f_files
}
/// Total file nodes in filesystem
#[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files(&self) -> u32 {
self.0.f_files
}
/// Free file nodes in filesystem
#[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
+ apple_targets,
+ linux_android,
target_os = "fuchsia",
target_os = "openbsd",
- target_os = "linux",
))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files_free(&self) -> u64 {
self.0.f_ffree
}
/// Free file nodes in filesystem
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files_free(&self) -> libc::c_long {
self.0.f_ffree
}
/// Free file nodes in filesystem
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files_free(&self) -> i64 {
self.0.f_ffree
}
/// Free file nodes in filesystem
#[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files_free(&self) -> u32 {
self.0.f_ffree
}
@@ -699,16 +633,7 @@ impl Debug for Statfs {
ds.field("files", &self.files());
ds.field("files_free", &self.files_free());
ds.field("filesystem_id", &self.filesystem_id());
- #[cfg(all(
- feature = "mount",
- any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )
- ))]
+ #[cfg(all(feature = "mount", bsd))]
ds.field("flags", &self.flags());
ds.finish()
}
@@ -747,107 +672,3 @@ pub fn fstatfs<Fd: AsFd>(fd: Fd) -> Result<Statfs> {
.map(|_| Statfs(stat.assume_init()))
}
}
-
-#[cfg(test)]
-mod test {
- use std::fs::File;
-
- use crate::sys::statfs::*;
- use crate::sys::statvfs::*;
- use std::path::Path;
-
- #[test]
- fn statfs_call() {
- check_statfs("/tmp");
- check_statfs("/dev");
- check_statfs("/run");
- check_statfs("/");
- }
-
- #[test]
- fn fstatfs_call() {
- check_fstatfs("/tmp");
- check_fstatfs("/dev");
- check_fstatfs("/run");
- check_fstatfs("/");
- }
-
- fn check_fstatfs(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes()).unwrap();
- let file = File::open(path).unwrap();
- let fs = fstatfs(&file).unwrap();
- assert_fs_equals(fs, vfs);
- }
-
- fn check_statfs(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes()).unwrap();
- let fs = statfs(path.as_bytes()).unwrap();
- assert_fs_equals(fs, vfs);
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn assert_fs_equals(fs: Statfs, vfs: Statvfs) {
- assert_eq!(fs.files() as u64, vfs.files() as u64);
- assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
- assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
- }
-
- // This test is ignored because files_free/blocks_free can change after statvfs call and before
- // statfs call.
- #[test]
- #[ignore]
- fn statfs_call_strict() {
- check_statfs_strict("/tmp");
- check_statfs_strict("/dev");
- check_statfs_strict("/run");
- check_statfs_strict("/");
- }
-
- // This test is ignored because files_free/blocks_free can change after statvfs call and before
- // fstatfs call.
- #[test]
- #[ignore]
- fn fstatfs_call_strict() {
- check_fstatfs_strict("/tmp");
- check_fstatfs_strict("/dev");
- check_fstatfs_strict("/run");
- check_fstatfs_strict("/");
- }
-
- fn check_fstatfs_strict(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes());
- let file = File::open(path).unwrap();
- let fs = fstatfs(&file);
- assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
- }
-
- fn check_statfs_strict(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes());
- let fs = statfs(path.as_bytes());
- assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) {
- assert_eq!(fs.files_free() as u64, vfs.files_free() as u64);
- assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64);
- assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64);
- assert_eq!(fs.files() as u64, vfs.files() as u64);
- assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
- assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
- }
-}
diff --git a/third_party/rust/nix/src/sys/statvfs.rs b/third_party/rust/nix/src/sys/statvfs.rs
index 35424e5e27..db1abdd4fe 100644
--- a/third_party/rust/nix/src/sys/statvfs.rs
+++ b/third_party/rust/nix/src/sys/statvfs.rs
@@ -21,44 +21,34 @@ libc_bitflags!(
#[cfg(not(target_os = "haiku"))]
ST_NOSUID;
/// Do not interpret character or block-special devices
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ST_NODEV;
/// Do not allow execution of binaries on the filesystem
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ST_NOEXEC;
/// All IO should be done synchronously
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ST_SYNCHRONOUS;
/// Allow mandatory locks on the filesystem
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ST_MANDLOCK;
/// Write on file/directory/symlink
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
ST_WRITE;
/// Append-only file
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
ST_APPEND;
/// Immutable file
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
ST_IMMUTABLE;
/// Do not update access times on files
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ST_NOATIME;
/// Do not update access times on files
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
ST_NODIRATIME;
/// Update access time relative to modify/change time
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"), not(target_env = "ohos"))))]
ST_RELATIME;
}
);
@@ -114,13 +104,18 @@ impl Statvfs {
}
/// Get the file system id
+ #[cfg(not(target_os = "hurd"))]
pub fn filesystem_id(&self) -> c_ulong {
self.0.f_fsid
}
+ /// Get the file system id
+ #[cfg(target_os = "hurd")]
+ pub fn filesystem_id(&self) -> u64 {
+ self.0.f_fsid
+ }
/// Get the mount flags
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
pub fn flags(&self) -> FsFlags {
FsFlags::from_bits_truncate(self.0.f_flag)
}
@@ -153,20 +148,3 @@ pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> Result<Statvfs> {
.map(|_| Statvfs(stat.assume_init()))
}
}
-
-#[cfg(test)]
-mod test {
- use crate::sys::statvfs::*;
- use std::fs::File;
-
- #[test]
- fn statvfs_call() {
- statvfs(&b"/"[..]).unwrap();
- }
-
- #[test]
- fn fstatvfs_call() {
- let root = File::open("/").unwrap();
- fstatvfs(&root).unwrap();
- }
-}
diff --git a/third_party/rust/nix/src/sys/termios.rs b/third_party/rust/nix/src/sys/termios.rs
index ecaa3eaf8f..e006c2f1b0 100644
--- a/third_party/rust/nix/src/sys/termios.rs
+++ b/third_party/rust/nix/src/sys/termios.rs
@@ -85,28 +85,8 @@
//!
//! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`:
//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust,ignore"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust"
-)]
+#![cfg_attr(bsd, doc = " ```rust,ignore")]
+#![cfg_attr(not(bsd), doc = " ```rust")]
//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
//! # fn main() {
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
@@ -118,28 +98,8 @@
//!
//! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s:
//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust,ignore"
-)]
+#![cfg_attr(bsd, doc = " ```rust")]
+#![cfg_attr(not(bsd), doc = " ```rust,ignore")]
//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
//! # fn main() {
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
@@ -151,28 +111,8 @@
//!
//! It's trivial to convert from a `BaudRate` to a `u32` on BSDs:
//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust,ignore"
-)]
+#![cfg_attr(bsd, doc = " ```rust")]
+#![cfg_attr(not(bsd), doc = " ```rust,ignore")]
//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios};
//! # fn main() {
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
@@ -185,28 +125,8 @@
//! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support)
//! by specifying baud rates directly using `u32`s:
//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust,ignore"
-)]
+#![cfg_attr(bsd, doc = " ```rust")]
+#![cfg_attr(not(bsd), doc = " ```rust,ignore")]
//! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios};
//! # fn main() {
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
@@ -246,7 +166,7 @@ pub struct Termios {
/// Control characters (see `termios.c_cc` documentation)
pub control_chars: [libc::cc_t; NCCS],
/// Line discipline (see `termios.c_line` documentation)
- #[cfg(any(target_os = "linux", target_os = "android",))]
+ #[cfg(linux_android)]
pub line_discipline: libc::cc_t,
/// Line discipline (see `termios.c_line` documentation)
#[cfg(target_os = "haiku")]
@@ -266,11 +186,7 @@ impl Termios {
termios.c_cflag = self.control_flags.bits();
termios.c_lflag = self.local_flags.bits();
termios.c_cc = self.control_chars;
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
+ #[cfg(any(linux_android, target_os = "haiku"))]
{
termios.c_line = self.line_discipline;
}
@@ -292,11 +208,7 @@ impl Termios {
termios.c_cflag = self.control_flags.bits();
termios.c_lflag = self.local_flags.bits();
termios.c_cc = self.control_chars;
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
+ #[cfg(any(linux_android, target_os = "haiku"))]
{
termios.c_line = self.line_discipline;
}
@@ -312,11 +224,7 @@ impl Termios {
self.control_flags = ControlFlags::from_bits_retain(termios.c_cflag);
self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag);
self.control_chars = termios.c_cc;
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
+ #[cfg(any(linux_android, target_os = "haiku"))]
{
self.line_discipline = termios.c_line;
}
@@ -332,11 +240,7 @@ impl From<libc::termios> for Termios {
control_flags: ControlFlags::from_bits_truncate(termios.c_cflag),
local_flags: LocalFlags::from_bits_truncate(termios.c_lflag),
control_chars: termios.c_cc,
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
+ #[cfg(any(linux_android, target_os = "haiku"))]
line_discipline: termios.c_line,
}
}
@@ -356,8 +260,13 @@ libc_enum! {
///
/// B0 is special and will disable the port.
#[cfg_attr(target_os = "haiku", repr(u8))]
- #[cfg_attr(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64"), repr(u64))]
- #[cfg_attr(all(not(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64")), not(target_os = "haiku")), repr(u32))]
+ #[cfg_attr(target_os = "hurd", repr(i32))]
+ #[cfg_attr(all(apple_targets, target_pointer_width = "64"), repr(u64))]
+ #[cfg_attr(all(
+ not(all(apple_targets, target_pointer_width = "64")),
+ not(target_os = "haiku"),
+ not(target_os = "hurd")
+ ), repr(u32))]
#[non_exhaustive]
pub enum BaudRate {
B0,
@@ -373,110 +282,62 @@ libc_enum! {
B1800,
B2400,
B4800,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
B7200,
B9600,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
B14400,
B19200,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
B28800,
B38400,
#[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B57600,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
B76800,
#[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B115200,
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(solarish)]
B153600,
#[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B230400,
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(solarish)]
B307200,
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
+ solarish,
target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ target_os = "netbsd"))]
B460800,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
B500000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
B576000,
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
+ solarish,
target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ target_os = "netbsd"))]
B921600,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
B1000000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
B1152000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
B1500000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
B2000000,
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B2500000,
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B3000000,
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B3500000,
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
B4000000,
}
impl TryFrom<libc::speed_t>
}
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
+#[cfg(bsd)]
impl From<BaudRate> for u32 {
fn from(b: BaudRate) -> u32 {
b as u32
@@ -542,80 +403,57 @@ libc_enum! {
}
// TODO: Make this usable directly as a slice index.
-#[cfg(not(target_os = "haiku"))]
libc_enum! {
/// Indices into the `termios.c_cc` array for special characters.
#[repr(usize)]
#[non_exhaustive]
pub enum SpecialCharacterIndices {
- #[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(target_os = "aix", target_os = "haiku")))]
VDISCARD,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "aix",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(bsd,
+ solarish,
+ target_os = "aix"))]
VDSUSP,
VEOF,
VEOL,
VEOL2,
VERASE,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(freebsdlike, solarish))]
VERASE2,
VINTR,
VKILL,
+ #[cfg(not(target_os = "haiku"))]
VLNEXT,
#[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"),
- target_os = "illumos", target_os = "solaris", target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ solarish, target_os = "aix", target_os = "haiku")))]
VMIN,
VQUIT,
+ #[cfg(not(target_os = "haiku"))]
VREPRINT,
VSTART,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(bsd, solarish))]
VSTATUS,
VSTOP,
VSUSP,
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
VSWTC,
- #[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(solarish, target_os = "haiku"))]
VSWTCH,
#[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"),
- target_os = "illumos", target_os = "solaris", target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ solarish, target_os = "aix", target_os = "haiku")))]
VTIME,
- #[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(target_os = "aix", target_os = "haiku")))]
VWERASE,
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
VCHECKPT,
}
}
#[cfg(any(
all(target_os = "linux", target_arch = "sparc64"),
- target_os = "illumos",
- target_os = "solaris",
+ solarish,
target_os = "aix",
+ target_os = "haiku",
))]
impl SpecialCharacterIndices {
pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF;
@@ -623,17 +461,7 @@ impl SpecialCharacterIndices {
}
pub use libc::NCCS;
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "aix",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(linux_android, target_os = "aix", bsd))]
pub use libc::_POSIX_VDISABLE;
libc_bitflags! {
@@ -651,13 +479,10 @@ libc_bitflags! {
IXON;
IXOFF;
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
IXANY;
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
IMAXBEL;
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
IUTF8;
}
}
@@ -666,209 +491,119 @@ libc_bitflags! {
/// Flags for configuring the output mode of a terminal
pub struct OutputFlags: tcflag_t {
OPOST;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "linux",
target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
OLCUC;
ONLCR;
OCRNL as tcflag_t;
ONOCR as tcflag_t;
ONLRET as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- OFILL as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
OFDEL as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
NL0 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
NL1 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
CR0 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
CR1 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
CR2 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
CR3 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "freebsd",
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
TAB0 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
TAB1 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
TAB2 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "freebsd",
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
TAB3 as tcflag_t;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
XTABS;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
BS0 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
BS1 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
VT0 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
VT1 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
FF0 as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
FF1 as tcflag_t;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
OXTABS;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
ONOEOT as tcflag_t;
// Bitmasks for use with OutputFlags to select specific settings
// These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110
// is resolved.
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
NLDLY as tcflag_t; // FIXME: Datatype needs to be corrected in libc for mac
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
CRDLY as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "freebsd",
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
TABDLY as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
BSDLY as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
VTDLY as tcflag_t;
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ apple_targets))]
FFDLY as tcflag_t;
}
}
@@ -876,13 +611,7 @@ libc_bitflags! {
libc_bitflags! {
/// Flags for setting the control mode of a terminal
pub struct ControlFlags: tcflag_t {
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
CIGNORE;
CS5;
CS6;
@@ -895,54 +624,30 @@ libc_bitflags! {
HUPCL;
CLOCAL;
#[cfg(not(any(target_os = "redox", target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
CRTSCTS;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
CBAUD;
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "mips"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
CMSPAR;
#[cfg(any(target_os = "android",
all(target_os = "linux",
not(any(target_arch = "powerpc", target_arch = "powerpc64")))))]
CIBAUD;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
CBAUDEX;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
MDMBUF;
- #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(netbsdlike)]
CHWFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(freebsdlike, netbsdlike))]
CCTS_OFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(freebsdlike, netbsdlike))]
CRTS_IFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
CDTR_IFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
CDSR_OFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
CCAR_OFLOW;
// Bitmasks for use with ControlFlags to select specific settings
@@ -957,58 +662,35 @@ libc_bitflags! {
/// Flags for setting any local modes
pub struct LocalFlags: tcflag_t {
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
ECHOKE;
ECHOE;
ECHOK;
ECHO;
ECHONL;
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
ECHOPRT;
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
ECHOCTL;
ISIG;
ICANON;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
ALTWERASE;
IEXTEN;
#[cfg(not(any(target_os = "redox", target_os = "haiku", target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
EXTPROC;
TOSTOP;
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
FLUSHO;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
NOKERNINFO;
#[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
PENDIN;
NOFLSH;
}
}
cfg_if! {
- if #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))] {
+ if #[cfg(bsd)] {
/// Get input baud rate (see
/// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
///
@@ -1141,7 +823,6 @@ pub fn cfmakeraw(termios: &mut Termios) {
///
/// Note that this is a non-standard function, available on FreeBSD.
#[cfg(target_os = "freebsd")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn cfmakesane(termios: &mut Termios) {
let inner_termios = unsafe { termios.get_libc_termios_mut() };
unsafe {
@@ -1242,18 +923,3 @@ pub fn tcgetsid<Fd: AsFd>(fd: Fd) -> Result<Pid> {
Errno::result(res).map(Pid::from_raw)
}
}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use std::convert::TryFrom;
-
- #[test]
- fn try_from() {
- assert_eq!(Ok(BaudRate::B0), BaudRate::try_from(libc::B0));
- #[cfg(not(target_os = "haiku"))]
- BaudRate::try_from(999999999).expect_err("assertion failed");
- #[cfg(target_os = "haiku")]
- BaudRate::try_from(99).expect_err("assertion failed");
- }
-}
diff --git a/third_party/rust/nix/src/sys/time.rs b/third_party/rust/nix/src/sys/time.rs
index a0160e21ff..af436cabd5 100644
--- a/third_party/rust/nix/src/sys/time.rs
+++ b/third_party/rust/nix/src/sys/time.rs
@@ -2,7 +2,6 @@
// https://github.com/rust-lang/libc/issues/1848
pub use libc::{suseconds_t, time_t};
use libc::{timespec, timeval};
-use std::convert::From;
use std::time::Duration;
use std::{cmp, fmt, ops};
@@ -18,7 +17,7 @@ const fn zero_init_timespec() -> timespec {
all(
any(
target_os = "freebsd",
- target_os = "illumos",
+ solarish,
target_os = "linux",
target_os = "netbsd"
),
@@ -88,7 +87,7 @@ pub(crate) mod timer {
Interval(TimeSpec),
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
bitflags! {
/// Flags that are used for arming the timer.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -97,12 +96,7 @@ pub(crate) mod timer {
const TFD_TIMER_CANCEL_ON_SET = libc::TFD_TIMER_CANCEL_ON_SET;
}
}
- #[cfg(any(
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "dragonfly",
- target_os = "illumos"
- ))]
+ #[cfg(any(freebsdlike, target_os = "netbsd", solarish))]
bitflags! {
/// Flags that are used for arming the timer.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -334,6 +328,17 @@ impl TimeValLike for TimeSpec {
}
impl TimeSpec {
+ /// Leave the timestamp unchanged.
+ #[cfg(not(target_os = "redox"))]
+ // At the time of writing this PR, redox does not support this feature
+ pub const UTIME_OMIT: TimeSpec =
+ TimeSpec::new(0, libc::UTIME_OMIT as timespec_tv_nsec_t);
+ /// Update the timestamp to `Now`
+ // At the time of writing this PR, redox does not support this feature
+ #[cfg(not(target_os = "redox"))]
+ pub const UTIME_NOW: TimeSpec =
+ TimeSpec::new(0, libc::UTIME_NOW as timespec_tv_nsec_t);
+
/// Construct a new `TimeSpec` from its components
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
pub const fn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self {
@@ -712,101 +717,3 @@ fn mod_floor_64(this: i64, other: i64) -> i64 {
fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
(this / other, this % other)
}
-
-#[cfg(test)]
-mod test {
- use super::{TimeSpec, TimeVal, TimeValLike};
- use std::time::Duration;
-
- #[test]
- pub fn test_timespec() {
- assert_ne!(TimeSpec::seconds(1), TimeSpec::zero());
- assert_eq!(
- TimeSpec::seconds(1) + TimeSpec::seconds(2),
- TimeSpec::seconds(3)
- );
- assert_eq!(
- TimeSpec::minutes(3) + TimeSpec::seconds(2),
- TimeSpec::seconds(182)
- );
- }
-
- #[test]
- pub fn test_timespec_from() {
- let duration = Duration::new(123, 123_456_789);
- let timespec = TimeSpec::nanoseconds(123_123_456_789);
-
- assert_eq!(TimeSpec::from(duration), timespec);
- assert_eq!(Duration::from(timespec), duration);
- }
-
- #[test]
- pub fn test_timespec_neg() {
- let a = TimeSpec::seconds(1) + TimeSpec::nanoseconds(123);
- let b = TimeSpec::seconds(-1) + TimeSpec::nanoseconds(-123);
-
- assert_eq!(a, -b);
- }
-
- #[test]
- pub fn test_timespec_ord() {
- assert_eq!(TimeSpec::seconds(1), TimeSpec::nanoseconds(1_000_000_000));
- assert!(TimeSpec::seconds(1) < TimeSpec::nanoseconds(1_000_000_001));
- assert!(TimeSpec::seconds(1) > TimeSpec::nanoseconds(999_999_999));
- assert!(TimeSpec::seconds(-1) < TimeSpec::nanoseconds(-999_999_999));
- assert!(TimeSpec::seconds(-1) > TimeSpec::nanoseconds(-1_000_000_001));
- }
-
- #[test]
- pub fn test_timespec_fmt() {
- assert_eq!(TimeSpec::zero().to_string(), "0 seconds");
- assert_eq!(TimeSpec::seconds(42).to_string(), "42 seconds");
- assert_eq!(TimeSpec::milliseconds(42).to_string(), "0.042 seconds");
- assert_eq!(TimeSpec::microseconds(42).to_string(), "0.000042 seconds");
- assert_eq!(
- TimeSpec::nanoseconds(42).to_string(),
- "0.000000042 seconds"
- );
- assert_eq!(TimeSpec::seconds(-86401).to_string(), "-86401 seconds");
- }
-
- #[test]
- pub fn test_timeval() {
- assert_ne!(TimeVal::seconds(1), TimeVal::zero());
- assert_eq!(
- TimeVal::seconds(1) + TimeVal::seconds(2),
- TimeVal::seconds(3)
- );
- assert_eq!(
- TimeVal::minutes(3) + TimeVal::seconds(2),
- TimeVal::seconds(182)
- );
- }
-
- #[test]
- pub fn test_timeval_ord() {
- assert_eq!(TimeVal::seconds(1), TimeVal::microseconds(1_000_000));
- assert!(TimeVal::seconds(1) < TimeVal::microseconds(1_000_001));
- assert!(TimeVal::seconds(1) > TimeVal::microseconds(999_999));
- assert!(TimeVal::seconds(-1) < TimeVal::microseconds(-999_999));
- assert!(TimeVal::seconds(-1) > TimeVal::microseconds(-1_000_001));
- }
-
- #[test]
- pub fn test_timeval_neg() {
- let a = TimeVal::seconds(1) + TimeVal::microseconds(123);
- let b = TimeVal::seconds(-1) + TimeVal::microseconds(-123);
-
- assert_eq!(a, -b);
- }
-
- #[test]
- pub fn test_timeval_fmt() {
- assert_eq!(TimeVal::zero().to_string(), "0 seconds");
- assert_eq!(TimeVal::seconds(42).to_string(), "42 seconds");
- assert_eq!(TimeVal::milliseconds(42).to_string(), "0.042 seconds");
- assert_eq!(TimeVal::microseconds(42).to_string(), "0.000042 seconds");
- assert_eq!(TimeVal::nanoseconds(1402).to_string(), "0.000001 seconds");
- assert_eq!(TimeVal::seconds(-86401).to_string(), "-86401 seconds");
- }
-}
diff --git a/third_party/rust/nix/src/sys/timerfd.rs b/third_party/rust/nix/src/sys/timerfd.rs
index c4337c9dfa..68b06d6322 100644
--- a/third_party/rust/nix/src/sys/timerfd.rs
+++ b/third_party/rust/nix/src/sys/timerfd.rs
@@ -53,7 +53,7 @@ impl AsFd for TimerFd {
impl FromRawFd for TimerFd {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
TimerFd {
- fd: OwnedFd::from_raw_fd(fd),
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
}
}
}
diff --git a/third_party/rust/nix/src/sys/uio.rs b/third_party/rust/nix/src/sys/uio.rs
index eaf61edfd4..cdf380dd11 100644
--- a/third_party/rust/nix/src/sys/uio.rs
+++ b/third_party/rust/nix/src/sys/uio.rs
@@ -2,7 +2,7 @@
use crate::errno::Errno;
use crate::Result;
-use libc::{self, c_int, c_void, off_t, size_t};
+use libc::{self, c_int, off_t, size_t};
use std::io::{IoSlice, IoSliceMut};
use std::os::unix::io::{AsFd, AsRawFd};
@@ -18,7 +18,11 @@ pub fn writev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>]) -> Result<usize> {
//
// Because it is ABI compatible, a pointer cast here is valid
let res = unsafe {
- libc::writev(fd.as_fd().as_raw_fd(), iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
+ libc::writev(
+ fd.as_fd().as_raw_fd(),
+ iov.as_ptr().cast(),
+ iov.len() as c_int,
+ )
};
Errno::result(res).map(|r| r as usize)
@@ -33,7 +37,11 @@ pub fn writev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>]) -> 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.as_fd().as_raw_fd(), iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
+ libc::readv(
+ fd.as_fd().as_raw_fd(),
+ iov.as_ptr().cast(),
+ iov.len() as c_int,
+ )
};
Errno::result(res).map(|r| r as usize)
@@ -45,9 +53,12 @@ pub fn readv<Fd: AsFd>(fd: Fd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
/// or an error occurs. The file offset is not changed.
///
/// 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: AsFd>(fd: Fd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
+#[cfg(not(any(target_os = "redox", target_os = "haiku", target_os = "solaris")))]
+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
@@ -55,7 +66,7 @@ pub fn pwritev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>], offset: off_t) -> Result<u
let res = unsafe {
libc::pwritev(
fd.as_fd().as_raw_fd(),
- iov.as_ptr() as *const libc::iovec,
+ iov.as_ptr().cast(),
iov.len() as c_int,
offset,
)
@@ -71,8 +82,7 @@ pub fn pwritev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>], offset: off_t) -> Result<u
/// changed.
///
/// 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())))]
+#[cfg(not(any(target_os = "redox", target_os = "haiku", target_os = "solaris")))]
// Clippy doesn't know that we need to pass iov mutably only because the
// mutation happens after converting iov to a pointer
#[allow(clippy::needless_pass_by_ref_mut)]
@@ -88,7 +98,7 @@ pub fn preadv<Fd: AsFd>(
let res = unsafe {
libc::preadv(
fd.as_fd().as_raw_fd(),
- iov.as_ptr() as *const libc::iovec,
+ iov.as_ptr().cast(),
iov.len() as c_int,
offset,
)
@@ -105,7 +115,7 @@ pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pwrite(
fd.as_fd().as_raw_fd(),
- buf.as_ptr() as *const c_void,
+ buf.as_ptr().cast(),
buf.len() as size_t,
offset,
)
@@ -122,7 +132,7 @@ pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pread(
fd.as_fd().as_raw_fd(),
- buf.as_mut_ptr() as *mut c_void,
+ buf.as_mut_ptr().cast(),
buf.len() as size_t,
offset,
)
@@ -139,8 +149,7 @@ pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: off_t) -> Result<usize> {
/// therefore not represented in Rust by an actual slice as `IoSlice` is. It
/// is used with [`process_vm_readv`](fn.process_vm_readv.html)
/// and [`process_vm_writev`](fn.process_vm_writev.html).
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(linux_android)]
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct RemoteIoVec {
@@ -173,7 +182,7 @@ feature! {
/// [ptrace]: ../ptrace/index.html
/// [`IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html
/// [`RemoteIoVec`]: struct.RemoteIoVec.html
-#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
+#[cfg(all(linux_android, not(target_env = "uclibc")))]
pub fn process_vm_writev(
pid: crate::unistd::Pid,
local_iov: &[IoSlice<'_>],
@@ -181,8 +190,8 @@ pub fn process_vm_writev(
{
let res = unsafe {
libc::process_vm_writev(pid.into(),
- local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
- remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
+ local_iov.as_ptr().cast(), local_iov.len() as libc::c_ulong,
+ remote_iov.as_ptr().cast(), remote_iov.len() as libc::c_ulong, 0)
};
Errno::result(res).map(|r| r as usize)
@@ -208,7 +217,7 @@ pub fn process_vm_writev(
/// [`ptrace`]: ../ptrace/index.html
/// [`IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html
/// [`RemoteIoVec`]: struct.RemoteIoVec.html
-#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
+#[cfg(all(linux_android, not(target_env = "uclibc")))]
pub fn process_vm_readv(
pid: crate::unistd::Pid,
local_iov: &mut [IoSliceMut<'_>],
@@ -216,8 +225,8 @@ pub fn process_vm_readv(
{
let res = unsafe {
libc::process_vm_readv(pid.into(),
- local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
- remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
+ local_iov.as_ptr().cast(), local_iov.len() as libc::c_ulong,
+ remote_iov.as_ptr().cast(), remote_iov.len() as libc::c_ulong, 0)
};
Errno::result(res).map(|r| r as usize)
diff --git a/third_party/rust/nix/src/sys/utsname.rs b/third_party/rust/nix/src/sys/utsname.rs
index b48ed9f45e..cf4e6cc738 100644
--- a/third_party/rust/nix/src/sys/utsname.rs
+++ b/third_party/rust/nix/src/sys/utsname.rs
@@ -37,7 +37,7 @@ impl UtsName {
}
/// NIS or YP domain name of this machine.
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
pub fn domainname(&self) -> &OsStr {
cast_and_trim(&self.0.domainname)
}
@@ -62,24 +62,3 @@ fn cast_and_trim(slice: &[c_char]) -> &OsStr {
OsStr::from_bytes(bytes)
}
-
-#[cfg(test)]
-mod test {
- #[cfg(target_os = "linux")]
- #[test]
- pub fn test_uname_linux() {
- assert_eq!(super::uname().unwrap().sysname(), "Linux");
- }
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- #[test]
- pub fn test_uname_darwin() {
- assert_eq!(super::uname().unwrap().sysname(), "Darwin");
- }
-
- #[cfg(target_os = "freebsd")]
- #[test]
- pub fn test_uname_freebsd() {
- assert_eq!(super::uname().unwrap().sysname(), "FreeBSD");
- }
-}
diff --git a/third_party/rust/nix/src/sys/wait.rs b/third_party/rust/nix/src/sys/wait.rs
index f7a63ffcd2..844e165c18 100644
--- a/third_party/rust/nix/src/sys/wait.rs
+++ b/third_party/rust/nix/src/sys/wait.rs
@@ -24,53 +24,41 @@ libc_bitflags!(
/// [`SIGSTOP`](crate::sys::signal::Signal::SIGSTOP) signal.
WUNTRACED;
/// Report the status of selected processes which have terminated.
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
+ apple_targets,
target_os = "freebsd",
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
target_os = "redox",
- target_os = "macos",
target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
WEXITED;
/// Report the status of selected processes that have continued from a
/// job control stop by receiving a
/// [`SIGCONT`](crate::sys::signal::Signal::SIGCONT) signal.
WCONTINUED;
/// An alias for WUNTRACED.
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
+ apple_targets,
target_os = "freebsd",
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
target_os = "redox",
- target_os = "macos",
target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
WSTOPPED;
/// Don't reap, just poll status.
- #[cfg(any(target_os = "android",
+ #[cfg(any(linux_android,
+ apple_targets,
target_os = "freebsd",
target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
target_os = "redox",
- target_os = "macos",
target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
WNOWAIT;
/// Don't wait on children of other threads in this group
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "redox"))]
__WNOTHREAD;
/// Wait on all children, regardless of type
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "redox"))]
__WALL;
/// Wait for "clone" children only.
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, target_os = "redox"))]
__WCLONE;
}
);
@@ -107,16 +95,14 @@ pub enum WaitStatus {
///
/// [`nix::sys::ptrace`]: ../ptrace/index.html
/// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html
- #[cfg(any(target_os = "linux", target_os = "android"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
PtraceEvent(Pid, Signal, c_int),
/// The traced process was stopped by execution of a system call,
/// and `PTRACE_O_TRACESYSGOOD` is in effect. See [`ptrace`(2)] for
/// more information.
///
/// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html
- #[cfg(any(target_os = "linux", target_os = "android"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
PtraceSyscall(Pid),
/// The process was previously stopped but has resumed execution
/// after receiving a `SIGCONT` signal. This is only reported if
@@ -139,7 +125,7 @@ impl WaitStatus {
Some(p)
}
StillAlive => None,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p),
}
}
@@ -173,7 +159,7 @@ fn stop_signal(status: i32) -> Result<Signal> {
Signal::try_from(libc::WSTOPSIG(status))
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
fn syscall_stop(status: i32) -> bool {
// From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect
// of delivering SIGTRAP | 0x80 as the signal number for syscall
@@ -182,7 +168,7 @@ fn syscall_stop(status: i32) -> bool {
libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
fn stop_additional(status: i32) -> c_int {
(status >> 16) as c_int
}
@@ -216,7 +202,7 @@ impl WaitStatus {
WaitStatus::Signaled(pid, term_signal(status)?, dumped_core(status))
} else if stopped(status) {
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(linux_android)] {
fn decode_stopped(pid: Pid, status: i32) -> Result<WaitStatus> {
let status_additional = stop_additional(status);
Ok(if syscall_stop(status) {
@@ -259,7 +245,7 @@ impl WaitStatus {
all(target_os = "linux", not(target_env = "uclibc")),
))]
unsafe fn from_siginfo(siginfo: &libc::siginfo_t) -> Result<WaitStatus> {
- let si_pid = siginfo.si_pid();
+ let si_pid = unsafe { siginfo.si_pid() };
if si_pid == 0 {
return Ok(WaitStatus::StillAlive);
}
@@ -267,7 +253,7 @@ impl WaitStatus {
assert_eq!(siginfo.si_signo, libc::SIGCHLD);
let pid = Pid::from_raw(si_pid);
- let si_status = siginfo.si_status();
+ let si_status = unsafe { siginfo.si_status() };
let status = match siginfo.si_code {
libc::CLD_EXITED => WaitStatus::Exited(pid, si_status),
@@ -280,7 +266,7 @@ impl WaitStatus {
WaitStatus::Stopped(pid, Signal::try_from(si_status)?)
}
libc::CLD_CONTINUED => WaitStatus::Continued(pid),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::CLD_TRAPPED => {
if si_status == libc::SIGTRAP | 0x80 {
WaitStatus::PtraceSyscall(pid)
@@ -354,7 +340,7 @@ pub enum Id<'fd> {
/// If the PID is zero, the caller's process group is used since Linux 5.4.
PGid(Pid),
/// Wait for the child referred to by the given PID file descriptor
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
PIDFd(BorrowedFd<'fd>),
/// A helper variant to resolve the unused parameter (`'fd`) problem on platforms
/// other than Linux and Android.
@@ -376,9 +362,11 @@ pub fn waitid(id: Id, flags: WaitPidFlag) -> Result<WaitStatus> {
Id::All => (libc::P_ALL, 0),
Id::Pid(pid) => (libc::P_PID, pid.as_raw() as libc::id_t),
Id::PGid(pid) => (libc::P_PGID, pid.as_raw() as libc::id_t),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
Id::PIDFd(fd) => (libc::P_PIDFD, fd.as_raw_fd() as libc::id_t),
- Id::_Unreachable(_) => unreachable!("This variant could never be constructed"),
+ Id::_Unreachable(_) => {
+ unreachable!("This variant could never be constructed")
+ }
};
let siginfo = unsafe {