Skip to content

Commit

Permalink
Add ESP-IDF framework support
Browse files Browse the repository at this point in the history
Mostly fixing compiler errors but also working around nonblocking issues
with accept, eventfd, etc.

Closes tokio-rs#1691
  • Loading branch information
jasta committed Jul 18, 2023
1 parent 0639d6a commit b763d29
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 6 deletions.
6 changes: 5 additions & 1 deletion src/sys/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
};
Expand All @@ -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")]
Expand Down
2 changes: 2 additions & 0 deletions src/sys/unix/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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`");

Expand Down
7 changes: 6 additions & 1 deletion src/sys/unix/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion src/sys/unix/uds/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand All @@ -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(
Expand All @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion src/sys/unix/uds/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ cfg_os_poll! {
target_os = "macos",
target_os = "tvos",
target_os = "watchos",
target_os = "espidf",
)))]
let flags = flags | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;

let mut fds = [-1; 2];
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,
Expand All @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions src/sys/unix/waker.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -23,7 +23,12 @@ mod eventfd {

impl Waker {
pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
#[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)?;
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit b763d29

Please sign in to comment.