From b763d2975098923fccee49af6fd1bb8e3d0fd965 Mon Sep 17 00:00:00 2001 From: jasta Date: Wed, 12 Jul 2023 16:30:47 -0700 Subject: [PATCH] Add ESP-IDF framework support Mostly fixing compiler errors but also working around nonblocking issues with accept, eventfd, etc. Closes #1691 --- src/sys/unix/net.rs | 6 +++++- src/sys/unix/pipe.rs | 2 ++ src/sys/unix/tcp.rs | 7 ++++++- src/sys/unix/uds/listener.rs | 8 +++++++- src/sys/unix/uds/mod.rs | 6 +++++- src/sys/unix/waker.rs | 9 +++++++-- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/sys/unix/net.rs b/src/sys/unix/net.rs index e93918c72..53019b12c 100644 --- a/src/sys/unix/net.rs +++ b/src/sys/unix/net.rs @@ -44,18 +44,20 @@ pub(crate) fn new_socket(domain: libc::c_int, socket_type: libc::c_int) -> io::R return Err(err); } - // Darwin doesn't have SOCK_NONBLOCK or SOCK_CLOEXEC. + // Darwin (and others) doesn't have SOCK_NONBLOCK or SOCK_CLOEXEC. #[cfg(any( target_os = "ios", target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "espidf", ))] { if let Err(err) = syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK)) { let _ = syscall!(close(socket)); return Err(err); } + #[cfg(not(target_os = "espidf"))] if let Err(err) = syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC)) { let _ = syscall!(close(socket)); return Err(err); @@ -105,6 +107,7 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_ target_os = "openbsd", target_os = "tvos", target_os = "watchos", + target_os = "espidf", ))] sin_len: 0, }; @@ -131,6 +134,7 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_ target_os = "openbsd", target_os = "tvos", target_os = "watchos", + target_os = "espidf", ))] sin6_len: 0, #[cfg(target_os = "illumos")] diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs index c2654ad59..cb9e62e06 100644 --- a/src/sys/unix/pipe.rs +++ b/src/sys/unix/pipe.rs @@ -168,6 +168,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "espidf", ))] unsafe { // For platforms that don't have `pipe2(2)` we need to manually set the @@ -202,6 +203,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> { target_os = "redox", target_os = "tvos", target_os = "watchos", + target_os = "espidf", )))] compile_error!("unsupported target for `mio::unix::pipe`"); diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs index 48cf8d9ef..75ab32382 100644 --- a/src/sys/unix/tcp.rs +++ b/src/sys/unix/tcp.rs @@ -87,6 +87,7 @@ pub(crate) fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, target_os = "redox", target_os = "tvos", target_os = "watchos", + target_os = "espidf", all(target_arch = "x86", target_os = "android"), ))] let stream = { @@ -97,10 +98,14 @@ pub(crate) fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, )) .map(|socket| unsafe { net::TcpStream::from_raw_fd(socket) }) .and_then(|s| { + #[cfg(not(target_os = "espidf"))] syscall!(fcntl(s.as_raw_fd(), libc::F_SETFD, libc::FD_CLOEXEC))?; // See https://github.com/tokio-rs/mio/issues/1450 - #[cfg(all(target_arch = "x86", target_os = "android"))] + #[cfg(any( + all(target_arch = "x86", target_os = "android"), + target_os = "espidf", + ))] syscall!(fcntl(s.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK))?; Ok(s) diff --git a/src/sys/unix/uds/listener.rs b/src/sys/unix/uds/listener.rs index 52387a544..6ec51e616 100644 --- a/src/sys/unix/uds/listener.rs +++ b/src/sys/unix/uds/listener.rs @@ -41,6 +41,7 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So target_os = "redox", target_os = "tvos", target_os = "watchos", + target_os = "espidf", // Android x86's seccomp profile forbids calls to `accept4(2)` // See https://github.com/tokio-rs/mio/issues/1445 for details all(target_arch = "x86", target_os = "android"), @@ -63,6 +64,7 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So target_os = "redox", target_os = "tvos", target_os = "watchos", + target_os = "espidf", all(target_arch = "x86", target_os = "android") ))] let socket = syscall!(accept( @@ -74,10 +76,14 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So // Ensure the socket is closed if either of the `fcntl` calls // error below. let s = unsafe { net::UnixStream::from_raw_fd(socket) }; + #[cfg(not(target_os = "espidf"))] syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC))?; // See https://github.com/tokio-rs/mio/issues/1450 - #[cfg(all(target_arch = "x86", target_os = "android"))] + #[cfg(any( + all(target_arch = "x86", target_os = "android"), + target_os = "espidf", + ))] syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK))?; Ok(s) diff --git a/src/sys/unix/uds/mod.rs b/src/sys/unix/uds/mod.rs index ed355ce4e..7ffe498c1 100644 --- a/src/sys/unix/uds/mod.rs +++ b/src/sys/unix/uds/mod.rs @@ -82,6 +82,7 @@ cfg_os_poll! { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "espidf", )))] let flags = flags | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC; @@ -89,7 +90,7 @@ cfg_os_poll! { syscall!(socketpair(libc::AF_UNIX, flags, 0, fds.as_mut_ptr()))?; let pair = unsafe { (T::from_raw_fd(fds[0]), T::from_raw_fd(fds[1])) }; - // Darwin doesn't have SOCK_NONBLOCK or SOCK_CLOEXEC. + // Darwin (and others) doesn't have SOCK_NONBLOCK or SOCK_CLOEXEC. // // In order to set those flags, additional `fcntl` sys calls must be // performed. If a `fnctl` fails after the sockets have been created, @@ -100,11 +101,14 @@ cfg_os_poll! { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "espidf", ))] { syscall!(fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK))?; + #[cfg(not(target_os = "espidf"))] syscall!(fcntl(fds[0], libc::F_SETFD, libc::FD_CLOEXEC))?; syscall!(fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK))?; + #[cfg(not(target_os = "espidf"))] syscall!(fcntl(fds[1], libc::F_SETFD, libc::FD_CLOEXEC))?; } Ok(pair) diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs index 65002d690..344a5edf4 100644 --- a/src/sys/unix/waker.rs +++ b/src/sys/unix/waker.rs @@ -1,6 +1,6 @@ #[cfg(all( not(mio_unsupported_force_waker_pipe), - any(target_os = "linux", target_os = "android") + any(target_os = "linux", target_os = "android", target_os = "espidf") ))] mod eventfd { use crate::sys::Selector; @@ -23,7 +23,12 @@ mod eventfd { impl Waker { pub fn new(selector: &Selector, token: Token) -> io::Result { + #[cfg(not(target_os = "espidf"))] let fd = syscall!(eventfd(0, libc::EFD_CLOEXEC | libc::EFD_NONBLOCK))?; + // ESP-IDF is EFD_NONBLOCK by default and errors if you try to pass this flag. + #[cfg(target_os = "espidf")] + let fd = syscall!(eventfd(0, 0))?; + let file = unsafe { File::from_raw_fd(fd) }; selector.register(fd, token, Interest::READABLE)?; @@ -60,7 +65,7 @@ mod eventfd { #[cfg(all( not(mio_unsupported_force_waker_pipe), - any(target_os = "linux", target_os = "android") + any(target_os = "linux", target_os = "android", target_os = "espidf") ))] pub use self::eventfd::Waker;