From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Mon, 8 Jan 2024 01:21:28 +0400 Subject: Initial vendor packages Signed-off-by: Valentin Popov --- vendor/cc/src/os_pipe/unix.rs | 121 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 vendor/cc/src/os_pipe/unix.rs (limited to 'vendor/cc/src/os_pipe/unix.rs') diff --git a/vendor/cc/src/os_pipe/unix.rs b/vendor/cc/src/os_pipe/unix.rs new file mode 100644 index 0000000..ec4e547 --- /dev/null +++ b/vendor/cc/src/os_pipe/unix.rs @@ -0,0 +1,121 @@ +use std::{ + fs::File, + io, + os::{raw::c_int, unix::io::FromRawFd}, +}; + +pub(super) fn pipe() -> io::Result<(File, File)> { + let mut fds = [0; 2]; + + // The only known way right now to create atomically set the CLOEXEC flag is + // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9 + // and musl 0.9.3, and some other targets also have it. + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox" + ))] + { + unsafe { + cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?; + } + } + + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox" + )))] + { + unsafe { + cvt(libc::pipe(fds.as_mut_ptr()))?; + } + + cloexec::set_cloexec(fds[0])?; + cloexec::set_cloexec(fds[1])?; + } + + unsafe { Ok((File::from_raw_fd(fds[0]), File::from_raw_fd(fds[1]))) } +} + +fn cvt(t: c_int) -> io::Result { + if t == -1 { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} + +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox" +)))] +mod cloexec { + use super::{c_int, cvt, io}; + + #[cfg(not(any( + target_env = "newlib", + target_os = "solaris", + target_os = "illumos", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "l4re", + target_os = "linux", + target_os = "haiku", + target_os = "redox", + target_os = "vxworks", + target_os = "nto", + )))] + pub(super) fn set_cloexec(fd: c_int) -> io::Result<()> { + unsafe { + cvt(libc::ioctl(fd, libc::FIOCLEX))?; + } + + Ok(()) + } + + #[cfg(any( + all( + target_env = "newlib", + not(any(target_os = "espidf", target_os = "horizon")) + ), + target_os = "solaris", + target_os = "illumos", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "l4re", + target_os = "linux", + target_os = "haiku", + target_os = "redox", + target_os = "vxworks", + target_os = "nto", + ))] + pub(super) fn set_cloexec(fd: c_int) -> io::Result<()> { + unsafe { + let previous = cvt(libc::fcntl(fd, libc::F_GETFD))?; + let new = previous | libc::FD_CLOEXEC; + if new != previous { + cvt(libc::fcntl(fd, libc::F_SETFD, new))?; + } + } + + Ok(()) + } + + // FD_CLOEXEC is not supported in ESP-IDF and Horizon OS but there's no need to, + // because neither supports spawning processes. + #[cfg(any(target_os = "espidf", target_os = "horizon"))] + pub(super) fn set_cloexec(_fd: c_int) -> io::Result<()> { + Ok(()) + } +} -- cgit v1.2.3