Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot find value SOCK_CLOEXEC in crate libc; cannot find value SOCK_NONBLOCK in crate libc #29

Open
powerttt opened this issue Oct 14, 2024 · 0 comments

Comments

@powerttt
Copy link

在 macOS 上运行 example-monoio-mem 时遇到的问题及解决方案

环境信息

  • 操作系统:macOS 15.0 (24A335)
  • Rust 版本:rustc 1.81.0 (eeb90cda1 2024-09-04) (Homebrew)

问题描述

在 macOS 上克隆并运行项目时,examples/example-monoio 可以正常运行,但 examples/example-monoio-mem 出现编译错误。错误信息如下:

error[E0425]: cannot find value SOCK_CLOEXEC in crate libc
error[E0425]: cannot find value SOCK_NONBLOCK in crate libc

这个问题是由于 macOS 上 libc crate 中缺少 SOCK_CLOEXECSOCK_NONBLOCK 常量导致的。

解决方案

修改 mem-ring/src/eventfd.rs 文件,使用条件编译来处理不同平台的差异。以下是修改后的代码:

use std::{
    cell::UnsafeCell,
    io::Error,
    os::unix::io::{AsRawFd, FromRawFd, RawFd},
};

#[cfg(feature = "monoio")]
use monoio::{buf::RawBuf, io::AsyncReadRent, net::UnixStream};

#[cfg(all(feature = "tokio", not(feature = "monoio")))]
use tokio::{io::AsyncReadExt, net::UnixStream};

pub(crate) fn new_pair() -> Result<(RawFd, RawFd), Error> {
    let mut fds = [-1; 2];
    let mut flags = libc::SOCK_STREAM;

    #[cfg(any(target_os = "linux", target_os = "android"))]
    {
        flags |= libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
    }

    if unsafe {
        libc::socketpair(
            libc::AF_UNIX,
            flags,
            0,
            fds.as_mut_ptr(),
        )
    } == -1
    {
        return Err(Error::last_os_error());
    }

    #[cfg(not(any(target_os = "linux", target_os = "android")))]
    {
        for &fd in &fds {
            unsafe {
                // 设置非阻塞
                let flags = libc::fcntl(fd, libc::F_GETFL);
                libc::fcntl(fd, libc::F_SETFL, flags | libc::O_NONBLOCK);
                
                // 设置 CLOEXEC
                libc::fcntl(fd, libc::F_SETFD, libc::FD_CLOEXEC);
            }
        }
    }

    Ok((fds[0], fds[1]))
}

这个修改使用条件编译来处理 Linux/Android 和其他 Unix 系统(如 macOS)之间的差异。对于 Linux 和 Android,直接在 socketpair 调用中使用 SOCK_NONBLOCKSOCK_CLOEXEC 标志。对于其他系统,在创建套接字后使用 fcntl 来设置非阻塞模式和 CLOEXEC 标志。

验证

在进行上述修改后,examples/example-monoio-mem 可以在 macOS 上成功编译和运行。

建议

考虑将这个修改合并到主分支,以提高项目在不同 Unix 系统上的兼容性。同时,可以在文档中注明这个平台差异,以帮助其他可能遇到类似问题的开发者。

由于Rust刚入门,此Issue来自AI总结,如有问题请及时更正

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant