diff --git a/.cirrus.yml b/.cirrus.yml index d3dd39b44..708d2a66f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -13,3 +13,16 @@ task: test_script: - . $HOME/.cargo/env - cargo test --workspace --features=all-apis + +task: + name: stable x86_64-unknown-freebsd-12 + freebsd_instance: + image_family: freebsd-12-1 + setup_script: + - curl https://sh.rustup.rs -sSf --output rustup.sh + - sh rustup.sh --default-toolchain stable -y --profile=minimal + - . $HOME/.cargo/env + - rustup default stable + test_script: + - . $HOME/.cargo/env + - cargo test --workspace --features=all-apis diff --git a/src/backend/libc/event/syscalls.rs b/src/backend/libc/event/syscalls.rs index 11f6af83e..eac88d4bb 100644 --- a/src/backend/libc/event/syscalls.rs +++ b/src/backend/libc/event/syscalls.rs @@ -33,7 +33,19 @@ pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result ret_owned_fd(eventfd2(initval, bitflags_bits!(flags))) } - #[cfg(any(target_os = "freebsd", target_os = "illumos"))] + // `eventfd` was added in FreeBSD 13, so it isn't available on FreeBSD 12. + #[cfg(target_os = "freebsd")] + unsafe { + weakcall! { + fn eventfd( + initval: c::c_uint, + flags: c::c_int + ) -> c::c_int + } + ret_owned_fd(eventfd(initval, bitflags_bits!(flags))) + } + + #[cfg(target_os = "illumos")] unsafe { ret_owned_fd(c::eventfd(initval, bitflags_bits!(flags))) } diff --git a/src/backend/libc/pty/syscalls.rs b/src/backend/libc/pty/syscalls.rs index 178201ead..8455024ab 100644 --- a/src/backend/libc/pty/syscalls.rs +++ b/src/backend/libc/pty/syscalls.rs @@ -31,9 +31,26 @@ pub(crate) fn ptsname(fd: BorrowedFd, mut buffer: Vec) -> io::Result c::c_int + } + if let Some(func) = ptsname_r.get() { + func(borrowed_fd(fd), buffer.as_mut_ptr().cast(), buffer.len()) + } else { + libc::ENOSYS + } + }; + // MacOS 10.13.4 has `ptsname_r`; use it if we have it, otherwise fall // back to calling the underlying ioctl directly. #[cfg(apple)] diff --git a/tests/event/eventfd.rs b/tests/event/eventfd.rs index 90b3097df..82195123d 100644 --- a/tests/event/eventfd.rs +++ b/tests/event/eventfd.rs @@ -6,7 +6,12 @@ fn test_eventfd() { use std::mem::size_of; use std::thread; - let efd = eventfd(0, EventfdFlags::CLOEXEC).unwrap(); + let efd = match eventfd(0, EventfdFlags::CLOEXEC) { + Ok(efd) => efd, + #[cfg(target_os = "freebsd")] + Err(rustix::io::Errno::NOSYS) => return, // FreeBSD 12 lacks `eventfd` + Err(e) => Err(e).unwrap(), + }; let child = thread::spawn(move || { for u in [1_u64, 3, 6, 11, 5000] { diff --git a/tests/process/procctl.rs b/tests/process/procctl.rs index 7abf34aaa..ff552d574 100644 --- a/tests/process/procctl.rs +++ b/tests/process/procctl.rs @@ -13,7 +13,11 @@ fn test_trace_status() { #[test] fn test_reaper_status() { - assert_eq!(set_reaper_status(false), Err(io::Errno::INVAL)); + match set_reaper_status(false).unwrap_err() { + io::Errno::INVAL => (), + io::Errno::PERM => return, // FreeBSD 12 doesn't support this + err => Err(err).unwrap(), + }; set_reaper_status(true).unwrap(); let status_while_acq = dbg!(get_reaper_status(None).unwrap()); set_reaper_status(false).unwrap(); @@ -38,7 +42,11 @@ fn test_trapcap() { #[test] fn test_no_new_privs() { - assert!(!no_new_privs(None).unwrap()); + match no_new_privs(None) { + Ok(flag) => assert!(!flag), + Err(io::Errno::INVAL) => return, // FreeBSD 12 doesn't support this + Err(err) => Err(err).unwrap(), + }; set_no_new_privs(None).unwrap(); assert!(no_new_privs(None).unwrap()); // No going back but, well, we're not gonna execute SUID binaries from the diff --git a/tests/pty/openpty.rs b/tests/pty/openpty.rs index 4eac0f51c..20632a009 100644 --- a/tests/pty/openpty.rs +++ b/tests/pty/openpty.rs @@ -1,72 +1,76 @@ use rustix::fs::{openat, Mode, OFlags, CWD}; use rustix::pty::*; use std::fs::File; -use std::io; use std::io::{Read, Write}; #[test] -fn openpty_basic() -> io::Result<()> { +fn openpty_basic() { // Use `CLOEXEC` if we can. #[cfg(any(linux_kernel, target_os = "freebsd", target_os = "netbsd"))] let flags = OpenptFlags::RDWR | OpenptFlags::NOCTTY | OpenptFlags::CLOEXEC; #[cfg(not(any(linux_kernel, target_os = "freebsd", target_os = "netbsd")))] let flags = OpenptFlags::RDWR | OpenptFlags::NOCTTY; - let controller = openpt(flags)?; + let controller = openpt(flags).unwrap(); - grantpt(&controller)?; - unlockpt(&controller)?; + grantpt(&controller).unwrap(); + unlockpt(&controller).unwrap(); - let name = ptsname(&controller, Vec::new())?; + let name = match ptsname(&controller, Vec::new()) { + Ok(name) => name, + #[cfg(target_os = "freebsd")] + Err(rustix::io::Errno::NOSYS) => return, // FreeBSD 12 doesn't support this + Err(err) => Err(err).unwrap(), + }; let user = openat( CWD, name, OFlags::RDWR | OFlags::NOCTTY | OFlags::CLOEXEC, Mode::empty(), - )?; + ) + .unwrap(); let mut controller = File::from(controller); let mut user = File::from(user); // The '\x04' is Ctrl-D, the default EOF control code. - controller.write_all(b"Hello, world!\n\x04")?; + controller.write_all(b"Hello, world!\n\x04").unwrap(); let mut s = String::new(); - user.read_to_string(&mut s)?; + user.read_to_string(&mut s).unwrap(); assert_eq!(s, "Hello, world!\n"); - Ok(()) } // Like `openpty_basic` but use `ioctl_tiocgptpeer` instead of `ptsname`. #[cfg(target_os = "linux")] #[test] -fn openpty_get_peer() -> io::Result<()> { +fn openpty_get_peer() { // Use `CLOEXEC` if we can. #[cfg(any(linux_kernel, target_os = "freebsd", target_os = "netbsd"))] let flags = OpenptFlags::RDWR | OpenptFlags::NOCTTY | OpenptFlags::CLOEXEC; #[cfg(not(any(linux_kernel, target_os = "freebsd", target_os = "netbsd")))] let flags = OpenptFlags::RDWR | OpenptFlags::NOCTTY; - let controller = openpt(flags)?; + let controller = openpt(flags).unwrap(); - grantpt(&controller)?; - unlockpt(&controller)?; + grantpt(&controller).unwrap(); + unlockpt(&controller).unwrap(); let user = ioctl_tiocgptpeer( &controller, OpenptFlags::RDWR | OpenptFlags::NOCTTY | OpenptFlags::CLOEXEC, - )?; + ) + .unwrap(); let mut controller = File::from(controller); let mut user = File::from(user); // The '\x04' is Ctrl-D, the default EOF control code. - controller.write_all(b"Hello, world!\n\x04")?; + controller.write_all(b"Hello, world!\n\x04").unwrap(); let mut s = String::new(); - user.read_to_string(&mut s)?; + user.read_to_string(&mut s).unwrap(); assert_eq!(s, "Hello, world!\n"); - Ok(()) }