summaryrefslogtreecommitdiffstats
path: root/vendor/nix/test/sys
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/nix/test/sys
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/nix/test/sys')
-rw-r--r--vendor/nix/test/sys/mod.rs60
-rw-r--r--vendor/nix/test/sys/test_aio.rs626
-rw-r--r--vendor/nix/test/sys/test_aio_drop.rs35
-rw-r--r--vendor/nix/test/sys/test_epoll.rs24
-rw-r--r--vendor/nix/test/sys/test_inotify.rs65
-rw-r--r--vendor/nix/test/sys/test_ioctl.rs376
-rw-r--r--vendor/nix/test/sys/test_mman.rs122
-rw-r--r--vendor/nix/test/sys/test_pthread.rs22
-rw-r--r--vendor/nix/test/sys/test_ptrace.rs275
-rw-r--r--vendor/nix/test/sys/test_select.rs81
-rw-r--r--vendor/nix/test/sys/test_signal.rs147
-rw-r--r--vendor/nix/test/sys/test_signalfd.rs27
-rw-r--r--vendor/nix/test/sys/test_socket.rs2628
-rw-r--r--vendor/nix/test/sys/test_sockopt.rs431
-rw-r--r--vendor/nix/test/sys/test_stat.rs29
-rw-r--r--vendor/nix/test/sys/test_sysinfo.rs20
-rw-r--r--vendor/nix/test/sys/test_termios.rs136
-rw-r--r--vendor/nix/test/sys/test_timerfd.rs69
-rw-r--r--vendor/nix/test/sys/test_uio.rs270
-rw-r--r--vendor/nix/test/sys/test_wait.rs257
20 files changed, 0 insertions, 5700 deletions
diff --git a/vendor/nix/test/sys/mod.rs b/vendor/nix/test/sys/mod.rs
deleted file mode 100644
index 20312120a..000000000
--- a/vendor/nix/test/sys/mod.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-mod test_signal;
-
-// NOTE: DragonFly lacks a kernel-level implementation of Posix AIO as of
-// this writing. There is an user-level implementation, but whether aio
-// works or not heavily depends on which pthread implementation is chosen
-// by the user at link time. For this reason we do not want to run aio test
-// cases on DragonFly.
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "macos",
- target_os = "netbsd"
-))]
-mod test_aio;
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-mod test_ioctl;
-#[cfg(not(target_os = "redox"))]
-mod test_mman;
-#[cfg(not(target_os = "redox"))]
-mod test_select;
-#[cfg(target_os = "linux")]
-mod test_signalfd;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-mod test_socket;
-#[cfg(not(any(target_os = "redox")))]
-mod test_sockopt;
-mod test_stat;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_sysinfo;
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-mod test_termios;
-mod test_uio;
-mod test_wait;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_epoll;
-#[cfg(target_os = "linux")]
-mod test_inotify;
-mod test_pthread;
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-mod test_ptrace;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_timerfd;
diff --git a/vendor/nix/test/sys/test_aio.rs b/vendor/nix/test/sys/test_aio.rs
deleted file mode 100644
index 84086f80c..000000000
--- a/vendor/nix/test/sys/test_aio.rs
+++ /dev/null
@@ -1,626 +0,0 @@
-use std::{
- io::{Read, Seek, Write},
- ops::Deref,
- os::unix::io::AsRawFd,
- pin::Pin,
- sync::atomic::{AtomicBool, Ordering},
- thread, time,
-};
-
-use libc::c_int;
-use nix::{
- errno::*,
- sys::{
- aio::*,
- signal::{
- sigaction, SaFlags, SigAction, SigHandler, SigSet, SigevNotify,
- Signal,
- },
- time::{TimeSpec, TimeValLike},
- },
-};
-use tempfile::tempfile;
-
-lazy_static! {
- pub static ref SIGNALED: AtomicBool = AtomicBool::new(false);
-}
-
-extern "C" fn sigfunc(_: c_int) {
- SIGNALED.store(true, Ordering::Relaxed);
-}
-
-// Helper that polls an AioCb for completion or error
-macro_rules! poll_aio {
- ($aiocb: expr) => {
- loop {
- let err = $aiocb.as_mut().error();
- if err != Err(Errno::EINPROGRESS) {
- break err;
- };
- thread::sleep(time::Duration::from_millis(10));
- }
- };
-}
-
-mod aio_fsync {
- use super::*;
-
- #[test]
- fn test_accessors() {
- let aiocb = AioFsync::new(
- 1001,
- AioFsyncMode::O_SYNC,
- 42,
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(AioFsyncMode::O_SYNC, aiocb.mode());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- /// `AioFsync::submit` should not modify the `AioCb` object if
- /// `libc::aio_fsync` returns an error
- // Skip on Linux, because Linux's AIO implementation can't detect errors
- // synchronously
- #[test]
- #[cfg(any(target_os = "freebsd", target_os = "macos"))]
- fn error() {
- use std::mem;
-
- const INITIAL: &[u8] = b"abcdef123456";
- // Create an invalid AioFsyncMode
- let mode = unsafe { mem::transmute(666) };
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiof = Box::pin(AioFsync::new(
- f.as_raw_fd(),
- mode,
- 0,
- SigevNotify::SigevNone,
- ));
- let err = aiof.as_mut().submit();
- err.expect_err("assertion failed");
- }
-
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let fd = f.as_raw_fd();
- let mut aiof = Box::pin(AioFsync::new(
- fd,
- AioFsyncMode::O_SYNC,
- 0,
- SigevNotify::SigevNone,
- ));
- aiof.as_mut().submit().unwrap();
- poll_aio!(&mut aiof).unwrap();
- aiof.as_mut().aio_return().unwrap();
- }
-}
-
-mod aio_read {
- use super::*;
-
- #[test]
- fn test_accessors() {
- let mut rbuf = vec![0; 4];
- let aiocb = AioRead::new(
- 1001,
- 2, //offset
- &mut rbuf,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(4, aiocb.nbytes());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- // Tests AioWrite.cancel. We aren't trying to test the OS's implementation,
- // only our bindings. So it's sufficient to check that cancel
- // returned any AioCancelStat value.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn cancel() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let fd = f.as_raw_fd();
- let mut aior =
- Box::pin(AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone));
- aior.as_mut().submit().unwrap();
-
- aior.as_mut().cancel().unwrap();
-
- // Wait for aiow to complete, but don't care whether it succeeded
- let _ = poll_aio!(&mut aior);
- let _ = aior.as_mut().aio_return();
- }
-
- /// `AioRead::submit` should not modify the `AioCb` object if
- /// `libc::aio_read` returns an error
- // Skip on Linux, because Linux's AIO implementation can't detect errors
- // synchronously
- #[test]
- #[cfg(any(target_os = "freebsd", target_os = "macos"))]
- fn error() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aior = Box::pin(AioRead::new(
- f.as_raw_fd(),
- -1, //an invalid offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aior.as_mut().submit().expect_err("assertion failed");
- }
-
- // Test a simple aio operation with no completion notification. We must
- // poll for completion
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- const EXPECT: &[u8] = b"cdef";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- {
- let fd = f.as_raw_fd();
- let mut aior = Box::pin(AioRead::new(
- fd,
- 2,
- &mut rbuf,
- 0,
- SigevNotify::SigevNone,
- ));
- aior.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aior);
- assert_eq!(err, Ok(()));
- assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len());
- }
- assert_eq!(EXPECT, rbuf.deref().deref());
- }
-
- // Like ok, but allocates the structure on the stack.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn on_stack() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- const EXPECT: &[u8] = b"cdef";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- {
- let fd = f.as_raw_fd();
- let mut aior =
- AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone);
- let mut aior = unsafe { Pin::new_unchecked(&mut aior) };
- aior.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aior);
- assert_eq!(err, Ok(()));
- assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len());
- }
- assert_eq!(EXPECT, rbuf.deref().deref());
- }
-}
-
-#[cfg(target_os = "freebsd")]
-#[cfg(fbsd14)]
-mod aio_readv {
- use std::io::IoSliceMut;
-
- use super::*;
-
- #[test]
- fn test_accessors() {
- let mut rbuf0 = vec![0; 4];
- let mut rbuf1 = vec![0; 8];
- let mut rbufs =
- [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)];
- let aiocb = AioReadv::new(
- 1001,
- 2, //offset
- &mut rbufs,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(2, aiocb.iovlen());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf0 = vec![0; 4];
- let mut rbuf1 = vec![0; 2];
- let mut rbufs =
- [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)];
- const EXPECT0: &[u8] = b"cdef";
- const EXPECT1: &[u8] = b"12";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- {
- let fd = f.as_raw_fd();
- let mut aior = Box::pin(AioReadv::new(
- fd,
- 2,
- &mut rbufs,
- 0,
- SigevNotify::SigevNone,
- ));
- aior.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aior);
- assert_eq!(err, Ok(()));
- assert_eq!(
- aior.as_mut().aio_return().unwrap(),
- EXPECT0.len() + EXPECT1.len()
- );
- }
- assert_eq!(&EXPECT0, &rbuf0);
- assert_eq!(&EXPECT1, &rbuf1);
- }
-}
-
-mod aio_write {
- use super::*;
-
- #[test]
- fn test_accessors() {
- let wbuf = vec![0; 4];
- let aiocb = AioWrite::new(
- 1001,
- 2, //offset
- &wbuf,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(4, aiocb.nbytes());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- // Tests AioWrite.cancel. We aren't trying to test the OS's implementation,
- // only our bindings. So it's sufficient to check that cancel
- // returned any AioCancelStat value.
- #[test]
- #[cfg_attr(target_env = "musl", ignore)]
- fn cancel() {
- let wbuf: &[u8] = b"CDEF";
-
- let f = tempfile().unwrap();
- let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 0,
- wbuf,
- 0,
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().unwrap();
- let err = aiow.as_mut().error();
- assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS));
-
- aiow.as_mut().cancel().unwrap();
-
- // Wait for aiow to complete, but don't care whether it succeeded
- let _ = poll_aio!(&mut aiow);
- let _ = aiow.as_mut().aio_return();
- }
-
- // Test a simple aio operation with no completion notification. We must
- // poll for completion.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let wbuf = "CDEF".to_string().into_bytes();
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"abCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2,
- &wbuf,
- 0,
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aiow);
- assert_eq!(err, Ok(()));
- assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len());
-
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
- }
-
- // Like ok, but allocates the structure on the stack.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn on_stack() {
- const INITIAL: &[u8] = b"abcdef123456";
- let wbuf = "CDEF".to_string().into_bytes();
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"abCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- &wbuf,
- 0, //priority
- SigevNotify::SigevNone,
- );
- let mut aiow = unsafe { Pin::new_unchecked(&mut aiow) };
- aiow.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aiow);
- assert_eq!(err, Ok(()));
- assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len());
-
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
- }
-
- /// `AioWrite::write` should not modify the `AioCb` object if
- /// `libc::aio_write` returns an error.
- // Skip on Linux, because Linux's AIO implementation can't detect errors
- // synchronously
- #[test]
- #[cfg(any(target_os = "freebsd", target_os = "macos"))]
- fn error() {
- let wbuf = "CDEF".to_string().into_bytes();
- let mut aiow = Box::pin(AioWrite::new(
- 666, // An invalid file descriptor
- 0, //offset
- &wbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().expect_err("assertion failed");
- // Dropping the AioWrite at this point should not panic
- }
-}
-
-#[cfg(target_os = "freebsd")]
-#[cfg(fbsd14)]
-mod aio_writev {
- use std::io::IoSlice;
-
- use super::*;
-
- #[test]
- fn test_accessors() {
- let wbuf0 = vec![0; 4];
- let wbuf1 = vec![0; 8];
- let wbufs = [IoSlice::new(&wbuf0), IoSlice::new(&wbuf1)];
- let aiocb = AioWritev::new(
- 1001,
- 2, //offset
- &wbufs,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(2, aiocb.iovlen());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- // Test a simple aio operation with no completion notification. We must
- // poll for completion.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let wbuf0 = b"BC";
- let wbuf1 = b"DEF";
- let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)];
- let wlen = wbuf0.len() + wbuf1.len();
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"aBCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = Box::pin(AioWritev::new(
- f.as_raw_fd(),
- 1,
- &wbufs,
- 0,
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aiow);
- assert_eq!(err, Ok(()));
- assert_eq!(aiow.as_mut().aio_return().unwrap(), wlen);
-
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
- }
-}
-
-// Test an aio operation with completion delivered by a signal
-#[test]
-#[cfg_attr(
- any(
- all(target_env = "musl", target_arch = "x86_64"),
- target_arch = "mips",
- target_arch = "mips64"
- ),
- ignore
-)]
-fn sigev_signal() {
- let _m = crate::SIGNAL_MTX.lock();
- let sa = SigAction::new(
- SigHandler::Handler(sigfunc),
- SaFlags::SA_RESETHAND,
- SigSet::empty(),
- );
- SIGNALED.store(false, Ordering::Relaxed);
- unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
-
- const INITIAL: &[u8] = b"abcdef123456";
- const WBUF: &[u8] = b"CDEF";
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"abCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- WBUF,
- 0, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 0, //TODO: validate in sigfunc
- },
- ));
- aiow.as_mut().submit().unwrap();
- while !SIGNALED.load(Ordering::Relaxed) {
- thread::sleep(time::Duration::from_millis(10));
- }
-
- assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
-}
-
-// Tests using aio_cancel_all for all outstanding IOs.
-#[test]
-#[cfg_attr(target_env = "musl", ignore)]
-fn test_aio_cancel_all() {
- let wbuf: &[u8] = b"CDEF";
-
- let f = tempfile().unwrap();
- let mut aiocb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 0, //offset
- wbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aiocb.as_mut().submit().unwrap();
- let err = aiocb.as_mut().error();
- assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS));
-
- aio_cancel_all(f.as_raw_fd()).unwrap();
-
- // Wait for aiocb to complete, but don't care whether it succeeded
- let _ = poll_aio!(&mut aiocb);
- let _ = aiocb.as_mut().aio_return();
-}
-
-#[test]
-// On Cirrus on Linux, this test fails due to a glibc bug.
-// https://github.com/nix-rust/nix/issues/1099
-#[cfg_attr(target_os = "linux", ignore)]
-// On Cirrus, aio_suspend is failing with EINVAL
-// https://github.com/nix-rust/nix/issues/1361
-#[cfg_attr(target_os = "macos", ignore)]
-fn test_aio_suspend() {
- const INITIAL: &[u8] = b"abcdef123456";
- const WBUF: &[u8] = b"CDEFG";
- let timeout = TimeSpec::seconds(10);
- let mut rbuf = vec![0; 4];
- let rlen = rbuf.len();
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
-
- let mut wcb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- ));
-
- let mut rcb = Box::pin(AioRead::new(
- f.as_raw_fd(),
- 8, //offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- wcb.as_mut().submit().unwrap();
- rcb.as_mut().submit().unwrap();
- loop {
- {
- let cbbuf = [
- &*wcb as &dyn AsRef<libc::aiocb>,
- &*rcb as &dyn AsRef<libc::aiocb>,
- ];
- let r = aio_suspend(&cbbuf[..], Some(timeout));
- match r {
- Err(Errno::EINTR) => continue,
- Err(e) => panic!("aio_suspend returned {:?}", e),
- Ok(_) => (),
- };
- }
- if rcb.as_mut().error() != Err(Errno::EINPROGRESS)
- && wcb.as_mut().error() != Err(Errno::EINPROGRESS)
- {
- break;
- }
- }
-
- assert_eq!(wcb.as_mut().aio_return().unwrap(), WBUF.len());
- assert_eq!(rcb.as_mut().aio_return().unwrap(), rlen);
-}
diff --git a/vendor/nix/test/sys/test_aio_drop.rs b/vendor/nix/test/sys/test_aio_drop.rs
deleted file mode 100644
index bbe6623fd..000000000
--- a/vendor/nix/test/sys/test_aio_drop.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Test dropping an AioCb that hasn't yet finished.
-// This must happen in its own process, because on OSX this test seems to hose
-// the AIO subsystem and causes subsequent tests to fail
-#[test]
-#[should_panic(expected = "Dropped an in-progress AioCb")]
-#[cfg(all(
- not(target_env = "musl"),
- not(target_env = "uclibc"),
- any(
- target_os = "linux",
- target_os = "ios",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "netbsd"
- )
-))]
-fn test_drop() {
- use nix::sys::aio::*;
- use nix::sys::signal::*;
- use std::os::unix::io::AsRawFd;
- use tempfile::tempfile;
-
- const WBUF: &[u8] = b"CDEF";
-
- let f = tempfile().unwrap();
- f.set_len(6).unwrap();
- let mut aiocb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aiocb.as_mut().submit().unwrap();
-}
diff --git a/vendor/nix/test/sys/test_epoll.rs b/vendor/nix/test/sys/test_epoll.rs
deleted file mode 100644
index 915691595..000000000
--- a/vendor/nix/test/sys/test_epoll.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use nix::errno::Errno;
-use nix::sys::epoll::{epoll_create1, epoll_ctl};
-use nix::sys::epoll::{EpollCreateFlags, EpollEvent, EpollFlags, EpollOp};
-
-#[test]
-pub fn test_epoll_errno() {
- let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
- let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None);
- result.expect_err("assertion failed");
- assert_eq!(result.unwrap_err(), Errno::ENOENT);
-
- let result = epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, None);
- result.expect_err("assertion failed");
- assert_eq!(result.unwrap_err(), Errno::EINVAL);
-}
-
-#[test]
-pub fn test_epoll_ctl() {
- let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
- let mut event =
- EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, 1);
- epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap();
- epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap();
-}
diff --git a/vendor/nix/test/sys/test_inotify.rs b/vendor/nix/test/sys/test_inotify.rs
deleted file mode 100644
index bb5851a90..000000000
--- a/vendor/nix/test/sys/test_inotify.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use nix::errno::Errno;
-use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify};
-use std::ffi::OsString;
-use std::fs::{rename, File};
-
-#[test]
-pub fn test_inotify() {
- let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap();
- let tempdir = tempfile::tempdir().unwrap();
-
- instance
- .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS)
- .unwrap();
-
- let events = instance.read_events();
- assert_eq!(events.unwrap_err(), Errno::EAGAIN);
-
- File::create(tempdir.path().join("test")).unwrap();
-
- let events = instance.read_events().unwrap();
- assert_eq!(events[0].name, Some(OsString::from("test")));
-}
-
-#[test]
-pub fn test_inotify_multi_events() {
- let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap();
- let tempdir = tempfile::tempdir().unwrap();
-
- instance
- .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS)
- .unwrap();
-
- let events = instance.read_events();
- assert_eq!(events.unwrap_err(), Errno::EAGAIN);
-
- File::create(tempdir.path().join("test")).unwrap();
- rename(tempdir.path().join("test"), tempdir.path().join("test2")).unwrap();
-
- // Now there should be 5 events in queue:
- // - IN_CREATE on test
- // - IN_OPEN on test
- // - IN_CLOSE_WRITE on test
- // - IN_MOVED_FROM on test with a cookie
- // - IN_MOVED_TO on test2 with the same cookie
-
- let events = instance.read_events().unwrap();
- assert_eq!(events.len(), 5);
-
- assert_eq!(events[0].mask, AddWatchFlags::IN_CREATE);
- assert_eq!(events[0].name, Some(OsString::from("test")));
-
- assert_eq!(events[1].mask, AddWatchFlags::IN_OPEN);
- assert_eq!(events[1].name, Some(OsString::from("test")));
-
- assert_eq!(events[2].mask, AddWatchFlags::IN_CLOSE_WRITE);
- assert_eq!(events[2].name, Some(OsString::from("test")));
-
- assert_eq!(events[3].mask, AddWatchFlags::IN_MOVED_FROM);
- assert_eq!(events[3].name, Some(OsString::from("test")));
-
- assert_eq!(events[4].mask, AddWatchFlags::IN_MOVED_TO);
- assert_eq!(events[4].name, Some(OsString::from("test2")));
-
- assert_eq!(events[3].cookie, events[4].cookie);
-}
diff --git a/vendor/nix/test/sys/test_ioctl.rs b/vendor/nix/test/sys/test_ioctl.rs
deleted file mode 100644
index 40f60cfdb..000000000
--- a/vendor/nix/test/sys/test_ioctl.rs
+++ /dev/null
@@ -1,376 +0,0 @@
-#![allow(dead_code)]
-
-// Simple tests to ensure macro generated fns compile
-ioctl_none_bad!(do_bad, 0x1234);
-ioctl_read_bad!(do_bad_read, 0x1234, u16);
-ioctl_write_int_bad!(do_bad_write_int, 0x1234);
-ioctl_write_ptr_bad!(do_bad_write_ptr, 0x1234, u8);
-ioctl_readwrite_bad!(do_bad_readwrite, 0x1234, u32);
-ioctl_none!(do_none, 0, 0);
-ioctl_read!(read_test, 0, 0, u32);
-ioctl_write_int!(write_ptr_int, 0, 0);
-ioctl_write_ptr!(write_ptr_u8, 0, 0, u8);
-ioctl_write_ptr!(write_ptr_u32, 0, 0, u32);
-ioctl_write_ptr!(write_ptr_u64, 0, 0, u64);
-ioctl_readwrite!(readwrite_test, 0, 0, u64);
-ioctl_read_buf!(readbuf_test, 0, 0, u32);
-const SPI_IOC_MAGIC: u8 = b'k';
-const SPI_IOC_MESSAGE: u8 = 0;
-ioctl_write_buf!(writebuf_test_consts, SPI_IOC_MAGIC, SPI_IOC_MESSAGE, u8);
-ioctl_write_buf!(writebuf_test_u8, 0, 0, u8);
-ioctl_write_buf!(writebuf_test_u32, 0, 0, u32);
-ioctl_write_buf!(writebuf_test_u64, 0, 0, u64);
-ioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32);
-
-// See C code for source of values for op calculations (does NOT work for mips/powerpc):
-// https://gist.github.com/posborne/83ea6880770a1aef332e
-//
-// TODO: Need a way to compute these constants at test time. Using precomputed
-// values is fragile and needs to be maintained.
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod linux {
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_none() {
- if cfg!(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64"
- )) {
- assert_eq!(request_code_none!(b'q', 10) as u32, 0x2000_710A);
- assert_eq!(request_code_none!(b'a', 255) as u32, 0x2000_61FF);
- } else {
- assert_eq!(request_code_none!(b'q', 10) as u32, 0x0000_710A);
- assert_eq!(request_code_none!(b'a', 255) as u32, 0x0000_61FF);
- }
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_write() {
- if cfg!(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64"
- )) {
- assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x8001_7A0A);
- assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x8200_7A0A);
- } else {
- assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x4001_7A0A);
- assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x4200_7A0A);
- }
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_write_64() {
- if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) {
- assert_eq!(
- request_code_write!(b'z', 10, 1u64 << 32) as u32,
- 0x8000_7A0A
- );
- } else {
- assert_eq!(
- request_code_write!(b'z', 10, 1u64 << 32) as u32,
- 0x4000_7A0A
- );
- }
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_read() {
- if cfg!(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64"
- )) {
- assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x4001_7A0A);
- assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x4200_7A0A);
- } else {
- assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x8001_7A0A);
- assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x8200_7A0A);
- }
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_64() {
- if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) {
- assert_eq!(
- request_code_read!(b'z', 10, 1u64 << 32) as u32,
- 0x4000_7A0A
- );
- } else {
- assert_eq!(
- request_code_read!(b'z', 10, 1u64 << 32) as u32,
- 0x8000_7A0A
- );
- }
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_read_write() {
- assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A);
- assert_eq!(request_code_readwrite!(b'z', 10, 512) as u32, 0xC200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_write_64() {
- assert_eq!(
- request_code_readwrite!(b'z', 10, 1u64 << 32) as u32,
- 0xC000_7A0A
- );
- }
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-mod bsd {
- #[test]
- fn test_op_none() {
- assert_eq!(request_code_none!(b'q', 10), 0x2000_710A);
- assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF);
- }
-
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[test]
- fn test_op_write_int() {
- assert_eq!(request_code_write_int!(b'v', 4), 0x2004_7604);
- assert_eq!(request_code_write_int!(b'p', 2), 0x2004_7002);
- }
-
- #[test]
- fn test_op_write() {
- assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A);
- assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_write_64() {
- assert_eq!(request_code_write!(b'z', 10, 1u64 << 32), 0x8000_7A0A);
- }
-
- #[test]
- fn test_op_read() {
- assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A);
- assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_64() {
- assert_eq!(request_code_read!(b'z', 10, 1u64 << 32), 0x4000_7A0A);
- }
-
- #[test]
- fn test_op_read_write() {
- assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A);
- assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_write_64() {
- assert_eq!(request_code_readwrite!(b'z', 10, 1u64 << 32), 0xC000_7A0A);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod linux_ioctls {
- use std::mem;
- use std::os::unix::io::AsRawFd;
-
- use libc::{termios, TCGETS, TCSBRK, TCSETS, TIOCNXCL};
- use tempfile::tempfile;
-
- use nix::errno::Errno;
-
- ioctl_none_bad!(tiocnxcl, TIOCNXCL);
- #[test]
- fn test_ioctl_none_bad() {
- let file = tempfile().unwrap();
- let res = unsafe { tiocnxcl(file.as_raw_fd()) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_read_bad!(tcgets, TCGETS, termios);
- #[test]
- fn test_ioctl_read_bad() {
- let file = tempfile().unwrap();
- let mut termios = unsafe { mem::zeroed() };
- let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_write_int_bad!(tcsbrk, TCSBRK);
- #[test]
- fn test_ioctl_write_int_bad() {
- let file = tempfile().unwrap();
- let res = unsafe { tcsbrk(file.as_raw_fd(), 0) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_write_ptr_bad!(tcsets, TCSETS, termios);
- #[test]
- fn test_ioctl_write_ptr_bad() {
- let file = tempfile().unwrap();
- let termios: termios = unsafe { mem::zeroed() };
- let res = unsafe { tcsets(file.as_raw_fd(), &termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- // FIXME: Find a suitable example for `ioctl_readwrite_bad`
-
- // From linux/videodev2.h
- ioctl_none!(log_status, b'V', 70);
- #[test]
- fn test_ioctl_none() {
- let file = tempfile().unwrap();
- let res = unsafe { log_status(file.as_raw_fd()) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- #[repr(C)]
- pub struct v4l2_audio {
- index: u32,
- name: [u8; 32],
- capability: u32,
- mode: u32,
- reserved: [u32; 2],
- }
-
- // From linux/videodev2.h
- ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
- #[test]
- fn test_ioctl_write_ptr() {
- let file = tempfile().unwrap();
- let data: v4l2_audio = unsafe { mem::zeroed() };
- let res = unsafe { s_audio(file.as_raw_fd(), &data) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // From linux/net/bluetooth/hci_sock.h
- const HCI_IOC_MAGIC: u8 = b'H';
- const HCI_IOC_HCIDEVUP: u8 = 201;
- ioctl_write_int!(hcidevup, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
- #[test]
- fn test_ioctl_write_int() {
- let file = tempfile().unwrap();
- let res = unsafe { hcidevup(file.as_raw_fd(), 0) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // From linux/videodev2.h
- ioctl_read!(g_audio, b'V', 33, v4l2_audio);
- #[test]
- fn test_ioctl_read() {
- let file = tempfile().unwrap();
- let mut data: v4l2_audio = unsafe { mem::zeroed() };
- let res = unsafe { g_audio(file.as_raw_fd(), &mut data) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // From linux/videodev2.h
- ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
- #[test]
- fn test_ioctl_readwrite() {
- let file = tempfile().unwrap();
- let mut data: v4l2_audio = unsafe { mem::zeroed() };
- let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // FIXME: Find a suitable example for `ioctl_read_buf`.
-
- #[repr(C)]
- pub struct spi_ioc_transfer {
- tx_buf: u64,
- rx_buf: u64,
- len: u32,
- speed_hz: u32,
- delay_usecs: u16,
- bits_per_word: u8,
- cs_change: u8,
- tx_nbits: u8,
- rx_nbits: u8,
- pad: u16,
- }
-
- // From linux/spi/spidev.h
- ioctl_write_buf!(
- spi_ioc_message,
- super::SPI_IOC_MAGIC,
- super::SPI_IOC_MESSAGE,
- spi_ioc_transfer
- );
- #[test]
- fn test_ioctl_write_buf() {
- let file = tempfile().unwrap();
- let data: [spi_ioc_transfer; 4] = unsafe { mem::zeroed() };
- let res = unsafe { spi_ioc_message(file.as_raw_fd(), &data[..]) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // FIXME: Find a suitable example for `ioctl_readwrite_buf`.
-}
-
-#[cfg(target_os = "freebsd")]
-mod freebsd_ioctls {
- use std::mem;
- use std::os::unix::io::AsRawFd;
-
- use libc::termios;
- use tempfile::tempfile;
-
- use nix::errno::Errno;
-
- // From sys/sys/ttycom.h
- const TTY_IOC_MAGIC: u8 = b't';
- const TTY_IOC_TYPE_NXCL: u8 = 14;
- const TTY_IOC_TYPE_GETA: u8 = 19;
- const TTY_IOC_TYPE_SETA: u8 = 20;
-
- ioctl_none!(tiocnxcl, TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL);
- #[test]
- fn test_ioctl_none() {
- let file = tempfile().unwrap();
- let res = unsafe { tiocnxcl(file.as_raw_fd()) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_read!(tiocgeta, TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA, termios);
- #[test]
- fn test_ioctl_read() {
- let file = tempfile().unwrap();
- let mut termios = unsafe { mem::zeroed() };
- let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_write_ptr!(tiocseta, TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA, termios);
- #[test]
- fn test_ioctl_write_ptr() {
- let file = tempfile().unwrap();
- let termios: termios = unsafe { mem::zeroed() };
- let res = unsafe { tiocseta(file.as_raw_fd(), &termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-}
diff --git a/vendor/nix/test/sys/test_mman.rs b/vendor/nix/test/sys/test_mman.rs
deleted file mode 100644
index e748427bc..000000000
--- a/vendor/nix/test/sys/test_mman.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use nix::sys::mman::{mmap, MapFlags, ProtFlags};
-use std::num::NonZeroUsize;
-
-#[test]
-fn test_mmap_anonymous() {
- unsafe {
- let ptr = mmap(
- None,
- NonZeroUsize::new(1).unwrap(),
- ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
- MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
- -1,
- 0,
- )
- .unwrap() as *mut u8;
- assert_eq!(*ptr, 0x00u8);
- *ptr = 0xffu8;
- assert_eq!(*ptr, 0xffu8);
- }
-}
-
-#[test]
-#[cfg(any(target_os = "linux", target_os = "netbsd"))]
-fn test_mremap_grow() {
- use nix::libc::{c_void, size_t};
- use nix::sys::mman::{mremap, MRemapFlags};
-
- const ONE_K: size_t = 1024;
- let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
-
- let slice: &mut [u8] = unsafe {
- let mem = mmap(
- None,
- one_k_non_zero,
- ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
- MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
- -1,
- 0,
- )
- .unwrap();
- std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
- };
- assert_eq!(slice[ONE_K - 1], 0x00);
- slice[ONE_K - 1] = 0xFF;
- assert_eq!(slice[ONE_K - 1], 0xFF);
-
- let slice: &mut [u8] = unsafe {
- #[cfg(target_os = "linux")]
- let mem = mremap(
- slice.as_mut_ptr() as *mut c_void,
- ONE_K,
- 10 * ONE_K,
- MRemapFlags::MREMAP_MAYMOVE,
- None,
- )
- .unwrap();
- #[cfg(target_os = "netbsd")]
- let mem = mremap(
- slice.as_mut_ptr() as *mut c_void,
- ONE_K,
- 10 * ONE_K,
- MRemapFlags::MAP_REMAPDUP,
- None,
- )
- .unwrap();
- std::slice::from_raw_parts_mut(mem as *mut u8, 10 * ONE_K)
- };
-
- // The first KB should still have the old data in it.
- assert_eq!(slice[ONE_K - 1], 0xFF);
-
- // The additional range should be zero-init'd and accessible.
- assert_eq!(slice[10 * ONE_K - 1], 0x00);
- slice[10 * ONE_K - 1] = 0xFF;
- assert_eq!(slice[10 * ONE_K - 1], 0xFF);
-}
-
-#[test]
-#[cfg(any(target_os = "linux", target_os = "netbsd"))]
-// Segfaults for unknown reasons under QEMU for 32-bit targets
-#[cfg_attr(all(target_pointer_width = "32", qemu), ignore)]
-fn test_mremap_shrink() {
- use nix::libc::{c_void, size_t};
- use nix::sys::mman::{mremap, MRemapFlags};
- use std::num::NonZeroUsize;
-
- const ONE_K: size_t = 1024;
- let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
- let slice: &mut [u8] = unsafe {
- let mem = mmap(
- None,
- ten_one_k,
- ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
- MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
- -1,
- 0,
- )
- .unwrap();
- std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
- };
- assert_eq!(slice[ONE_K - 1], 0x00);
- slice[ONE_K - 1] = 0xFF;
- assert_eq!(slice[ONE_K - 1], 0xFF);
-
- let slice: &mut [u8] = unsafe {
- let mem = mremap(
- slice.as_mut_ptr() as *mut c_void,
- ten_one_k.into(),
- ONE_K,
- MRemapFlags::empty(),
- None,
- )
- .unwrap();
- // Since we didn't supply MREMAP_MAYMOVE, the address should be the
- // same.
- assert_eq!(mem, slice.as_mut_ptr() as *mut c_void);
- std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
- };
-
- // The first KB should still be accessible and have the old data in it.
- assert_eq!(slice[ONE_K - 1], 0xFF);
-}
diff --git a/vendor/nix/test/sys/test_pthread.rs b/vendor/nix/test/sys/test_pthread.rs
deleted file mode 100644
index ce048bae6..000000000
--- a/vendor/nix/test/sys/test_pthread.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use nix::sys::pthread::*;
-
-#[cfg(any(target_env = "musl", target_os = "redox"))]
-#[test]
-fn test_pthread_self() {
- let tid = pthread_self();
- assert!(!tid.is_null());
-}
-
-#[cfg(not(any(target_env = "musl", target_os = "redox")))]
-#[test]
-fn test_pthread_self() {
- let tid = pthread_self();
- assert_ne!(tid, 0);
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_pthread_kill_none() {
- pthread_kill(pthread_self(), None)
- .expect("Should be able to send signal to my thread.");
-}
diff --git a/vendor/nix/test/sys/test_ptrace.rs b/vendor/nix/test/sys/test_ptrace.rs
deleted file mode 100644
index 530560fe1..000000000
--- a/vendor/nix/test/sys/test_ptrace.rs
+++ /dev/null
@@ -1,275 +0,0 @@
-#[cfg(all(
- target_os = "linux",
- any(target_arch = "x86_64", target_arch = "x86"),
- target_env = "gnu"
-))]
-use memoffset::offset_of;
-use nix::errno::Errno;
-use nix::sys::ptrace;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use nix::sys::ptrace::Options;
-use nix::unistd::getpid;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use std::mem;
-
-use crate::*;
-
-#[test]
-fn test_ptrace() {
- // Just make sure ptrace can be called at all, for now.
- // FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS
- require_capability!("test_ptrace", CAP_SYS_PTRACE);
- let err = ptrace::attach(getpid()).unwrap_err();
- assert!(
- err == Errno::EPERM || err == Errno::EINVAL || err == Errno::ENOSYS
- );
-}
-
-// Just make sure ptrace_setoptions can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_setoptions() {
- require_capability!("test_ptrace_setoptions", CAP_SYS_PTRACE);
- let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD)
- .unwrap_err();
- assert_ne!(err, Errno::EOPNOTSUPP);
-}
-
-// Just make sure ptrace_getevent can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_getevent() {
- require_capability!("test_ptrace_getevent", CAP_SYS_PTRACE);
- let err = ptrace::getevent(getpid()).unwrap_err();
- assert_ne!(err, Errno::EOPNOTSUPP);
-}
-
-// Just make sure ptrace_getsiginfo can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_getsiginfo() {
- require_capability!("test_ptrace_getsiginfo", CAP_SYS_PTRACE);
- if let Err(Errno::EOPNOTSUPP) = ptrace::getsiginfo(getpid()) {
- panic!("ptrace_getsiginfo returns Errno::EOPNOTSUPP!");
- }
-}
-
-// Just make sure ptrace_setsiginfo can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_setsiginfo() {
- require_capability!("test_ptrace_setsiginfo", CAP_SYS_PTRACE);
- let siginfo = unsafe { mem::zeroed() };
- if let Err(Errno::EOPNOTSUPP) = ptrace::setsiginfo(getpid(), &siginfo) {
- panic!("ptrace_setsiginfo returns Errno::EOPNOTSUPP!");
- }
-}
-
-#[test]
-fn test_ptrace_cont() {
- use nix::sys::ptrace;
- use nix::sys::signal::{raise, Signal};
- use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus};
- use nix::unistd::fork;
- use nix::unistd::ForkResult::*;
-
- require_capability!("test_ptrace_cont", CAP_SYS_PTRACE);
-
- let _m = crate::FORK_MTX.lock();
-
- // FIXME: qemu-user doesn't implement ptrace on all architectures
- // and returns ENOSYS in this case.
- // We (ab)use this behavior to detect the affected platforms
- // and skip the test then.
- // On valid platforms the ptrace call should return Errno::EPERM, this
- // is already tested by `test_ptrace`.
- let err = ptrace::attach(getpid()).unwrap_err();
- if err == Errno::ENOSYS {
- return;
- }
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- ptrace::traceme().unwrap();
- // As recommended by ptrace(2), raise SIGTRAP to pause the child
- // until the parent is ready to continue
- loop {
- raise(Signal::SIGTRAP).unwrap();
- }
- }
- Parent { child } => {
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGTRAP))
- );
- ptrace::cont(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGTRAP))
- );
- ptrace::cont(child, Some(Signal::SIGKILL)).unwrap();
- match waitpid(child, None) {
- Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _))
- if pid == child =>
- {
- // FIXME It's been observed on some systems (apple) the
- // tracee may not be killed but remain as a zombie process
- // affecting other wait based tests. Add an extra kill just
- // to make sure there are no zombies.
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() {
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- }
- }
- _ => panic!("The process should have been killed"),
- }
- }
- }
-}
-
-#[cfg(target_os = "linux")]
-#[test]
-fn test_ptrace_interrupt() {
- use nix::sys::ptrace;
- use nix::sys::signal::Signal;
- use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus};
- use nix::unistd::fork;
- use nix::unistd::ForkResult::*;
- use std::thread::sleep;
- use std::time::Duration;
-
- require_capability!("test_ptrace_interrupt", CAP_SYS_PTRACE);
-
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => loop {
- sleep(Duration::from_millis(1000));
- },
- Parent { child } => {
- ptrace::seize(child, ptrace::Options::PTRACE_O_TRACESYSGOOD)
- .unwrap();
- ptrace::interrupt(child).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceEvent(child, Signal::SIGTRAP, 128))
- );
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceSyscall(child))
- );
- ptrace::detach(child, Some(Signal::SIGKILL)).unwrap();
- match waitpid(child, None) {
- Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _))
- if pid == child =>
- {
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() {
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- }
- }
- _ => panic!("The process should have been killed"),
- }
- }
- }
-}
-
-// ptrace::{setoptions, getregs} are only available in these platforms
-#[cfg(all(
- target_os = "linux",
- any(target_arch = "x86_64", target_arch = "x86"),
- target_env = "gnu"
-))]
-#[test]
-fn test_ptrace_syscall() {
- use nix::sys::ptrace;
- use nix::sys::signal::kill;
- use nix::sys::signal::Signal;
- use nix::sys::wait::{waitpid, WaitStatus};
- use nix::unistd::fork;
- use nix::unistd::getpid;
- use nix::unistd::ForkResult::*;
-
- require_capability!("test_ptrace_syscall", CAP_SYS_PTRACE);
-
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- ptrace::traceme().unwrap();
- // first sigstop until parent is ready to continue
- let pid = getpid();
- kill(pid, Signal::SIGSTOP).unwrap();
- kill(pid, Signal::SIGTERM).unwrap();
- unsafe {
- ::libc::_exit(0);
- }
- }
-
- Parent { child } => {
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGSTOP))
- );
-
- // set this option to recognize syscall-stops
- ptrace::setoptions(child, ptrace::Options::PTRACE_O_TRACESYSGOOD)
- .unwrap();
-
- #[cfg(target_arch = "x86_64")]
- let get_syscall_id =
- || ptrace::getregs(child).unwrap().orig_rax as libc::c_long;
-
- #[cfg(target_arch = "x86")]
- let get_syscall_id =
- || ptrace::getregs(child).unwrap().orig_eax as libc::c_long;
-
- // this duplicates `get_syscall_id` for the purpose of testing `ptrace::read_user`.
- #[cfg(target_arch = "x86_64")]
- let rax_offset = offset_of!(libc::user_regs_struct, orig_rax);
- #[cfg(target_arch = "x86")]
- let rax_offset = offset_of!(libc::user_regs_struct, orig_eax);
-
- let get_syscall_from_user_area = || {
- // Find the offset of `user.regs.rax` (or `user.regs.eax` for x86)
- let rax_offset = offset_of!(libc::user, regs) + rax_offset;
- ptrace::read_user(child, rax_offset as _).unwrap()
- as libc::c_long
- };
-
- // kill entry
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceSyscall(child))
- );
- assert_eq!(get_syscall_id(), ::libc::SYS_kill);
- assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill);
-
- // kill exit
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceSyscall(child))
- );
- assert_eq!(get_syscall_id(), ::libc::SYS_kill);
- assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill);
-
- // receive signal
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGTERM))
- );
-
- // inject signal
- ptrace::syscall(child, Signal::SIGTERM).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Signaled(child, Signal::SIGTERM, false))
- );
- }
- }
-}
diff --git a/vendor/nix/test/sys/test_select.rs b/vendor/nix/test/sys/test_select.rs
deleted file mode 100644
index 40bda4d90..000000000
--- a/vendor/nix/test/sys/test_select.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-use nix::sys::select::*;
-use nix::sys::signal::SigSet;
-use nix::sys::time::{TimeSpec, TimeValLike};
-use nix::unistd::{pipe, write};
-
-#[test]
-pub fn test_pselect() {
- let _mtx = crate::SIGNAL_MTX.lock();
-
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let timeout = TimeSpec::seconds(10);
- let sigmask = SigSet::empty();
- assert_eq!(
- 1,
- pselect(None, &mut fd_set, None, None, &timeout, &sigmask).unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
-}
-
-#[test]
-pub fn test_pselect_nfds2() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let timeout = TimeSpec::seconds(10);
- assert_eq!(
- 1,
- pselect(
- ::std::cmp::max(r1, r2) + 1,
- &mut fd_set,
- None,
- None,
- &timeout,
- None
- )
- .unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
-}
-
-macro_rules! generate_fdset_bad_fd_tests {
- ($fd:expr, $($method:ident),* $(,)?) => {
- $(
- #[test]
- #[should_panic]
- fn $method() {
- FdSet::new().$method($fd);
- }
- )*
- }
-}
-
-mod test_fdset_negative_fd {
- use super::*;
- generate_fdset_bad_fd_tests!(-1, insert, remove, contains);
-}
-
-mod test_fdset_too_large_fd {
- use super::*;
- use std::convert::TryInto;
- generate_fdset_bad_fd_tests!(
- FD_SETSIZE.try_into().unwrap(),
- insert,
- remove,
- contains,
- );
-}
diff --git a/vendor/nix/test/sys/test_signal.rs b/vendor/nix/test/sys/test_signal.rs
deleted file mode 100644
index 3ad14f40c..000000000
--- a/vendor/nix/test/sys/test_signal.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-#[cfg(not(target_os = "redox"))]
-use nix::errno::Errno;
-use nix::sys::signal::*;
-use nix::unistd::*;
-use std::convert::TryFrom;
-use std::sync::atomic::{AtomicBool, Ordering};
-
-#[test]
-fn test_kill_none() {
- kill(getpid(), None).expect("Should be able to send signal to myself.");
-}
-
-#[test]
-#[cfg(not(target_os = "fuchsia"))]
-fn test_killpg_none() {
- killpg(getpgrp(), None)
- .expect("Should be able to send signal to my process group.");
-}
-
-#[test]
-fn test_old_sigaction_flags() {
- let _m = crate::SIGNAL_MTX.lock();
-
- extern "C" fn handler(_: ::libc::c_int) {}
- let act = SigAction::new(
- SigHandler::Handler(handler),
- SaFlags::empty(),
- SigSet::empty(),
- );
- let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
- let _flags = oact.flags();
- let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
- let _flags = oact.flags();
-}
-
-#[test]
-fn test_sigprocmask_noop() {
- sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
- .expect("this should be an effective noop");
-}
-
-#[test]
-fn test_sigprocmask() {
- let _m = crate::SIGNAL_MTX.lock();
-
- // This needs to be a signal that rust doesn't use in the test harness.
- const SIGNAL: Signal = Signal::SIGCHLD;
-
- let mut old_signal_set = SigSet::empty();
- sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
- .expect("expect to be able to retrieve old signals");
-
- // Make sure the old set doesn't contain the signal, otherwise the following
- // test don't make sense.
- assert!(
- !old_signal_set.contains(SIGNAL),
- "the {:?} signal is already blocked, please change to a \
- different one",
- SIGNAL
- );
-
- // Now block the signal.
- let mut signal_set = SigSet::empty();
- signal_set.add(SIGNAL);
- sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
- .expect("expect to be able to block signals");
-
- // And test it again, to make sure the change was effective.
- old_signal_set.clear();
- sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
- .expect("expect to be able to retrieve old signals");
- assert!(
- old_signal_set.contains(SIGNAL),
- "expected the {:?} to be blocked",
- SIGNAL
- );
-
- // Reset the signal.
- sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
- .expect("expect to be able to block signals");
-}
-
-lazy_static! {
- static ref SIGNALED: AtomicBool = AtomicBool::new(false);
-}
-
-extern "C" fn test_sigaction_handler(signal: libc::c_int) {
- let signal = Signal::try_from(signal).unwrap();
- SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
-}
-
-#[cfg(not(target_os = "redox"))]
-extern "C" fn test_sigaction_action(
- _: libc::c_int,
- _: *mut libc::siginfo_t,
- _: *mut libc::c_void,
-) {
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_signal_sigaction() {
- let _m = crate::SIGNAL_MTX.lock();
-
- let action_handler = SigHandler::SigAction(test_sigaction_action);
- assert_eq!(
- unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(),
- Errno::ENOTSUP
- );
-}
-
-#[test]
-fn test_signal() {
- let _m = crate::SIGNAL_MTX.lock();
-
- unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
- raise(Signal::SIGINT).unwrap();
- assert_eq!(
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
- SigHandler::SigIgn
- );
-
- let handler = SigHandler::Handler(test_sigaction_handler);
- assert_eq!(
- unsafe { signal(Signal::SIGINT, handler) }.unwrap(),
- SigHandler::SigDfl
- );
- raise(Signal::SIGINT).unwrap();
- assert!(SIGNALED.load(Ordering::Relaxed));
-
- #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
- assert_eq!(
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
- handler
- );
-
- // System V based OSes (e.g. illumos and Solaris) always resets the
- // disposition to SIG_DFL prior to calling the signal handler
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- assert_eq!(
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
- SigHandler::SigDfl
- );
-
- // Restore default signal handler
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap();
-}
diff --git a/vendor/nix/test/sys/test_signalfd.rs b/vendor/nix/test/sys/test_signalfd.rs
deleted file mode 100644
index 87153c957..000000000
--- a/vendor/nix/test/sys/test_signalfd.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use std::convert::TryFrom;
-
-#[test]
-fn test_signalfd() {
- use nix::sys::signal::{self, raise, SigSet, Signal};
- use nix::sys::signalfd::SignalFd;
-
- // Grab the mutex for altering signals so we don't interfere with other tests.
- let _m = crate::SIGNAL_MTX.lock();
-
- // Block the SIGUSR1 signal from automatic processing for this thread
- let mut mask = SigSet::empty();
- mask.add(signal::SIGUSR1);
- mask.thread_block().unwrap();
-
- let mut fd = SignalFd::new(&mask).unwrap();
-
- // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
- // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
- // cargo test session. Instead use `raise` which does the correct thing by default.
- raise(signal::SIGUSR1).expect("Error: raise(SIGUSR1) failed");
-
- // And now catch that same signal.
- let res = fd.read_signal().unwrap().unwrap();
- let signo = Signal::try_from(res.ssi_signo as i32).unwrap();
- assert_eq!(signo, signal::SIGUSR1);
-}
diff --git a/vendor/nix/test/sys/test_socket.rs b/vendor/nix/test/sys/test_socket.rs
deleted file mode 100644
index 5adc77ed6..000000000
--- a/vendor/nix/test/sys/test_socket.rs
+++ /dev/null
@@ -1,2628 +0,0 @@
-#[cfg(any(target_os = "linux", target_os = "android"))]
-use crate::*;
-use libc::{c_char, sockaddr_storage};
-#[allow(deprecated)]
-use nix::sys::socket::InetAddr;
-use nix::sys::socket::{
- getsockname, sockaddr, sockaddr_in6, AddressFamily, UnixAddr,
-};
-use std::collections::hash_map::DefaultHasher;
-use std::hash::{Hash, Hasher};
-use std::mem::{self, MaybeUninit};
-use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
-use std::os::unix::io::RawFd;
-use std::path::Path;
-use std::slice;
-use std::str::FromStr;
-
-#[allow(deprecated)]
-#[test]
-pub fn test_inetv4_addr_to_sock_addr() {
- let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
- let addr = InetAddr::from_std(&actual);
-
- match addr {
- InetAddr::V4(addr) => {
- let ip: u32 = 0x7f00_0001;
- let port: u16 = 3000;
- let saddr = addr.sin_addr.s_addr;
-
- assert_eq!(saddr, ip.to_be());
- assert_eq!(addr.sin_port, port.to_be());
- }
- _ => panic!("nope"),
- }
-
- assert_eq!(addr.to_string(), "127.0.0.1:3000");
-
- let inet = addr.to_std();
- assert_eq!(actual, inet);
-}
-
-#[allow(deprecated)]
-#[test]
-pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() {
- use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr};
-
- let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
- let addr = InetAddr::from_std(&actual);
- let sockaddr = SockAddr::new_inet(addr);
-
- let (storage, ffi_size) = {
- let mut storage = MaybeUninit::<sockaddr_storage>::zeroed();
- let storage_ptr = storage.as_mut_ptr().cast::<sockaddr>();
- let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
- assert_eq!(mem::size_of::<sockaddr>(), ffi_size as usize);
- unsafe {
- storage_ptr.copy_from_nonoverlapping(ffi_ptr as *const sockaddr, 1);
- (storage.assume_init(), ffi_size)
- }
- };
-
- let from_storage =
- sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap();
- assert_eq!(from_storage, sockaddr);
- let from_storage =
- sockaddr_storage_to_addr(&storage, mem::size_of::<sockaddr_storage>())
- .unwrap();
- assert_eq!(from_storage, sockaddr);
-}
-
-#[cfg(any(target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_timestamping() {
- use nix::sys::socket::{
- recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping,
- ControlMessageOwned, 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,
- )
- .expect("send socket failed");
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- nix::sys::socket::bind(rsock, &sock_addr).unwrap();
-
- setsockopt(rsock, Timestamping, &TimestampingFlag::all()).unwrap();
-
- let sbuf = [0u8; 2048];
- let mut rbuf = [0u8; 2048];
- let flags = MsgFlags::empty();
- let iov1 = [IoSlice::new(&sbuf)];
- let mut iov2 = [IoSliceMut::new(&mut rbuf)];
-
- let mut cmsg = cmsg_space!(nix::sys::socket::Timestamps);
- sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap();
- let recv = recvmsg::<()>(rsock, &mut iov2, Some(&mut cmsg), flags).unwrap();
-
- let mut ts = None;
- for c in recv.cmsgs() {
- if let ControlMessageOwned::ScmTimestampsns(timestamps) = c {
- ts = Some(timestamps.system);
- }
- }
- let ts = ts.expect("ScmTimestampns is present");
- let sys_time =
- ::nix::time::clock_gettime(::nix::time::ClockId::CLOCK_REALTIME)
- .unwrap();
- let diff = if ts > sys_time {
- ts - sys_time
- } else {
- sys_time - ts
- };
- assert!(std::time::Duration::from(diff).as_secs() < 60);
-}
-
-#[allow(deprecated)]
-#[test]
-pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() {
- use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr};
-
- let port: u16 = 3000;
- let flowinfo: u32 = 1;
- let scope_id: u32 = 2;
- let ip: Ipv6Addr = "fe80::1".parse().unwrap();
-
- let actual =
- SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id));
- let addr = InetAddr::from_std(&actual);
- let sockaddr = SockAddr::new_inet(addr);
-
- let (storage, ffi_size) = {
- let mut storage = MaybeUninit::<sockaddr_storage>::zeroed();
- let storage_ptr = storage.as_mut_ptr().cast::<sockaddr_in6>();
- let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
- assert_eq!(mem::size_of::<sockaddr_in6>(), ffi_size as usize);
- unsafe {
- storage_ptr.copy_from_nonoverlapping(
- (ffi_ptr as *const sockaddr).cast::<sockaddr_in6>(),
- 1,
- );
- (storage.assume_init(), ffi_size)
- }
- };
-
- let from_storage =
- sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap();
- assert_eq!(from_storage, sockaddr);
- let from_storage =
- sockaddr_storage_to_addr(&storage, mem::size_of::<sockaddr_storage>())
- .unwrap();
- assert_eq!(from_storage, sockaddr);
-}
-
-#[test]
-pub fn test_path_to_sock_addr() {
- let path = "/foo/bar";
- let actual = Path::new(path);
- let addr = UnixAddr::new(actual).unwrap();
-
- let expect: &[c_char] = unsafe {
- slice::from_raw_parts(path.as_ptr() as *const c_char, path.len())
- };
- assert_eq!(unsafe { &(*addr.as_ptr()).sun_path[..8] }, expect);
-
- assert_eq!(addr.path(), Some(actual));
-}
-
-fn calculate_hash<T: Hash>(t: &T) -> u64 {
- let mut s = DefaultHasher::new();
- t.hash(&mut s);
- s.finish()
-}
-
-#[test]
-pub fn test_addr_equality_path() {
- let path = "/foo/bar";
- let actual = Path::new(path);
- let addr1 = UnixAddr::new(actual).unwrap();
- let mut addr2 = addr1;
-
- unsafe { (*addr2.as_mut_ptr()).sun_path[10] = 127 };
-
- assert_eq!(addr1, addr2);
- assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_abstract_sun_path_too_long() {
- let name = String::from("nix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0testttttnix\0abstract\0test\0make\0sure\0this\0is\0long\0enough");
- let addr = UnixAddr::new_abstract(name.as_bytes());
- addr.expect_err("assertion failed");
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_addr_equality_abstract() {
- let name = String::from("nix\0abstract\0test");
- let addr1 = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let mut addr2 = addr1;
-
- assert_eq!(addr1, addr2);
- assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
-
- unsafe { (*addr2.as_mut_ptr()).sun_path[17] = 127 };
- assert_ne!(addr1, addr2);
- assert_ne!(calculate_hash(&addr1), calculate_hash(&addr2));
-}
-
-// Test getting/setting abstract addresses (without unix socket creation)
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_abstract_uds_addr() {
- let empty = String::new();
- let addr = UnixAddr::new_abstract(empty.as_bytes()).unwrap();
- let sun_path: [u8; 0] = [];
- assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
-
- let name = String::from("nix\0abstract\0test");
- let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let sun_path = [
- 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101,
- 115, 116,
- ];
- assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
- assert_eq!(addr.path(), None);
-
- // Internally, name is null-prefixed (abstract namespace)
- assert_eq!(unsafe { (*addr.as_ptr()).sun_path[0] }, 0);
-}
-
-// Test getting an unnamed address (without unix socket creation)
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_unnamed_uds_addr() {
- use crate::nix::sys::socket::SockaddrLike;
-
- let addr = UnixAddr::new_unnamed();
-
- assert!(addr.is_unnamed());
- assert_eq!(addr.len(), 2);
- assert!(addr.path().is_none());
- assert_eq!(addr.path_len(), 0);
-
- assert!(addr.as_abstract().is_none());
-}
-
-#[test]
-pub fn test_getsockname() {
- use nix::sys::socket::bind;
- use nix::sys::socket::{socket, AddressFamily, SockFlag, SockType};
-
- let tempdir = tempfile::tempdir().unwrap();
- let sockname = tempdir.path().join("sock");
- let sock = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
- let sockaddr = UnixAddr::new(&sockname).unwrap();
- bind(sock, &sockaddr).expect("bind failed");
- assert_eq!(sockaddr, getsockname(sock).expect("getsockname failed"));
-}
-
-#[test]
-pub fn test_socketpair() {
- use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
- use nix::unistd::{read, write};
-
- let (fd1, fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- write(fd1, b"hello").unwrap();
- let mut buf = [0; 5];
- read(fd2, &mut buf).unwrap();
-
- assert_eq!(&buf[..], b"hello");
-}
-
-#[test]
-pub fn test_std_conversions() {
- use nix::sys::socket::*;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
- assert_eq!(std_sa, sock_addr.into());
-
- let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap();
- let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa);
- assert_eq!(std_sa, sock_addr.into());
-}
-
-mod recvfrom {
- use super::*;
- use nix::sys::socket::*;
- use nix::{errno::Errno, Result};
- use std::thread;
-
- const MSG: &[u8] = b"Hello, World!";
-
- fn sendrecv<Fs, Fr>(
- rsock: RawFd,
- ssock: RawFd,
- f_send: Fs,
- mut f_recv: Fr,
- ) -> Option<SockaddrStorage>
- where
- Fs: Fn(RawFd, &[u8], MsgFlags) -> Result<usize> + Send + 'static,
- Fr: FnMut(usize, Option<SockaddrStorage>),
- {
- let mut buf: [u8; 13] = [0u8; 13];
- let mut l = 0;
- let mut from = None;
-
- let send_thread = thread::spawn(move || {
- let mut l = 0;
- while l < std::mem::size_of_val(MSG) {
- l += f_send(ssock, &MSG[l..], MsgFlags::empty()).unwrap();
- }
- });
-
- while l < std::mem::size_of_val(MSG) {
- let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap();
- f_recv(len, from_);
- from = from_;
- l += len;
- }
- assert_eq!(&buf, MSG);
- send_thread.join().unwrap();
- from
- }
-
- #[test]
- pub fn stream() {
- let (fd2, fd1) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- // Ignore from for stream sockets
- let _ = sendrecv(fd1, fd2, send, |_, _| {});
- }
-
- #[test]
- pub fn udp() {
- let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- let from = sendrecv(
- rsock,
- ssock,
- move |s, m, flags| sendto(s, m, &sock_addr, flags),
- |_, _| {},
- );
- // UDP sockets should set the from address
- assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap());
- }
-
- #[cfg(target_os = "linux")]
- mod udp_offload {
- use super::*;
- use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment};
- use std::io::IoSlice;
-
- #[test]
- // Disable the test under emulation because it fails in Cirrus-CI. Lack
- // of QEMU support is suspected.
- #[cfg_attr(qemu, ignore)]
- pub fn gso() {
- require_kernel_version!(udp_offload::gso, ">= 4.18");
-
- // In this test, we send the data and provide a GSO segment size.
- // Since we are sending the buffer of size 13, six UDP packets
- // with size 2 and two UDP packet with size 1 will be sent.
- let segment_size: u16 = 2;
-
- let sock_addr = SockaddrIn::new(127, 0, 0, 1, 6791);
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- setsockopt(rsock, UdpGsoSegment, &(segment_size as _))
- .expect("setsockopt UDP_SEGMENT failed");
-
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let mut num_packets_received: i32 = 0;
-
- sendrecv(
- rsock,
- ssock,
- move |s, m, flags| {
- let iov = [IoSlice::new(m)];
- let cmsg = ControlMessage::UdpGsoSegments(&segment_size);
- sendmsg(s, &iov, &[cmsg], flags, Some(&sock_addr))
- },
- {
- let num_packets_received_ref = &mut num_packets_received;
-
- move |len, _| {
- // check that we receive UDP packets with payload size
- // less or equal to segment size
- assert!(len <= segment_size as usize);
- *num_packets_received_ref += 1;
- }
- },
- );
-
- // Buffer size is 13, we will receive six packets of size 2,
- // and one packet of size 1.
- assert_eq!(7, num_packets_received);
- }
-
- #[test]
- // Disable the test on emulated platforms because it fails in Cirrus-CI.
- // Lack of QEMU support is suspected.
- #[cfg_attr(qemu, ignore)]
- pub fn gro() {
- require_kernel_version!(udp_offload::gro, ">= 5.3");
-
- // It's hard to guarantee receiving GRO packets. Just checking
- // that `setsockopt` doesn't fail with error
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- setsockopt(rsock, UdpGroSegment, &true)
- .expect("setsockopt UDP_GRO failed");
- }
- }
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- ))]
- #[test]
- pub fn udp_sendmmsg() {
- use std::io::IoSlice;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:6793").unwrap();
- let std_sa2 = SocketAddrV4::from_str("127.0.0.1:6794").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
- let sock_addr2 = SockaddrIn::from(std_sa2);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let from = sendrecv(
- rsock,
- ssock,
- move |s, m, flags| {
- let batch_size = 15;
- let mut iovs = Vec::with_capacity(1 + batch_size);
- let mut addrs = Vec::with_capacity(1 + batch_size);
- let mut data = MultiHeaders::preallocate(1 + batch_size, None);
- let iov = IoSlice::new(m);
- // first chunk:
- iovs.push([iov]);
- addrs.push(Some(sock_addr));
-
- for _ in 0..batch_size {
- iovs.push([iov]);
- addrs.push(Some(sock_addr2));
- }
-
- let res = sendmmsg(s, &mut data, &iovs, addrs, [], flags)?;
- let mut sent_messages = 0;
- let mut sent_bytes = 0;
- for item in res {
- sent_messages += 1;
- sent_bytes += item.bytes;
- }
- //
- assert_eq!(sent_messages, iovs.len());
- assert_eq!(sent_bytes, sent_messages * m.len());
- Ok(sent_messages)
- },
- |_, _| {},
- );
- // UDP sockets should set the from address
- assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap());
- }
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- ))]
- #[test]
- pub fn udp_recvmmsg() {
- use nix::sys::socket::{recvmmsg, MsgFlags};
- use std::io::IoSliceMut;
-
- const NUM_MESSAGES_SENT: usize = 2;
- const DATA: [u8; 2] = [1, 2];
-
- let inet_addr = SocketAddrV4::from_str("127.0.0.1:6798").unwrap();
- let sock_addr = SockaddrIn::from(inet_addr);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let send_thread = thread::spawn(move || {
- for _ in 0..NUM_MESSAGES_SENT {
- sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty())
- .unwrap();
- }
- });
-
- let mut msgs = std::collections::LinkedList::new();
-
- // Buffers to receive exactly `NUM_MESSAGES_SENT` messages
- let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT];
- msgs.extend(
- receive_buffers
- .iter_mut()
- .map(|buf| [IoSliceMut::new(&mut buf[..])]),
- );
-
- let mut data =
- MultiHeaders::<SockaddrIn>::preallocate(msgs.len(), None);
-
- let res: Vec<RecvMsg<SockaddrIn>> =
- recvmmsg(rsock, &mut data, msgs.iter(), MsgFlags::empty(), None)
- .expect("recvmmsg")
- .collect();
- assert_eq!(res.len(), DATA.len());
-
- for RecvMsg { address, bytes, .. } in res.into_iter() {
- assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap());
- assert_eq!(DATA.len(), bytes);
- }
-
- for buf in &receive_buffers {
- assert_eq!(&buf[..DATA.len()], DATA);
- }
-
- send_thread.join().unwrap();
- }
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- ))]
- #[test]
- pub fn udp_recvmmsg_dontwait_short_read() {
- use nix::sys::socket::{recvmmsg, MsgFlags};
- use std::io::IoSliceMut;
-
- const NUM_MESSAGES_SENT: usize = 2;
- const DATA: [u8; 4] = [1, 2, 3, 4];
-
- let inet_addr = SocketAddrV4::from_str("127.0.0.1:6799").unwrap();
- let sock_addr = SockaddrIn::from(inet_addr);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let send_thread = thread::spawn(move || {
- for _ in 0..NUM_MESSAGES_SENT {
- sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty())
- .unwrap();
- }
- });
- // Ensure we've sent all the messages before continuing so `recvmmsg`
- // will return right away
- send_thread.join().unwrap();
-
- let mut msgs = std::collections::LinkedList::new();
-
- // Buffers to receive >`NUM_MESSAGES_SENT` messages to ensure `recvmmsg`
- // will return when there are fewer than requested messages in the
- // kernel buffers when using `MSG_DONTWAIT`.
- let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2];
- msgs.extend(
- receive_buffers
- .iter_mut()
- .map(|buf| [IoSliceMut::new(&mut buf[..])]),
- );
-
- let mut data = MultiHeaders::<SockaddrIn>::preallocate(
- NUM_MESSAGES_SENT + 2,
- None,
- );
-
- let res: Vec<RecvMsg<SockaddrIn>> = recvmmsg(
- rsock,
- &mut data,
- msgs.iter(),
- MsgFlags::MSG_DONTWAIT,
- None,
- )
- .expect("recvmmsg")
- .collect();
- assert_eq!(res.len(), NUM_MESSAGES_SENT);
-
- for RecvMsg { address, bytes, .. } in res.into_iter() {
- assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap());
- assert_eq!(DATA.len(), bytes);
- }
-
- for buf in &receive_buffers[..NUM_MESSAGES_SENT] {
- assert_eq!(&buf[..DATA.len()], DATA);
- }
- }
-
- #[test]
- pub fn udp_inet6() {
- let addr = std::net::Ipv6Addr::from_str("::1").unwrap();
- let rport = 6789;
- let rstd_sa = SocketAddrV6::new(addr, rport, 0, 0);
- let raddr = SockaddrIn6::from(rstd_sa);
- let sport = 6790;
- let sstd_sa = SocketAddrV6::new(addr, sport, 0, 0);
- let saddr = SockaddrIn6::from(sstd_sa);
- let rsock = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- match bind(rsock, &raddr) {
- Err(Errno::EADDRNOTAVAIL) => {
- println!("IPv6 not available, skipping test.");
- return;
- }
- Err(e) => panic!("bind: {}", e),
- Ok(()) => (),
- }
- let ssock = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- bind(ssock, &saddr).unwrap();
- let from = sendrecv(
- rsock,
- ssock,
- move |s, m, flags| sendto(s, m, &raddr, flags),
- |_, _| {},
- );
- assert_eq!(AddressFamily::Inet6, from.unwrap().family().unwrap());
- let osent_addr = from.unwrap();
- let sent_addr = osent_addr.as_sockaddr_in6().unwrap();
- assert_eq!(sent_addr.ip(), addr);
- assert_eq!(sent_addr.port(), sport);
- }
-}
-
-// Test error handling of our recvmsg wrapper
-#[test]
-pub fn test_recvmsg_ebadf() {
- use nix::errno::Errno;
- use nix::sys::socket::{recvmsg, MsgFlags};
- use std::io::IoSliceMut;
-
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
-
- let fd = -1; // Bad file descriptor
- let r = recvmsg::<()>(fd, &mut iov, None, MsgFlags::empty());
-
- assert_eq!(r.err().unwrap(), Errno::EBADF);
-}
-
-// Disable the test on emulated platforms due to a bug in QEMU versions <
-// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_scm_rights() {
- use nix::sys::socket::{
- recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
- ControlMessageOwned, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::{close, pipe, read, write};
- use std::io::{IoSlice, IoSliceMut};
-
- let (fd1, fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let (r, w) = pipe().unwrap();
- let mut received_r: Option<RawFd> = None;
-
- {
- let iov = [IoSlice::new(b"hello")];
- let fds = [r];
- let cmsg = ControlMessage::ScmRights(&fds);
- assert_eq!(
- sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(),
- 5
- );
- close(r).unwrap();
- close(fd1).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
-
- let mut iov = [IoSliceMut::new(&mut buf[..])];
- let mut cmsgspace = cmsg_space!([RawFd; 1]);
- let msg = recvmsg::<()>(
- fd2,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::empty(),
- )
- .unwrap();
-
- for cmsg in msg.cmsgs() {
- if let ControlMessageOwned::ScmRights(fd) = cmsg {
- assert_eq!(received_r, None);
- assert_eq!(fd.len(), 1);
- received_r = Some(fd[0]);
- } else {
- panic!("unexpected cmsg");
- }
- }
- assert_eq!(msg.bytes, 5);
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- close(fd2).unwrap();
- }
-
- let received_r = received_r.expect("Did not receive passed fd");
- // Ensure that the received file descriptor works
- write(w, b"world").unwrap();
- let mut buf = [0u8; 5];
- read(received_r, &mut buf).unwrap();
- assert_eq!(&buf[..], b"world");
- close(received_r).unwrap();
- close(w).unwrap();
-}
-
-// Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_af_alg_cipher() {
- use nix::sys::socket::sockopt::AlgSetKey;
- use nix::sys::socket::{
- accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr,
- ControlMessage, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::read;
- use std::io::IoSlice;
-
- skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
- // Travis's seccomp profile blocks AF_ALG
- // https://docs.docker.com/engine/security/seccomp/
- skip_if_seccomp!(test_af_alg_cipher);
-
- let alg_type = "skcipher";
- let alg_name = "ctr-aes-aesni";
- // 256-bits secret key
- let key = vec![0u8; 32];
- // 16-bytes IV
- let iv_len = 16;
- let iv = vec![1u8; iv_len];
- // 256-bytes plain payload
- let payload_len = 256;
- let payload = vec![2u8; payload_len];
-
- let sock = socket(
- AddressFamily::Alg,
- SockType::SeqPacket,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sockaddr = AlgAddr::new(alg_type, alg_name);
- bind(sock, &sockaddr).expect("bind failed");
-
- assert_eq!(sockaddr.alg_name().to_string_lossy(), alg_name);
- assert_eq!(sockaddr.alg_type().to_string_lossy(), alg_type);
-
- setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt");
- let session_socket = accept(sock).expect("accept failed");
-
- let msgs = [
- ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ];
- let iov = IoSlice::new(&payload);
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg encrypt");
-
- // allocate buffer for encrypted data
- let mut encrypted = vec![0u8; payload_len];
- let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
- assert_eq!(num_bytes, payload_len);
-
- let iov = IoSlice::new(&encrypted);
-
- let iv = vec![1u8; iv_len];
-
- let msgs = [
- ControlMessage::AlgSetOp(&libc::ALG_OP_DECRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ];
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg decrypt");
-
- // allocate buffer for decrypted data
- let mut decrypted = vec![0u8; payload_len];
- let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt");
-
- assert_eq!(num_bytes, payload_len);
- assert_eq!(decrypted, payload);
-}
-
-// Disable the test on emulated platforms due to not enabled support of AF_ALG
-// in QEMU from rust cross
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_af_alg_aead() {
- use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT};
- use nix::fcntl::{fcntl, FcntlArg, OFlag};
- use nix::sys::socket::sockopt::{AlgSetAeadAuthSize, AlgSetKey};
- use nix::sys::socket::{
- accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr,
- ControlMessage, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::{close, read};
- use std::io::IoSlice;
-
- skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
- // Travis's seccomp profile blocks AF_ALG
- // https://docs.docker.com/engine/security/seccomp/
- skip_if_seccomp!(test_af_alg_aead);
-
- let auth_size = 4usize;
- let assoc_size = 16u32;
-
- let alg_type = "aead";
- let alg_name = "gcm(aes)";
- // 256-bits secret key
- let key = vec![0u8; 32];
- // 12-bytes IV
- let iv_len = 12;
- let iv = vec![1u8; iv_len];
- // 256-bytes plain payload
- let payload_len = 256;
- let mut payload =
- vec![2u8; payload_len + (assoc_size as usize) + auth_size];
-
- for i in 0..assoc_size {
- payload[i as usize] = 10;
- }
-
- let len = payload.len();
-
- for i in 0..auth_size {
- payload[len - 1 - i] = 0;
- }
-
- let sock = socket(
- AddressFamily::Alg,
- SockType::SeqPacket,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sockaddr = AlgAddr::new(alg_type, alg_name);
- bind(sock, &sockaddr).expect("bind failed");
-
- setsockopt(sock, AlgSetAeadAuthSize, &auth_size)
- .expect("setsockopt AlgSetAeadAuthSize");
- setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt AlgSetKey");
- let session_socket = accept(sock).expect("accept failed");
-
- let msgs = [
- ControlMessage::AlgSetOp(&ALG_OP_ENCRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ControlMessage::AlgSetAeadAssoclen(&assoc_size),
- ];
-
- let iov = IoSlice::new(&payload);
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg encrypt");
-
- // allocate buffer for encrypted data
- let mut encrypted =
- vec![0u8; (assoc_size as usize) + payload_len + auth_size];
- let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
- assert_eq!(num_bytes, payload_len + auth_size + (assoc_size as usize));
- close(session_socket).expect("close");
-
- for i in 0..assoc_size {
- encrypted[i as usize] = 10;
- }
-
- let iov = IoSlice::new(&encrypted);
-
- let iv = vec![1u8; iv_len];
-
- let session_socket = accept(sock).expect("accept failed");
-
- let msgs = [
- ControlMessage::AlgSetOp(&ALG_OP_DECRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ControlMessage::AlgSetAeadAssoclen(&assoc_size),
- ];
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg decrypt");
-
- // allocate buffer for decrypted data
- let mut decrypted =
- vec![0u8; payload_len + (assoc_size as usize) + auth_size];
- // Starting with kernel 4.9, the interface changed slightly such that the
- // authentication tag memory is only needed in the output buffer for encryption
- // and in the input buffer for decryption.
- // Do not block on read, as we may have fewer bytes than buffer size
- fcntl(session_socket, FcntlArg::F_SETFL(OFlag::O_NONBLOCK))
- .expect("fcntl non_blocking");
- let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt");
-
- assert!(num_bytes >= payload_len + (assoc_size as usize));
- assert_eq!(
- decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))],
- payload[(assoc_size as usize)..payload_len + (assoc_size as usize)]
- );
-}
-
-// Verify `ControlMessage::Ipv4PacketInfo` for `sendmsg`.
-// This creates a (udp) socket bound to localhost, then sends a message to
-// itself but uses Ipv4PacketInfo to force the source address to be localhost.
-//
-// This would be a more interesting test if we could assume that the test host
-// has more than one IP address (since we could select a different address to
-// test from).
-#[cfg(any(target_os = "linux", target_os = "macos", target_os = "netbsd"))]
-#[test]
-pub fn test_sendmsg_ipv4packetinfo() {
- use cfg_if::cfg_if;
- use nix::sys::socket::{
- bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
- SockFlag, SockType, SockaddrIn,
- };
- use std::io::IoSlice;
-
- let sock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sock_addr = SockaddrIn::new(127, 0, 0, 1, 4000);
-
- bind(sock, &sock_addr).expect("bind failed");
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- cfg_if! {
- if #[cfg(target_os = "netbsd")] {
- let pi = libc::in_pktinfo {
- ipi_ifindex: 0, /* Unspecified interface */
- ipi_addr: libc::in_addr { s_addr: 0 },
- };
- } else {
- let pi = libc::in_pktinfo {
- ipi_ifindex: 0, /* Unspecified interface */
- ipi_addr: libc::in_addr { s_addr: 0 },
- ipi_spec_dst: sock_addr.as_ref().sin_addr,
- };
- }
- }
-
- let cmsg = [ControlMessage::Ipv4PacketInfo(&pi)];
-
- sendmsg(sock, &iov, &cmsg, MsgFlags::empty(), Some(&sock_addr))
- .expect("sendmsg");
-}
-
-// Verify `ControlMessage::Ipv6PacketInfo` for `sendmsg`.
-// This creates a (udp) socket bound to ip6-localhost, then sends a message to
-// itself but uses Ipv6PacketInfo to force the source address to be
-// ip6-localhost.
-//
-// This would be a more interesting test if we could assume that the test host
-// has more than one IP address (since we could select a different address to
-// test from).
-#[cfg(any(
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "freebsd"
-))]
-#[test]
-pub fn test_sendmsg_ipv6packetinfo() {
- use nix::errno::Errno;
- use nix::sys::socket::{
- bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
- SockFlag, SockType, SockaddrIn6,
- };
- use std::io::IoSlice;
-
- let sock = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap();
- let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa);
-
- if let Err(Errno::EADDRNOTAVAIL) = bind(sock, &sock_addr) {
- println!("IPv6 not available, skipping test.");
- return;
- }
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let pi = libc::in6_pktinfo {
- ipi6_ifindex: 0, /* Unspecified interface */
- ipi6_addr: sock_addr.as_ref().sin6_addr,
- };
-
- let cmsg = [ControlMessage::Ipv6PacketInfo(&pi)];
-
- sendmsg::<SockaddrIn6>(
- sock,
- &iov,
- &cmsg,
- MsgFlags::empty(),
- Some(&sock_addr),
- )
- .expect("sendmsg");
-}
-
-// Verify that ControlMessage::Ipv4SendSrcAddr works for sendmsg. This
-// creates a UDP socket bound to all local interfaces (0.0.0.0). It then
-// sends message to itself at 127.0.0.1 while explicitly specifying
-// 127.0.0.1 as the source address through an Ipv4SendSrcAddr
-// (IP_SENDSRCADDR) control message.
-//
-// Note that binding to 0.0.0.0 is *required* on FreeBSD; sendmsg
-// returns EINVAL otherwise. (See FreeBSD's ip(4) man page.)
-#[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
-))]
-#[test]
-pub fn test_sendmsg_ipv4sendsrcaddr() {
- use nix::sys::socket::{
- bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
- SockFlag, SockType, SockaddrIn,
- };
- use std::io::IoSlice;
-
- let sock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let unspec_sock_addr = SockaddrIn::new(0, 0, 0, 0, 0);
- bind(sock, &unspec_sock_addr).expect("bind failed");
- let bound_sock_addr: SockaddrIn = getsockname(sock).unwrap();
- let localhost_sock_addr: SockaddrIn =
- SockaddrIn::new(127, 0, 0, 1, bound_sock_addr.port());
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
- let cmsg = [ControlMessage::Ipv4SendSrcAddr(
- &localhost_sock_addr.as_ref().sin_addr,
- )];
-
- sendmsg(
- sock,
- &iov,
- &cmsg,
- MsgFlags::empty(),
- Some(&localhost_sock_addr),
- )
- .expect("sendmsg");
-}
-
-/// Tests that passing multiple fds using a single `ControlMessage` works.
-// Disable the test on emulated platforms due to a bug in QEMU versions <
-// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
-#[cfg_attr(qemu, ignore)]
-#[test]
-fn test_scm_rights_single_cmsg_multiple_fds() {
- use nix::sys::socket::{
- recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags,
- };
- use std::io::{IoSlice, IoSliceMut};
- use std::os::unix::io::{AsRawFd, RawFd};
- use std::os::unix::net::UnixDatagram;
- use std::thread;
-
- let (send, receive) = UnixDatagram::pair().unwrap();
- let thread = thread::spawn(move || {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
-
- let mut space = cmsg_space!([RawFd; 2]);
- let msg = recvmsg::<()>(
- receive.as_raw_fd(),
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .unwrap();
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
-
- let mut cmsgs = msg.cmsgs();
- match cmsgs.next() {
- Some(ControlMessageOwned::ScmRights(fds)) => {
- assert_eq!(
- fds.len(),
- 2,
- "unexpected fd count (expected 2 fds, got {})",
- fds.len()
- );
- }
- _ => panic!(),
- }
- assert!(cmsgs.next().is_none(), "unexpected control msg");
-
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- });
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
- let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout
- let cmsg = [ControlMessage::ScmRights(&fds)];
- sendmsg::<()>(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None)
- .unwrap();
- thread.join().unwrap();
-}
-
-// Verify `sendmsg` builds a valid `msghdr` when passing an empty
-// `cmsgs` argument. This should result in a msghdr with a nullptr
-// msg_control field and a msg_controllen of 0 when calling into the
-// raw `sendmsg`.
-#[test]
-pub fn test_sendmsg_empty_cmsgs() {
- use nix::sys::socket::{
- recvmsg, sendmsg, socketpair, AddressFamily, MsgFlags, SockFlag,
- SockType,
- };
- use nix::unistd::close;
- use std::io::{IoSlice, IoSliceMut};
-
- let (fd1, fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
-
- {
- let iov = [IoSlice::new(b"hello")];
- assert_eq!(
- sendmsg::<()>(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(),
- 5
- );
- close(fd1).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
-
- let mut cmsgspace = cmsg_space!([RawFd; 1]);
- let msg = recvmsg::<()>(
- fd2,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::empty(),
- )
- .unwrap();
-
- for _ in msg.cmsgs() {
- panic!("unexpected cmsg");
- }
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.bytes, 5);
- close(fd2).unwrap();
- }
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "freebsd",
- target_os = "dragonfly",
-))]
-#[test]
-fn test_scm_credentials() {
- use nix::sys::socket::{
- recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
- ControlMessageOwned, MsgFlags, SockFlag, SockType, UnixCredentials,
- };
- #[cfg(any(target_os = "android", target_os = "linux"))]
- use nix::sys::socket::{setsockopt, sockopt::PassCred};
- use nix::unistd::{close, getgid, getpid, getuid};
- use std::io::{IoSlice, IoSliceMut};
-
- let (send, recv) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- #[cfg(any(target_os = "android", target_os = "linux"))]
- setsockopt(recv, PassCred, &true).unwrap();
-
- {
- let iov = [IoSlice::new(b"hello")];
- #[cfg(any(target_os = "android", target_os = "linux"))]
- let cred = UnixCredentials::new();
- #[cfg(any(target_os = "android", target_os = "linux"))]
- let cmsg = ControlMessage::ScmCredentials(&cred);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- let cmsg = ControlMessage::ScmCreds;
- assert_eq!(
- sendmsg::<()>(send, &iov, &[cmsg], MsgFlags::empty(), None)
- .unwrap(),
- 5
- );
- close(send).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
-
- let mut cmsgspace = cmsg_space!(UnixCredentials);
- let msg = recvmsg::<()>(
- recv,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::empty(),
- )
- .unwrap();
- let mut received_cred = None;
-
- for cmsg in msg.cmsgs() {
- let cred = match cmsg {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessageOwned::ScmCredentials(cred) => cred,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- ControlMessageOwned::ScmCreds(cred) => cred,
- other => panic!("unexpected cmsg {:?}", other),
- };
- assert!(received_cred.is_none());
- assert_eq!(cred.pid(), getpid().as_raw());
- assert_eq!(cred.uid(), getuid().as_raw());
- assert_eq!(cred.gid(), getgid().as_raw());
- received_cred = Some(cred);
- }
- received_cred.expect("no creds received");
- assert_eq!(msg.bytes, 5);
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- close(recv).unwrap();
- }
-}
-
-/// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single
-/// `sendmsg` call.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation
-// see https://bugs.launchpad.net/qemu/+bug/1781280
-#[cfg_attr(qemu, ignore)]
-#[test]
-fn test_scm_credentials_and_rights() {
- let space = cmsg_space!(libc::ucred, RawFd);
- test_impl_scm_credentials_and_rights(space);
-}
-
-/// Ensure that passing a an oversized control message buffer to recvmsg
-/// still works.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation
-// see https://bugs.launchpad.net/qemu/+bug/1781280
-#[cfg_attr(qemu, ignore)]
-#[test]
-fn test_too_large_cmsgspace() {
- let space = vec![0u8; 1024];
- test_impl_scm_credentials_and_rights(space);
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
- use libc::ucred;
- use nix::sys::socket::sockopt::PassCred;
- use nix::sys::socket::{
- recvmsg, sendmsg, setsockopt, socketpair, ControlMessage,
- ControlMessageOwned, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::{close, getgid, getpid, getuid, pipe, write};
- use std::io::{IoSlice, IoSliceMut};
-
- let (send, recv) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- setsockopt(recv, PassCred, &true).unwrap();
-
- let (r, w) = pipe().unwrap();
- let mut received_r: Option<RawFd> = None;
-
- {
- let iov = [IoSlice::new(b"hello")];
- let cred = ucred {
- pid: getpid().as_raw(),
- uid: getuid().as_raw(),
- gid: getgid().as_raw(),
- }
- .into();
- let fds = [r];
- let cmsgs = [
- ControlMessage::ScmCredentials(&cred),
- ControlMessage::ScmRights(&fds),
- ];
- assert_eq!(
- sendmsg::<()>(send, &iov, &cmsgs, MsgFlags::empty(), None).unwrap(),
- 5
- );
- close(r).unwrap();
- close(send).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
- let msg =
- recvmsg::<()>(recv, &mut iov, Some(&mut space), MsgFlags::empty())
- .unwrap();
- let mut received_cred = None;
-
- assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
-
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::ScmRights(fds) => {
- assert_eq!(received_r, None, "already received fd");
- assert_eq!(fds.len(), 1);
- received_r = Some(fds[0]);
- }
- ControlMessageOwned::ScmCredentials(cred) => {
- assert!(received_cred.is_none());
- assert_eq!(cred.pid(), getpid().as_raw());
- assert_eq!(cred.uid(), getuid().as_raw());
- assert_eq!(cred.gid(), getgid().as_raw());
- received_cred = Some(cred);
- }
- _ => panic!("unexpected cmsg"),
- }
- }
- received_cred.expect("no creds received");
- assert_eq!(msg.bytes, 5);
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- close(recv).unwrap();
- }
-
- let received_r = received_r.expect("Did not receive passed fd");
- // Ensure that the received file descriptor works
- write(w, b"world").unwrap();
- let mut buf = [0u8; 5];
- read(received_r, &mut buf).unwrap();
- assert_eq!(&buf[..], b"world");
- close(received_r).unwrap();
- close(w).unwrap();
-}
-
-// Test creating and using named unix domain sockets
-#[test]
-pub fn test_named_unixdomain() {
- use nix::sys::socket::{accept, bind, connect, listen, socket, UnixAddr};
- use nix::sys::socket::{SockFlag, SockType};
- use nix::unistd::{close, read, write};
- use std::thread;
-
- let tempdir = tempfile::tempdir().unwrap();
- let sockname = tempdir.path().join("sock");
- let s1 = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
- let sockaddr = UnixAddr::new(&sockname).unwrap();
- bind(s1, &sockaddr).expect("bind failed");
- listen(s1, 10).expect("listen failed");
-
- let thr = thread::spawn(move || {
- let s2 = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
- connect(s2, &sockaddr).expect("connect failed");
- write(s2, b"hello").expect("write failed");
- close(s2).unwrap();
- });
-
- let s3 = accept(s1).expect("accept failed");
-
- let mut buf = [0; 5];
- read(s3, &mut buf).unwrap();
- close(s3).unwrap();
- close(s1).unwrap();
- thr.join().unwrap();
-
- assert_eq!(&buf[..], b"hello");
-}
-
-// Test using unnamed unix domain addresses
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_unnamed_unixdomain() {
- use nix::sys::socket::{getsockname, socketpair};
- use nix::sys::socket::{SockFlag, SockType};
- use nix::unistd::close;
-
- let (fd_1, fd_2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .expect("socketpair failed");
-
- let addr_1: UnixAddr = getsockname(fd_1).expect("getsockname failed");
- assert!(addr_1.is_unnamed());
-
- close(fd_1).unwrap();
- close(fd_2).unwrap();
-}
-
-// Test creating and using unnamed unix domain addresses for autobinding sockets
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_unnamed_unixdomain_autobind() {
- use nix::sys::socket::{bind, getsockname, socket};
- use nix::sys::socket::{SockFlag, SockType};
- use nix::unistd::close;
-
- let fd = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- // unix(7): "If a bind(2) call specifies addrlen as `sizeof(sa_family_t)`, or [...], then the
- // socket is autobound to an abstract address"
- bind(fd, &UnixAddr::new_unnamed()).expect("bind failed");
-
- let addr: UnixAddr = getsockname(fd).expect("getsockname failed");
- let addr = addr.as_abstract().unwrap();
-
- // changed from 8 to 5 bytes in Linux 2.3.15, and rust's minimum supported Linux version is 3.2
- // (as of 2022-11)
- assert_eq!(addr.len(), 5);
-
- close(fd).unwrap();
-}
-
-// Test creating and using named system control sockets
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-#[test]
-pub fn test_syscontrol() {
- use nix::errno::Errno;
- use nix::sys::socket::{
- socket, SockFlag, SockProtocol, SockType, SysControlAddr,
- };
-
- let fd = socket(
- AddressFamily::System,
- SockType::Datagram,
- SockFlag::empty(),
- SockProtocol::KextControl,
- )
- .expect("socket failed");
- SysControlAddr::from_name(fd, "com.apple.net.utun_control", 0)
- .expect("resolving sys_control name failed");
- assert_eq!(
- SysControlAddr::from_name(fd, "foo.bar.lol", 0).err(),
- Some(Errno::ENOENT)
- );
-
- // requires root privileges
- // connect(fd, &sockaddr).expect("connect failed");
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-fn loopback_address(
- family: AddressFamily,
-) -> Option<nix::ifaddrs::InterfaceAddress> {
- use nix::ifaddrs::getifaddrs;
- use nix::net::if_::*;
- use nix::sys::socket::SockaddrLike;
- use std::io;
- use std::io::Write;
-
- let mut addrs = match getifaddrs() {
- Ok(iter) => iter,
- Err(e) => {
- let stdioerr = io::stderr();
- let mut handle = stdioerr.lock();
- writeln!(handle, "getifaddrs: {:?}", e).unwrap();
- return None;
- }
- };
- // return first address matching family
- addrs.find(|ifaddr| {
- ifaddr.flags.contains(InterfaceFlags::IFF_LOOPBACK)
- && ifaddr.address.as_ref().and_then(SockaddrLike::family)
- == Some(family)
- })
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
-))]
-// qemu doesn't seem to be emulating this correctly in these architectures
-#[cfg_attr(
- all(
- qemu,
- any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc64",
- )
- ),
- ignore
-)]
-#[test]
-pub fn test_recv_ipv4pktinfo() {
- use nix::net::if_::*;
- use nix::sys::socket::sockopt::Ipv4PacketInfo;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet);
- let (lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv4 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv4PacketInfo, &true).expect("setsockopt failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
-
- let mut space = cmsg_space!(libc::in_pktinfo);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
-
- let mut cmsgs = msg.cmsgs();
- if let Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) = cmsgs.next()
- {
- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
- assert_eq!(
- pktinfo.ipi_ifindex as libc::c_uint, i,
- "unexpected ifindex (expected {}, got {})",
- i, pktinfo.ipi_ifindex
- );
- }
- assert!(cmsgs.next().is_none(), "unexpected additional control msg");
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-// qemu doesn't seem to be emulating this correctly in these architectures
-#[cfg_attr(
- all(
- qemu,
- any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc64",
- )
- ),
- ignore
-)]
-#[test]
-pub fn test_recvif() {
- use nix::net::if_::*;
- use nix::sys::socket::sockopt::{Ipv4RecvDstAddr, Ipv4RecvIf};
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet);
- let (lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv4 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv4RecvIf, &true)
- .expect("setsockopt IP_RECVIF failed");
- setsockopt(receive, Ipv4RecvDstAddr, &true)
- .expect("setsockopt IP_RECVDSTADDR failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut space = cmsg_space!(libc::sockaddr_dl, libc::in_addr);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
-
- let mut rx_recvif = false;
- let mut rx_recvdstaddr = false;
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::Ipv4RecvIf(dl) => {
- rx_recvif = true;
- let i = if_nametoindex(lo_name.as_bytes())
- .expect("if_nametoindex");
- assert_eq!(
- dl.sdl_index as libc::c_uint, i,
- "unexpected ifindex (expected {}, got {})",
- i, dl.sdl_index
- );
- }
- ControlMessageOwned::Ipv4RecvDstAddr(addr) => {
- rx_recvdstaddr = true;
- if let Some(sin) = lo.as_sockaddr_in() {
- assert_eq!(sin.as_ref().sin_addr.s_addr,
- addr.s_addr,
- "unexpected destination address (expected {}, got {})",
- sin.as_ref().sin_addr.s_addr,
- addr.s_addr);
- } else {
- panic!("unexpected Sockaddr");
- }
- }
- _ => panic!("unexpected additional control msg"),
- }
- }
- assert!(rx_recvif);
- assert!(rx_recvdstaddr);
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_recvif_ipv4() {
- use nix::sys::socket::sockopt::Ipv4OrigDstAddr;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet);
- let (_lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv4 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv4OrigDstAddr, &true)
- .expect("setsockopt IP_ORIGDSTADDR failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut space = cmsg_space!(libc::sockaddr_in);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs");
-
- let mut rx_recvorigdstaddr = false;
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::Ipv4OrigDstAddr(addr) => {
- rx_recvorigdstaddr = true;
- if let Some(sin) = lo.as_sockaddr_in() {
- assert_eq!(sin.as_ref().sin_addr.s_addr,
- addr.sin_addr.s_addr,
- "unexpected destination address (expected {}, got {})",
- sin.as_ref().sin_addr.s_addr,
- addr.sin_addr.s_addr);
- } else {
- panic!("unexpected Sockaddr");
- }
- }
- _ => panic!("unexpected additional control msg"),
- }
- }
- assert!(rx_recvorigdstaddr);
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_recvif_ipv6() {
- use nix::sys::socket::sockopt::Ipv6OrigDstAddr;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet6);
- let (_lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv6 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv6OrigDstAddr, &true)
- .expect("setsockopt IP_ORIGDSTADDR failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut space = cmsg_space!(libc::sockaddr_in6);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs");
-
- let mut rx_recvorigdstaddr = false;
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::Ipv6OrigDstAddr(addr) => {
- rx_recvorigdstaddr = true;
- if let Some(sin) = lo.as_sockaddr_in6() {
- assert_eq!(sin.as_ref().sin6_addr.s6_addr,
- addr.sin6_addr.s6_addr,
- "unexpected destination address (expected {:?}, got {:?})",
- sin.as_ref().sin6_addr.s6_addr,
- addr.sin6_addr.s6_addr);
- } else {
- panic!("unexpected Sockaddr");
- }
- }
- _ => panic!("unexpected additional control msg"),
- }
- }
- assert!(rx_recvorigdstaddr);
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-// qemu doesn't seem to be emulating this correctly in these architectures
-#[cfg_attr(
- all(
- qemu,
- any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc64",
- )
- ),
- ignore
-)]
-#[test]
-pub fn test_recv_ipv6pktinfo() {
- use nix::net::if_::*;
- use nix::sys::socket::sockopt::Ipv6RecvPacketInfo;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet6);
- let (lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv6 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv6RecvPacketInfo, &true).expect("setsockopt failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
-
- let mut space = cmsg_space!(libc::in6_pktinfo);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
-
- let mut cmsgs = msg.cmsgs();
- if let Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) = cmsgs.next()
- {
- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
- assert_eq!(
- pktinfo.ipi6_ifindex as libc::c_uint, i,
- "unexpected ifindex (expected {}, got {})",
- i, pktinfo.ipi6_ifindex
- );
- }
- assert!(cmsgs.next().is_none(), "unexpected additional control msg");
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(graviton, ignore = "Not supported by the CI environment")]
-#[test]
-pub fn test_vsock() {
- use nix::errno::Errno;
- use nix::sys::socket::{
- bind, connect, listen, socket, AddressFamily, SockFlag, SockType,
- VsockAddr,
- };
- use nix::unistd::close;
- use std::thread;
-
- let port: u32 = 3000;
-
- let s1 = socket(
- AddressFamily::Vsock,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- // VMADDR_CID_HYPERVISOR is reserved, so we expect an EADDRNOTAVAIL error.
- let sockaddr_hv = VsockAddr::new(libc::VMADDR_CID_HYPERVISOR, port);
- assert_eq!(bind(s1, &sockaddr_hv).err(), Some(Errno::EADDRNOTAVAIL));
-
- let sockaddr_any = VsockAddr::new(libc::VMADDR_CID_ANY, port);
- assert_eq!(bind(s1, &sockaddr_any), Ok(()));
- listen(s1, 10).expect("listen failed");
-
- let thr = thread::spawn(move || {
- let cid: u32 = libc::VMADDR_CID_HOST;
-
- let s2 = socket(
- AddressFamily::Vsock,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sockaddr_host = VsockAddr::new(cid, port);
-
- // The current implementation does not support loopback devices, so,
- // for now, we expect a failure on the connect.
- assert_ne!(connect(s2, &sockaddr_host), Ok(()));
-
- close(s2).unwrap();
- });
-
- close(s1).unwrap();
- thr.join().unwrap();
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(all(target_os = "linux"))]
-#[test]
-fn test_recvmsg_timestampns() {
- use nix::sys::socket::*;
- use nix::sys::time::*;
- use std::io::{IoSlice, IoSliceMut};
- use std::time::*;
-
- // Set up
- let message = "Ohayō!".as_bytes();
- let in_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap();
- let localhost = SockaddrIn::new(127, 0, 0, 1, 0);
- bind(in_socket, &localhost).unwrap();
- let address: SockaddrIn = getsockname(in_socket).unwrap();
- // Get initial time
- let time0 = SystemTime::now();
- // Send the message
- let iov = [IoSlice::new(message)];
- let flags = MsgFlags::empty();
- let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
- assert_eq!(message.len(), l);
- // Receive the message
- let mut buffer = vec![0u8; message.len()];
- let mut cmsgspace = nix::cmsg_space!(TimeSpec);
-
- let mut iov = [IoSliceMut::new(&mut buffer)];
- let r = recvmsg::<()>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
- .unwrap();
- let rtime = match r.cmsgs().next() {
- Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
- Some(_) => panic!("Unexpected control message"),
- None => panic!("No control message"),
- };
- // Check the final time
- let time1 = SystemTime::now();
- // the packet's received timestamp should lie in-between the two system
- // times, unless the system clock was adjusted in the meantime.
- let rduration =
- Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32);
- assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
- assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
- // Close socket
- nix::unistd::close(in_socket).unwrap();
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(all(target_os = "linux"))]
-#[test]
-fn test_recvmmsg_timestampns() {
- use nix::sys::socket::*;
- use nix::sys::time::*;
- use std::io::{IoSlice, IoSliceMut};
- use std::time::*;
-
- // Set up
- let message = "Ohayō!".as_bytes();
- let in_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap();
- let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
- bind(in_socket, &localhost).unwrap();
- let address: SockaddrIn = getsockname(in_socket).unwrap();
- // Get initial time
- let time0 = SystemTime::now();
- // Send the message
- let iov = [IoSlice::new(message)];
- let flags = MsgFlags::empty();
- let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
- assert_eq!(message.len(), l);
- // Receive the message
- let mut buffer = vec![0u8; message.len()];
- let cmsgspace = nix::cmsg_space!(TimeSpec);
- let iov = vec![[IoSliceMut::new(&mut buffer)]];
- let mut data = MultiHeaders::preallocate(1, Some(cmsgspace));
- let r: Vec<RecvMsg<()>> =
- recvmmsg(in_socket, &mut data, iov.iter(), flags, None)
- .unwrap()
- .collect();
- let rtime = match r[0].cmsgs().next() {
- Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
- Some(_) => panic!("Unexpected control message"),
- None => panic!("No control message"),
- };
- // Check the final time
- let time1 = SystemTime::now();
- // the packet's received timestamp should lie in-between the two system
- // times, unless the system clock was adjusted in the meantime.
- let rduration =
- Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32);
- assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
- assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
- // Close socket
- nix::unistd::close(in_socket).unwrap();
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
-#[test]
-fn test_recvmsg_rxq_ovfl() {
- use nix::sys::socket::sockopt::{RcvBuf, RxqOvfl};
- use nix::sys::socket::*;
- use nix::Error;
- use std::io::{IoSlice, IoSliceMut};
-
- let message = [0u8; 2048];
- let bufsize = message.len() * 2;
-
- let in_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let out_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
- bind(in_socket, &localhost).unwrap();
-
- let address: SockaddrIn = getsockname(in_socket).unwrap();
- connect(out_socket, &address).unwrap();
-
- // Set SO_RXQ_OVFL flag.
- setsockopt(in_socket, RxqOvfl, &1).unwrap();
-
- // Set the receiver buffer size to hold only 2 messages.
- setsockopt(in_socket, RcvBuf, &bufsize).unwrap();
-
- let mut drop_counter = 0;
-
- for _ in 0..2 {
- let iov = [IoSlice::new(&message)];
- let flags = MsgFlags::empty();
-
- // Send the 3 messages (the receiver buffer can only hold 2 messages)
- // to create an overflow.
- for _ in 0..3 {
- let l =
- sendmsg(out_socket, &iov, &[], flags, Some(&address)).unwrap();
- assert_eq!(message.len(), l);
- }
-
- // Receive the message and check the drop counter if any.
- loop {
- let mut buffer = vec![0u8; message.len()];
- let mut cmsgspace = nix::cmsg_space!(u32);
-
- let mut iov = [IoSliceMut::new(&mut buffer)];
-
- match recvmsg::<()>(
- in_socket,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::MSG_DONTWAIT,
- ) {
- Ok(r) => {
- drop_counter = match r.cmsgs().next() {
- Some(ControlMessageOwned::RxqOvfl(drop_counter)) => {
- drop_counter
- }
- Some(_) => panic!("Unexpected control message"),
- None => 0,
- };
- }
- Err(Error::EAGAIN) => {
- break;
- }
- _ => {
- panic!("unknown recvmsg() error");
- }
- }
- }
- }
-
- // One packet lost.
- assert_eq!(drop_counter, 1);
-
- // Close sockets
- nix::unistd::close(in_socket).unwrap();
- nix::unistd::close(out_socket).unwrap();
-}
-
-#[cfg(any(target_os = "linux", target_os = "android",))]
-mod linux_errqueue {
- use super::FromStr;
- use nix::sys::socket::*;
-
- // Send a UDP datagram to a bogus destination address and observe an ICMP error (v4).
- //
- // Disable the test on QEMU because QEMU emulation of IP_RECVERR is broken (as documented on PR
- // #1514).
- #[cfg_attr(qemu, ignore)]
- #[test]
- fn test_recverr_v4() {
- #[repr(u8)]
- enum IcmpTypes {
- DestUnreach = 3, // ICMP_DEST_UNREACH
- }
- #[repr(u8)]
- enum IcmpUnreachCodes {
- PortUnreach = 3, // ICMP_PORT_UNREACH
- }
-
- test_recverr_impl::<sockaddr_in, _, _>(
- "127.0.0.1:6800",
- AddressFamily::Inet,
- sockopt::Ipv4RecvErr,
- libc::SO_EE_ORIGIN_ICMP,
- IcmpTypes::DestUnreach as u8,
- IcmpUnreachCodes::PortUnreach as u8,
- // Closure handles protocol-specific testing and returns generic sock_extended_err for
- // protocol-independent test impl.
- |cmsg| {
- if let ControlMessageOwned::Ipv4RecvErr(ext_err, err_addr) =
- cmsg
- {
- if let Some(origin) = err_addr {
- // Validate that our network error originated from 127.0.0.1:0.
- assert_eq!(origin.sin_family, AddressFamily::Inet as _);
- assert_eq!(
- origin.sin_addr.s_addr,
- u32::from_be(0x7f000001)
- );
- assert_eq!(origin.sin_port, 0);
- } else {
- panic!("Expected some error origin");
- }
- *ext_err
- } else {
- panic!("Unexpected control message {:?}", cmsg);
- }
- },
- )
- }
-
- // Essentially the same test as v4.
- //
- // Disable the test on QEMU because QEMU emulation of IPV6_RECVERR is broken (as documented on
- // PR #1514).
- #[cfg_attr(qemu, ignore)]
- #[test]
- fn test_recverr_v6() {
- #[repr(u8)]
- enum IcmpV6Types {
- DestUnreach = 1, // ICMPV6_DEST_UNREACH
- }
- #[repr(u8)]
- enum IcmpV6UnreachCodes {
- PortUnreach = 4, // ICMPV6_PORT_UNREACH
- }
-
- test_recverr_impl::<sockaddr_in6, _, _>(
- "[::1]:6801",
- AddressFamily::Inet6,
- sockopt::Ipv6RecvErr,
- libc::SO_EE_ORIGIN_ICMP6,
- IcmpV6Types::DestUnreach as u8,
- IcmpV6UnreachCodes::PortUnreach as u8,
- // Closure handles protocol-specific testing and returns generic sock_extended_err for
- // protocol-independent test impl.
- |cmsg| {
- if let ControlMessageOwned::Ipv6RecvErr(ext_err, err_addr) =
- cmsg
- {
- if let Some(origin) = err_addr {
- // Validate that our network error originated from localhost:0.
- assert_eq!(
- origin.sin6_family,
- AddressFamily::Inet6 as _
- );
- assert_eq!(
- origin.sin6_addr.s6_addr,
- std::net::Ipv6Addr::LOCALHOST.octets()
- );
- assert_eq!(origin.sin6_port, 0);
- } else {
- panic!("Expected some error origin");
- }
- *ext_err
- } else {
- panic!("Unexpected control message {:?}", cmsg);
- }
- },
- )
- }
-
- fn test_recverr_impl<SA, OPT, TESTF>(
- sa: &str,
- af: AddressFamily,
- opt: OPT,
- ee_origin: u8,
- ee_type: u8,
- ee_code: u8,
- testf: TESTF,
- ) where
- OPT: SetSockOpt<Val = bool>,
- TESTF: FnOnce(&ControlMessageOwned) -> libc::sock_extended_err,
- {
- use nix::errno::Errno;
- use std::io::IoSliceMut;
-
- const MESSAGE_CONTENTS: &str = "ABCDEF";
- let std_sa = std::net::SocketAddr::from_str(sa).unwrap();
- let sock_addr = SockaddrStorage::from(std_sa);
- let sock = socket(af, SockType::Datagram, SockFlag::SOCK_CLOEXEC, None)
- .unwrap();
- setsockopt(sock, opt, &true).unwrap();
- if let Err(e) = sendto(
- sock,
- MESSAGE_CONTENTS.as_bytes(),
- &sock_addr,
- MsgFlags::empty(),
- ) {
- assert_eq!(e, Errno::EADDRNOTAVAIL);
- println!("{:?} not available, skipping test.", af);
- return;
- }
-
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut cspace = cmsg_space!(libc::sock_extended_err, SA);
-
- let msg = recvmsg(
- sock,
- &mut iovec,
- Some(&mut cspace),
- MsgFlags::MSG_ERRQUEUE,
- )
- .unwrap();
- // The sent message / destination associated with the error is returned:
- assert_eq!(msg.bytes, MESSAGE_CONTENTS.as_bytes().len());
- // recvmsg(2): "The original destination address of the datagram that caused the error is
- // supplied via msg_name;" however, this is not literally true. E.g., an earlier version
- // of this test used 0.0.0.0 (::0) as the destination address, which was mutated into
- // 127.0.0.1 (::1).
- assert_eq!(msg.address, Some(sock_addr));
-
- // Check for expected control message.
- let ext_err = match msg.cmsgs().next() {
- Some(cmsg) => testf(&cmsg),
- None => panic!("No control message"),
- };
-
- assert_eq!(ext_err.ee_errno, libc::ECONNREFUSED as u32);
- assert_eq!(ext_err.ee_origin, ee_origin);
- // ip(7): ee_type and ee_code are set from the type and code fields of the ICMP (ICMPv6)
- // header.
- assert_eq!(ext_err.ee_type, ee_type);
- assert_eq!(ext_err.ee_code, ee_code);
- // ip(7): ee_info contains the discovered MTU for EMSGSIZE errors.
- assert_eq!(ext_err.ee_info, 0);
-
- let bytes = msg.bytes;
- assert_eq!(&buf[..bytes], MESSAGE_CONTENTS.as_bytes());
- }
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(target_os = "linux")]
-#[test]
-pub fn test_txtime() {
- use nix::sys::socket::{
- bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage,
- MsgFlags, SockFlag, SockType, SockaddrIn,
- };
- use nix::sys::time::TimeValLike;
- use nix::time::{clock_gettime, ClockId};
-
- require_kernel_version!(test_txtime, ">= 5.8");
-
- let sock_addr = SockaddrIn::from_str("127.0.0.1:6802").unwrap();
-
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let txtime_cfg = libc::sock_txtime {
- clockid: libc::CLOCK_MONOTONIC,
- flags: 0,
- };
- setsockopt(ssock, sockopt::TxTime, &txtime_cfg).unwrap();
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
-
- let sbuf = [0u8; 2048];
- let iov1 = [std::io::IoSlice::new(&sbuf)];
-
- let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap();
- let delay = std::time::Duration::from_secs(1).into();
- let txtime = (now + delay).num_nanoseconds() as u64;
-
- let cmsg = ControlMessage::TxTime(&txtime);
- sendmsg(ssock, &iov1, &[cmsg], MsgFlags::empty(), Some(&sock_addr))
- .unwrap();
-
- let mut rbuf = [0u8; 2048];
- let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)];
- recvmsg::<()>(rsock, &mut iov2, None, MsgFlags::empty()).unwrap();
-}
diff --git a/vendor/nix/test/sys/test_sockopt.rs b/vendor/nix/test/sys/test_sockopt.rs
deleted file mode 100644
index 34bef945e..000000000
--- a/vendor/nix/test/sys/test_sockopt.rs
+++ /dev/null
@@ -1,431 +0,0 @@
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use crate::*;
-use nix::sys::socket::{
- getsockopt, setsockopt, socket, sockopt, AddressFamily, SockFlag,
- SockProtocol, SockType,
-};
-use rand::{thread_rng, Rng};
-
-// NB: FreeBSD supports LOCAL_PEERCRED for SOCK_SEQPACKET, but OSX does not.
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd",))]
-#[test]
-pub fn test_local_peercred_seqpacket() {
- use nix::{
- sys::socket::socketpair,
- unistd::{Gid, Uid},
- };
-
- let (fd1, _fd2) = socketpair(
- AddressFamily::Unix,
- SockType::SeqPacket,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap();
- assert_eq!(xucred.version(), 0);
- assert_eq!(Uid::from_raw(xucred.uid()), Uid::current());
- assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current());
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
-))]
-#[test]
-pub fn test_local_peercred_stream() {
- use nix::{
- sys::socket::socketpair,
- unistd::{Gid, Uid},
- };
-
- let (fd1, _fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap();
- assert_eq!(xucred.version(), 0);
- assert_eq!(Uid::from_raw(xucred.uid()), Uid::current());
- assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current());
-}
-
-#[cfg(target_os = "linux")]
-#[test]
-fn is_so_mark_functional() {
- use nix::sys::socket::sockopt;
-
- require_capability!("is_so_mark_functional", CAP_NET_ADMIN);
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(s, sockopt::Mark, &1337).unwrap();
- let mark = getsockopt(s, sockopt::Mark).unwrap();
- assert_eq!(mark, 1337);
-}
-
-#[test]
-fn test_so_buf() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- SockProtocol::Udp,
- )
- .unwrap();
- let bufsize: usize = thread_rng().gen_range(4096..131_072);
- setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap();
- let actual = getsockopt(fd, sockopt::SndBuf).unwrap();
- assert!(actual >= bufsize);
- setsockopt(fd, sockopt::RcvBuf, &bufsize).unwrap();
- let actual = getsockopt(fd, sockopt::RcvBuf).unwrap();
- assert!(actual >= bufsize);
-}
-
-#[test]
-fn test_so_tcp_maxseg() {
- use nix::sys::socket::{accept, bind, connect, listen, SockaddrIn};
- use nix::unistd::{close, write};
- use std::net::SocketAddrV4;
- use std::str::FromStr;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- listen(rsock, 10).unwrap();
- let initial = getsockopt(rsock, sockopt::TcpMaxSeg).unwrap();
- // Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
- // platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger
- // than 700
- cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- let segsize: u32 = 873;
- assert!(initial < segsize);
- setsockopt(rsock, sockopt::TcpMaxSeg, &segsize).unwrap();
- } else {
- assert!(initial < 700);
- }
- }
-
- // Connect and check the MSS that was advertised
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- connect(ssock, &sock_addr).unwrap();
- let rsess = accept(rsock).unwrap();
- write(rsess, b"hello").unwrap();
- let actual = getsockopt(ssock, sockopt::TcpMaxSeg).unwrap();
- // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
- // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
- cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- assert!((segsize - 100) <= actual);
- assert!(actual <= segsize);
- } else {
- assert!(initial < actual);
- assert!(536 < actual);
- }
- }
- close(rsock).unwrap();
- close(ssock).unwrap();
-}
-
-#[test]
-fn test_so_type() {
- let sockfd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- assert_eq!(Ok(SockType::Stream), getsockopt(sockfd, sockopt::SockType));
-}
-
-/// getsockopt(_, sockopt::SockType) should gracefully handle unknown socket
-/// types. Regression test for https://github.com/nix-rust/nix/issues/1819
-#[cfg(any(target_os = "android", target_os = "linux",))]
-#[test]
-fn test_so_type_unknown() {
- use nix::errno::Errno;
-
- require_capability!("test_so_type", CAP_NET_RAW);
- let sockfd = unsafe { libc::socket(libc::AF_PACKET, libc::SOCK_PACKET, 0) };
- assert!(sockfd >= 0, "Error opening socket: {}", nix::Error::last());
-
- assert_eq!(Err(Errno::EINVAL), getsockopt(sockfd, sockopt::SockType));
-}
-
-// The CI doesn't supported getsockopt and setsockopt on emulated processors.
-// It's believed that a QEMU issue, the tests run ok on a fully emulated system.
-// Current CI just run the binary with QEMU but the Kernel remains the same as the host.
-// So the syscall doesn't work properly unless the kernel is also emulated.
-#[test]
-#[cfg(all(
- any(target_arch = "x86", target_arch = "x86_64"),
- any(target_os = "freebsd", target_os = "linux")
-))]
-fn test_tcp_congestion() {
- use std::ffi::OsString;
-
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- let val = getsockopt(fd, sockopt::TcpCongestion).unwrap();
- setsockopt(fd, sockopt::TcpCongestion, &val).unwrap();
-
- setsockopt(
- fd,
- sockopt::TcpCongestion,
- &OsString::from("tcp_congestion_does_not_exist"),
- )
- .unwrap_err();
-
- assert_eq!(getsockopt(fd, sockopt::TcpCongestion).unwrap(), val);
-}
-
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_bindtodevice() {
- skip_if_not_root!("test_bindtodevice");
-
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- let val = getsockopt(fd, sockopt::BindToDevice).unwrap();
- setsockopt(fd, sockopt::BindToDevice, &val).unwrap();
-
- assert_eq!(getsockopt(fd, sockopt::BindToDevice).unwrap(), val);
-}
-
-#[test]
-fn test_so_tcp_keepalive() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- setsockopt(fd, sockopt::KeepAlive, &true).unwrap();
- assert!(getsockopt(fd, sockopt::KeepAlive).unwrap());
-
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
- ))]
- {
- let x = getsockopt(fd, sockopt::TcpKeepIdle).unwrap();
- setsockopt(fd, sockopt::TcpKeepIdle, &(x + 1)).unwrap();
- assert_eq!(getsockopt(fd, sockopt::TcpKeepIdle).unwrap(), x + 1);
-
- let x = getsockopt(fd, sockopt::TcpKeepCount).unwrap();
- setsockopt(fd, sockopt::TcpKeepCount, &(x + 1)).unwrap();
- assert_eq!(getsockopt(fd, sockopt::TcpKeepCount).unwrap(), x + 1);
-
- let x = getsockopt(fd, sockopt::TcpKeepInterval).unwrap();
- setsockopt(fd, sockopt::TcpKeepInterval, &(x + 1)).unwrap();
- assert_eq!(getsockopt(fd, sockopt::TcpKeepInterval).unwrap(), x + 1);
- }
-}
-
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-fn test_get_mtu() {
- use nix::sys::socket::{bind, connect, SockaddrIn};
- use std::net::SocketAddrV4;
- use std::str::FromStr;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap();
- let std_sb = SocketAddrV4::from_str("127.0.0.1:4002").unwrap();
-
- let usock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- SockProtocol::Udp,
- )
- .unwrap();
-
- // Bind and initiate connection
- bind(usock, &SockaddrIn::from(std_sa)).unwrap();
- connect(usock, &SockaddrIn::from(std_sb)).unwrap();
-
- // Loopback connections have 2^16 - the maximum - MTU
- assert_eq!(getsockopt(usock, sockopt::IpMtu), Ok(u16::MAX as i32))
-}
-
-#[test]
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-fn test_ttl_opts() {
- let fd4 = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd4, sockopt::Ipv4Ttl, &1)
- .expect("setting ipv4ttl on an inet socket should succeed");
- let fd6 = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd6, sockopt::Ipv6Ttl, &1)
- .expect("setting ipv6ttl on an inet6 socket should succeed");
-}
-
-#[test]
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-fn test_dontfrag_opts() {
- let fd4 = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- setsockopt(fd4, sockopt::IpDontFrag, &true)
- .expect("setting IP_DONTFRAG on an inet stream socket should succeed");
- setsockopt(fd4, sockopt::IpDontFrag, &false).expect(
- "unsetting IP_DONTFRAG on an inet stream socket should succeed",
- );
- let fd4d = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd4d, sockopt::IpDontFrag, &true).expect(
- "setting IP_DONTFRAG on an inet datagram socket should succeed",
- );
- setsockopt(fd4d, sockopt::IpDontFrag, &false).expect(
- "unsetting IP_DONTFRAG on an inet datagram socket should succeed",
- );
-}
-
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
-))]
-// Disable the test under emulation because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-fn test_v6dontfrag_opts() {
- let fd6 = socket(
- AddressFamily::Inet6,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- setsockopt(fd6, sockopt::Ipv6DontFrag, &true).expect(
- "setting IPV6_DONTFRAG on an inet6 stream socket should succeed",
- );
- setsockopt(fd6, sockopt::Ipv6DontFrag, &false).expect(
- "unsetting IPV6_DONTFRAG on an inet6 stream socket should succeed",
- );
- let fd6d = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd6d, sockopt::Ipv6DontFrag, &true).expect(
- "setting IPV6_DONTFRAG on an inet6 datagram socket should succeed",
- );
- setsockopt(fd6d, sockopt::Ipv6DontFrag, &false).expect(
- "unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed",
- );
-}
-
-#[test]
-#[cfg(target_os = "linux")]
-fn test_so_priority() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- let priority = 3;
- setsockopt(fd, sockopt::Priority, &priority).unwrap();
- assert_eq!(getsockopt(fd, sockopt::Priority).unwrap(), priority);
-}
-
-#[test]
-#[cfg(target_os = "linux")]
-fn test_ip_tos() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- let tos = 0x80; // CS4
- setsockopt(fd, sockopt::IpTos, &tos).unwrap();
- assert_eq!(getsockopt(fd, sockopt::IpTos).unwrap(), tos);
-}
-
-#[test]
-#[cfg(target_os = "linux")]
-// Disable the test under emulation because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-fn test_ipv6_tclass() {
- let fd = socket(
- AddressFamily::Inet6,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- let class = 0x80; // CS4
- setsockopt(fd, sockopt::Ipv6TClass, &class).unwrap();
- assert_eq!(getsockopt(fd, sockopt::Ipv6TClass).unwrap(), class);
-}
diff --git a/vendor/nix/test/sys/test_stat.rs b/vendor/nix/test/sys/test_stat.rs
deleted file mode 100644
index 426b4b658..000000000
--- a/vendor/nix/test/sys/test_stat.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// The conversion is not useless on all platforms.
-#[allow(clippy::useless_conversion)]
-#[cfg(target_os = "freebsd")]
-#[test]
-fn test_chflags() {
- use nix::{
- sys::stat::{fstat, FileFlag},
- unistd::chflags,
- };
- use std::os::unix::io::AsRawFd;
- use tempfile::NamedTempFile;
-
- let f = NamedTempFile::new().unwrap();
-
- let initial = FileFlag::from_bits_truncate(
- fstat(f.as_raw_fd()).unwrap().st_flags.into(),
- );
- // UF_OFFLINE is preserved by all FreeBSD file systems, but not interpreted
- // in any way, so it's handy for testing.
- let commanded = initial ^ FileFlag::UF_OFFLINE;
-
- chflags(f.path(), commanded).unwrap();
-
- let changed = FileFlag::from_bits_truncate(
- fstat(f.as_raw_fd()).unwrap().st_flags.into(),
- );
-
- assert_eq!(commanded, changed);
-}
diff --git a/vendor/nix/test/sys/test_sysinfo.rs b/vendor/nix/test/sys/test_sysinfo.rs
deleted file mode 100644
index 2897366ef..000000000
--- a/vendor/nix/test/sys/test_sysinfo.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use nix::sys::sysinfo::*;
-
-#[test]
-fn sysinfo_works() {
- let info = sysinfo().unwrap();
-
- let (l1, l5, l15) = info.load_average();
- assert!(l1 >= 0.0);
- assert!(l5 >= 0.0);
- assert!(l15 >= 0.0);
-
- info.uptime(); // just test Duration construction
-
- assert!(
- info.swap_free() <= info.swap_total(),
- "more swap available than installed (free: {}, total: {})",
- info.swap_free(),
- info.swap_total()
- );
-}
diff --git a/vendor/nix/test/sys/test_termios.rs b/vendor/nix/test/sys/test_termios.rs
deleted file mode 100644
index aaf00084f..000000000
--- a/vendor/nix/test/sys/test_termios.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-use std::os::unix::prelude::*;
-use tempfile::tempfile;
-
-use nix::errno::Errno;
-use nix::fcntl;
-use nix::pty::openpty;
-use nix::sys::termios::{self, tcgetattr, LocalFlags, OutputFlags};
-use nix::unistd::{close, read, write};
-
-/// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s
-fn write_all(f: RawFd, buf: &[u8]) {
- let mut len = 0;
- while len < buf.len() {
- len += write(f, &buf[len..]).unwrap();
- }
-}
-
-// Test tcgetattr on a terminal
-#[test]
-fn test_tcgetattr_pty() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- let pty = openpty(None, None).expect("openpty failed");
- termios::tcgetattr(pty.slave).unwrap();
- close(pty.master).expect("closing the master failed");
- close(pty.slave).expect("closing the slave failed");
-}
-
-// Test tcgetattr on something that isn't a terminal
-#[test]
-fn test_tcgetattr_enotty() {
- let file = tempfile().unwrap();
- assert_eq!(
- termios::tcgetattr(file.as_raw_fd()).err(),
- Some(Errno::ENOTTY)
- );
-}
-
-// Test tcgetattr on an invalid file descriptor
-#[test]
-fn test_tcgetattr_ebadf() {
- assert_eq!(termios::tcgetattr(-1).err(), Some(Errno::EBADF));
-}
-
-// Test modifying output flags
-#[test]
-fn test_output_flags() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open one pty to get attributes for the second one
- let mut termios = {
- let pty = openpty(None, None).expect("openpty failed");
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
- let termios = tcgetattr(pty.slave).expect("tcgetattr failed");
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- termios
- };
-
- // Make sure postprocessing '\r' isn't specified by default or this test is useless.
- assert!(!termios
- .output_flags
- .contains(OutputFlags::OPOST | OutputFlags::OCRNL));
-
- // Specify that '\r' characters should be transformed to '\n'
- // OPOST is specified to enable post-processing
- termios
- .output_flags
- .insert(OutputFlags::OPOST | OutputFlags::OCRNL);
-
- // Open a pty
- let pty = openpty(None, &termios).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Write into the master
- let string = "foofoofoo\r";
- write_all(pty.master, string.as_bytes());
-
- // Read from the slave verifying that the output has been properly transformed
- let mut buf = [0u8; 10];
- crate::read_exact(pty.slave, &mut buf);
- let transformed_string = "foofoofoo\n";
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- assert_eq!(&buf, transformed_string.as_bytes());
-}
-
-// Test modifying local flags
-#[test]
-fn test_local_flags() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open one pty to get attributes for the second one
- let mut termios = {
- let pty = openpty(None, None).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
- let termios = tcgetattr(pty.slave).unwrap();
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- termios
- };
-
- // Make sure echo is specified by default or this test is useless.
- assert!(termios.local_flags.contains(LocalFlags::ECHO));
-
- // Disable local echo
- termios.local_flags.remove(LocalFlags::ECHO);
-
- // Open a new pty with our modified termios settings
- let pty = openpty(None, &termios).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Set the master is in nonblocking mode or reading will never return.
- let flags = fcntl::fcntl(pty.master, fcntl::F_GETFL).unwrap();
- let new_flags =
- fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK;
- fcntl::fcntl(pty.master, fcntl::F_SETFL(new_flags)).unwrap();
-
- // Write into the master
- let string = "foofoofoo\r";
- write_all(pty.master, string.as_bytes());
-
- // Try to read from the master, which should not have anything as echoing was disabled.
- let mut buf = [0u8; 10];
- let read = read(pty.master, &mut buf).unwrap_err();
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- assert_eq!(read, Errno::EAGAIN);
-}
diff --git a/vendor/nix/test/sys/test_timerfd.rs b/vendor/nix/test/sys/test_timerfd.rs
deleted file mode 100644
index 08e292106..000000000
--- a/vendor/nix/test/sys/test_timerfd.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use nix::sys::time::{TimeSpec, TimeValLike};
-use nix::sys::timerfd::{
- ClockId, Expiration, TimerFd, TimerFlags, TimerSetTimeFlags,
-};
-use std::time::Instant;
-
-#[test]
-pub fn test_timerfd_oneshot() {
- let timer =
- TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
-
- let before = Instant::now();
-
- timer
- .set(
- Expiration::OneShot(TimeSpec::seconds(1)),
- TimerSetTimeFlags::empty(),
- )
- .unwrap();
-
- timer.wait().unwrap();
-
- let millis = before.elapsed().as_millis();
- assert!(millis > 900);
-}
-
-#[test]
-pub fn test_timerfd_interval() {
- let timer =
- TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
-
- let before = Instant::now();
- timer
- .set(
- Expiration::IntervalDelayed(
- TimeSpec::seconds(1),
- TimeSpec::seconds(2),
- ),
- TimerSetTimeFlags::empty(),
- )
- .unwrap();
-
- timer.wait().unwrap();
-
- let start_delay = before.elapsed().as_millis();
- assert!(start_delay > 900);
-
- timer.wait().unwrap();
-
- let interval_delay = before.elapsed().as_millis();
- assert!(interval_delay > 2900);
-}
-
-#[test]
-pub fn test_timerfd_unset() {
- let timer =
- TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
-
- timer
- .set(
- Expiration::OneShot(TimeSpec::seconds(1)),
- TimerSetTimeFlags::empty(),
- )
- .unwrap();
-
- timer.unset().unwrap();
-
- assert!(timer.get().unwrap().is_none());
-}
diff --git a/vendor/nix/test/sys/test_uio.rs b/vendor/nix/test/sys/test_uio.rs
deleted file mode 100644
index 0f4b8a656..000000000
--- a/vendor/nix/test/sys/test_uio.rs
+++ /dev/null
@@ -1,270 +0,0 @@
-use nix::sys::uio::*;
-use nix::unistd::*;
-use rand::distributions::Alphanumeric;
-use rand::{thread_rng, Rng};
-use std::fs::OpenOptions;
-use std::io::IoSlice;
-use std::os::unix::io::AsRawFd;
-use std::{cmp, iter};
-
-#[cfg(not(target_os = "redox"))]
-use std::io::IoSliceMut;
-
-use tempfile::tempdir;
-#[cfg(not(target_os = "redox"))]
-use tempfile::tempfile;
-
-#[test]
-fn test_writev() {
- let mut to_write = Vec::with_capacity(16 * 128);
- for _ in 0..16 {
- let s: String = thread_rng()
- .sample_iter(&Alphanumeric)
- .map(char::from)
- .take(128)
- .collect();
- let b = s.as_bytes();
- to_write.extend(b.iter().cloned());
- }
- // Allocate and fill iovecs
- let mut iovecs = Vec::new();
- let mut consumed = 0;
- while consumed < to_write.len() {
- let left = to_write.len() - consumed;
- let slice_len = if left <= 64 {
- left
- } else {
- thread_rng().gen_range(64..cmp::min(256, left))
- };
- let b = &to_write[consumed..consumed + slice_len];
- iovecs.push(IoSlice::new(b));
- consumed += slice_len;
- }
- let pipe_res = pipe();
- let (reader, writer) = pipe_res.expect("Couldn't create pipe");
- // FileDesc will close its filedesc (reader).
- let mut read_buf: Vec<u8> = iter::repeat(0u8).take(128 * 16).collect();
- // Blocking io, should write all data.
- let write_res = writev(writer, &iovecs);
- let written = write_res.expect("couldn't write");
- // Check whether we written all data
- assert_eq!(to_write.len(), written);
- let read_res = read(reader, &mut read_buf[..]);
- let read = read_res.expect("couldn't read");
- // Check we have read as much as we written
- assert_eq!(read, written);
- // Check equality of written and read data
- assert_eq!(&to_write, &read_buf);
- close(writer).expect("closed writer");
- close(reader).expect("closed reader");
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_readv() {
- let s: String = thread_rng()
- .sample_iter(&Alphanumeric)
- .map(char::from)
- .take(128)
- .collect();
- let to_write = s.as_bytes().to_vec();
- let mut storage = Vec::new();
- let mut allocated = 0;
- while allocated < to_write.len() {
- let left = to_write.len() - allocated;
- let vec_len = if left <= 64 {
- left
- } else {
- thread_rng().gen_range(64..cmp::min(256, left))
- };
- let v: Vec<u8> = iter::repeat(0u8).take(vec_len).collect();
- storage.push(v);
- allocated += vec_len;
- }
- let mut iovecs = Vec::with_capacity(storage.len());
- for v in &mut storage {
- iovecs.push(IoSliceMut::new(&mut v[..]));
- }
- let (reader, writer) = pipe().expect("couldn't create pipe");
- // Blocking io, should write all data.
- write(writer, &to_write).expect("write failed");
- let read = readv(reader, &mut iovecs[..]).expect("read failed");
- // Check whether we've read all data
- assert_eq!(to_write.len(), read);
- // Cccumulate data from iovecs
- let mut read_buf = Vec::with_capacity(to_write.len());
- for iovec in &iovecs {
- read_buf.extend(iovec.iter().cloned());
- }
- // Check whether iovecs contain all written data
- assert_eq!(read_buf.len(), to_write.len());
- // Check equality of written and read data
- assert_eq!(&read_buf, &to_write);
- close(reader).expect("couldn't close reader");
- close(writer).expect("couldn't close writer");
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_pwrite() {
- use std::io::Read;
-
- let mut file = tempfile().unwrap();
- let buf = [1u8; 8];
- assert_eq!(Ok(8), pwrite(file.as_raw_fd(), &buf, 8));
- let mut file_content = Vec::new();
- file.read_to_end(&mut file_content).unwrap();
- let mut expected = vec![0u8; 8];
- expected.extend(vec![1; 8]);
- assert_eq!(file_content, expected);
-}
-
-#[test]
-fn test_pread() {
- use std::io::Write;
-
- let tempdir = tempdir().unwrap();
-
- let path = tempdir.path().join("pread_test_file");
- let mut file = OpenOptions::new()
- .write(true)
- .read(true)
- .create(true)
- .truncate(true)
- .open(path)
- .unwrap();
- let file_content: Vec<u8> = (0..64).collect();
- file.write_all(&file_content).unwrap();
-
- let mut buf = [0u8; 16];
- assert_eq!(Ok(16), pread(file.as_raw_fd(), &mut buf, 16));
- let expected: Vec<_> = (16..32).collect();
- assert_eq!(&buf[..], &expected[..]);
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_pwritev() {
- use std::io::Read;
-
- let to_write: Vec<u8> = (0..128).collect();
- let expected: Vec<u8> = [vec![0; 100], to_write.clone()].concat();
-
- let iovecs = [
- IoSlice::new(&to_write[0..17]),
- IoSlice::new(&to_write[17..64]),
- IoSlice::new(&to_write[64..128]),
- ];
-
- let tempdir = tempdir().unwrap();
-
- // pwritev them into a temporary file
- let path = tempdir.path().join("pwritev_test_file");
- let mut file = OpenOptions::new()
- .write(true)
- .read(true)
- .create(true)
- .truncate(true)
- .open(path)
- .unwrap();
-
- let written = pwritev(file.as_raw_fd(), &iovecs, 100).ok().unwrap();
- assert_eq!(written, to_write.len());
-
- // Read the data back and make sure it matches
- let mut contents = Vec::new();
- file.read_to_end(&mut contents).unwrap();
- assert_eq!(contents, expected);
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_preadv() {
- use std::io::Write;
-
- let to_write: Vec<u8> = (0..200).collect();
- let expected: Vec<u8> = (100..200).collect();
-
- let tempdir = tempdir().unwrap();
-
- let path = tempdir.path().join("preadv_test_file");
-
- let mut file = OpenOptions::new()
- .read(true)
- .write(true)
- .create(true)
- .truncate(true)
- .open(path)
- .unwrap();
- file.write_all(&to_write).unwrap();
-
- let mut buffers: Vec<Vec<u8>> = vec![vec![0; 24], vec![0; 1], vec![0; 75]];
-
- {
- // Borrow the buffers into IoVecs and preadv into them
- let mut iovecs: Vec<_> = buffers
- .iter_mut()
- .map(|buf| IoSliceMut::new(&mut buf[..]))
- .collect();
- assert_eq!(Ok(100), preadv(file.as_raw_fd(), &mut iovecs, 100));
- }
-
- let all = buffers.concat();
- assert_eq!(all, expected);
-}
-
-#[test]
-#[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
-// uclibc doesn't implement process_vm_readv
-// qemu-user doesn't implement process_vm_readv/writev on most arches
-#[cfg_attr(qemu, ignore)]
-fn test_process_vm_readv() {
- use crate::*;
- use nix::sys::signal::*;
- use nix::sys::wait::*;
- use nix::unistd::ForkResult::*;
-
- require_capability!("test_process_vm_readv", CAP_SYS_PTRACE);
- let _m = crate::FORK_MTX.lock();
-
- // Pre-allocate memory in the child, since allocation isn't safe
- // post-fork (~= async-signal-safe)
- let mut vector = vec![1u8, 2, 3, 4, 5];
-
- let (r, w) = pipe().unwrap();
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Parent { child } => {
- close(w).unwrap();
- // wait for child
- read(r, &mut [0u8]).unwrap();
- close(r).unwrap();
-
- let ptr = vector.as_ptr() as usize;
- let remote_iov = RemoteIoVec { base: ptr, len: 5 };
- let mut buf = vec![0u8; 5];
-
- let ret = process_vm_readv(
- child,
- &mut [IoSliceMut::new(&mut buf)],
- &[remote_iov],
- );
-
- kill(child, SIGTERM).unwrap();
- waitpid(child, None).unwrap();
-
- assert_eq!(Ok(5), ret);
- assert_eq!(20u8, buf.iter().sum());
- }
- Child => {
- let _ = close(r);
- for i in &mut vector {
- *i += 1;
- }
- let _ = write(w, b"\0");
- let _ = close(w);
- loop {
- pause();
- }
- }
- }
-}
diff --git a/vendor/nix/test/sys/test_wait.rs b/vendor/nix/test/sys/test_wait.rs
deleted file mode 100644
index d472f1ec1..000000000
--- a/vendor/nix/test/sys/test_wait.rs
+++ /dev/null
@@ -1,257 +0,0 @@
-use libc::_exit;
-use nix::errno::Errno;
-use nix::sys::signal::*;
-use nix::sys::wait::*;
-use nix::unistd::ForkResult::*;
-use nix::unistd::*;
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_wait_signal() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- pause();
- unsafe { _exit(123) }
- }
- Parent { child } => {
- kill(child, Some(SIGKILL)).expect("Error: Kill Failed");
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Signaled(child, SIGKILL, false))
- );
- }
- }
-}
-
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- //target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
-fn test_waitid_signal() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- pause();
- unsafe { _exit(123) }
- }
- Parent { child } => {
- kill(child, Some(SIGKILL)).expect("Error: Kill Failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::Signaled(child, SIGKILL, false)),
- );
- }
- }
-}
-
-#[test]
-fn test_wait_exit() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: Child only calls `_exit`, which is async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => unsafe {
- _exit(12);
- },
- Parent { child } => {
- assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
- }
- }
-}
-
-#[cfg(not(target_os = "haiku"))]
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
-fn test_waitid_exit() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: Child only calls `_exit`, which is async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => unsafe {
- _exit(12);
- },
- Parent { child } => {
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::Exited(child, 12)),
- );
- }
- }
-}
-
-#[test]
-fn test_waitstatus_from_raw() {
- let pid = Pid::from_raw(1);
- assert_eq!(
- WaitStatus::from_raw(pid, 0x0002),
- Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false))
- );
- assert_eq!(
- WaitStatus::from_raw(pid, 0x0200),
- Ok(WaitStatus::Exited(pid, 2))
- );
- assert_eq!(WaitStatus::from_raw(pid, 0x7f7f), Err(Errno::EINVAL));
-}
-
-#[test]
-fn test_waitstatus_pid() {
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.unwrap() {
- Child => unsafe { _exit(0) },
- Parent { child } => {
- let status = waitpid(child, None).unwrap();
- assert_eq!(status.pid(), Some(child));
- }
- }
-}
-
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-fn test_waitid_pid() {
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.unwrap() {
- Child => unsafe { _exit(0) },
- Parent { child } => {
- let status = waitid(Id::Pid(child), WaitPidFlag::WEXITED).unwrap();
- assert_eq!(status.pid(), Some(child));
- }
- }
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-// FIXME: qemu-user doesn't implement ptrace on most arches
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-mod ptrace {
- use crate::*;
- use libc::_exit;
- use nix::sys::ptrace::{self, Event, Options};
- use nix::sys::signal::*;
- use nix::sys::wait::*;
- use nix::unistd::ForkResult::*;
- use nix::unistd::*;
-
- fn ptrace_child() -> ! {
- ptrace::traceme().unwrap();
- // As recommended by ptrace(2), raise SIGTRAP to pause the child
- // until the parent is ready to continue
- raise(SIGTRAP).unwrap();
- unsafe { _exit(0) }
- }
-
- fn ptrace_wait_parent(child: Pid) {
- // Wait for the raised SIGTRAP
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, SIGTRAP))
- );
- // We want to test a syscall stop and a PTRACE_EVENT stop
- ptrace::setoptions(
- child,
- Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT,
- )
- .expect("setoptions failed");
-
- // First, stop on the next system call, which will be exit()
- ptrace::syscall(child, None).expect("syscall failed");
- assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
- // Then get the ptrace event for the process exiting
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceEvent(
- child,
- SIGTRAP,
- Event::PTRACE_EVENT_EXIT as i32
- ))
- );
- // Finally get the normal wait() result, now that the process has exited
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0)));
- }
-
- #[cfg(not(target_env = "uclibc"))]
- fn ptrace_waitid_parent(child: Pid) {
- // Wait for the raised SIGTRAP
- //
- // Unlike waitpid(), waitid() can distinguish trap events from regular
- // stop events, so unlike ptrace_wait_parent(), we get a PtraceEvent here
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::PtraceEvent(child, SIGTRAP, 0)),
- );
- // We want to test a syscall stop and a PTRACE_EVENT stop
- ptrace::setoptions(
- child,
- Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT,
- )
- .expect("setopts failed");
-
- // First, stop on the next system call, which will be exit()
- ptrace::syscall(child, None).expect("syscall failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::PtraceSyscall(child)),
- );
- // Then get the ptrace event for the process exiting
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::PtraceEvent(
- child,
- SIGTRAP,
- Event::PTRACE_EVENT_EXIT as i32
- )),
- );
- // Finally get the normal wait() result, now that the process has exited
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::Exited(child, 0)),
- );
- }
-
- #[test]
- fn test_wait_ptrace() {
- require_capability!("test_wait_ptrace", CAP_SYS_PTRACE);
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => ptrace_child(),
- Parent { child } => ptrace_wait_parent(child),
- }
- }
-
- #[test]
- #[cfg(not(target_env = "uclibc"))]
- fn test_waitid_ptrace() {
- require_capability!("test_waitid_ptrace", CAP_SYS_PTRACE);
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => ptrace_child(),
- Parent { child } => ptrace_waitid_parent(child),
- }
- }
-}