Skip to content

Commit a64a491

Browse files
committed
Use rustix instead of direct calls to libc.
Use the [rustix] syscall wrapper crate to factor out error handling and unsafe system calls. This reduces the amount of unsafe code here, and is a step towards factoring it out entirely once [`AsFd`] is stabilized and can replace `AsRawFd` for these kinds of uses. This does require incrementing the minimum required Rust version to 1.48. Please feel free to decline this PR if you don't wish to take on these new requirements. [rustix]: https://crates.io/crates/rustix/ [`AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html
1 parent d3855ac commit a64a491

File tree

4 files changed

+20
-17
lines changed

4 files changed

+20
-17
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ jobs:
9292
matrix:
9393
# When updating this, the reminder to update the minimum supported
9494
# Rust version in Cargo.toml and .clippy.toml.
95-
rust: ['1.46']
95+
rust: ['1.48']
9696
steps:
9797
- uses: actions/checkout@v3
9898
- name: Install Rust

Cargo.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "async-io"
66
version = "1.10.0"
77
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
88
edition = "2018"
9-
rust-version = "1.46"
9+
rust-version = "1.48"
1010
description = "Async I/O and timers"
1111
license = "Apache-2.0 OR MIT"
1212
repository = "https://github.com/smol-rs/async-io"
@@ -33,7 +33,7 @@ waker-fn = "1.1.0"
3333
autocfg = "1"
3434

3535
[target."cfg(unix)".dependencies]
36-
libc = "0.2.77"
36+
rustix = { version = "0.36.0", features = ["fs"] }
3737

3838
[target.'cfg(windows)'.dependencies]
3939
winapi = { version = "0.3.9", features = ["winsock2"] }
@@ -49,7 +49,6 @@ tempfile = "3"
4949

5050
[target.'cfg(target_os = "linux")'.dev-dependencies]
5151
inotify = { version = "0.10", default-features = false }
52-
nix = { version = "0.25", default-features = false }
5352
timerfd = "1"
5453

5554
[target.'cfg(windows)'.dev-dependencies]

examples/linux-timerfd.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn main() -> std::io::Result<()> {
1414

1515
use async_io::Async;
1616
use futures_lite::future;
17+
use rustix::fd::BorrowedFd;
1718
use timerfd::{SetTimeFlags, TimerFd, TimerState};
1819

1920
/// Sleeps using an OS timer.
@@ -24,7 +25,12 @@ fn main() -> std::io::Result<()> {
2425

2526
// When the OS timer fires, a 64-bit integer can be read from it.
2627
Async::new(timer)?
27-
.read_with(|t| nix::unistd::read(t.as_raw_fd(), &mut [0u8; 8]).map_err(io::Error::from))
28+
.read_with(|t| {
29+
// Safety: Assume `as_raw_fd()` returns a valid fd; when `AsFd`
30+
// is stabilized, we can remove this unsafe and simplify.
31+
let fd = unsafe { BorrowedFd::borrow_raw(t.as_raw_fd()) };
32+
rustix::io::read(&fd, &mut [0u8; 8]).map_err(io::Error::from)
33+
})
2834
.await?;
2935
Ok(())
3036
}

src/lib.rs

+10-12
Original file line numberDiff line numberDiff line change
@@ -598,21 +598,19 @@ impl<T: AsRawFd> Async<T> {
598598
/// # std::io::Result::Ok(()) });
599599
/// ```
600600
pub fn new(io: T) -> io::Result<Async<T>> {
601-
let fd = io.as_raw_fd();
601+
let raw = io.as_raw_fd();
602602

603603
// Put the file descriptor in non-blocking mode.
604-
unsafe {
605-
let mut res = libc::fcntl(fd, libc::F_GETFL);
606-
if res != -1 {
607-
res = libc::fcntl(fd, libc::F_SETFL, res | libc::O_NONBLOCK);
608-
}
609-
if res == -1 {
610-
return Err(io::Error::last_os_error());
611-
}
612-
}
604+
//
605+
// Safety: We assume `as_raw_fd()` returns a valid fd. When
606+
// `AsFd` is stabilized and `TimerFd` implements it, we can
607+
// remove this unsafe and simplify this.
608+
let fd = unsafe { rustix::fd::BorrowedFd::borrow_raw(raw) };
609+
let flags = rustix::fs::fcntl_getfl(&fd)?;
610+
rustix::fs::fcntl_setfl(&fd, flags | rustix::fs::OFlags::NONBLOCK)?;
613611

614612
Ok(Async {
615-
source: Reactor::get().insert_io(fd)?,
613+
source: Reactor::get().insert_io(raw)?,
616614
io: Some(io),
617615
})
618616
}
@@ -1902,7 +1900,7 @@ fn connect(addr: SockAddr, domain: Domain, protocol: Option<Protocol>) -> io::Re
19021900
match socket.connect(&addr) {
19031901
Ok(_) => {}
19041902
#[cfg(unix)]
1905-
Err(err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
1903+
Err(err) if err.raw_os_error() == Some(rustix::io::Errno::INPROGRESS.raw_os_error()) => {}
19061904
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
19071905
Err(err) => return Err(err),
19081906
}

0 commit comments

Comments
 (0)