rust2go
rust2go copied to clipboard
cannot find value SOCK_CLOEXEC in crate libc; cannot find value SOCK_NONBLOCK in crate libc
在 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_CLOEXEC
和 SOCK_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_NONBLOCK
和 SOCK_CLOEXEC
标志。对于其他系统,在创建套接字后使用 fcntl
来设置非阻塞模式和 CLOEXEC 标志。
验证
在进行上述修改后,examples/example-monoio-mem
可以在 macOS 上成功编译和运行。
建议
考虑将这个修改合并到主分支,以提高项目在不同 Unix 系统上的兼容性。同时,可以在文档中注明这个平台差异,以帮助其他可能遇到类似问题的开发者。
由于Rust刚入门,此Issue来自AI总结,如有问题请及时更正