Skip to content

Commit c4786f4

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 c9b3a29 commit c4786f4

File tree

5 files changed

+21
-18
lines changed

5 files changed

+21
-18
lines changed

.clippy.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
msrv = "1.46"
1+
msrv = "1.48"

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ jobs:
8989
matrix:
9090
# When updating this, the reminder to update the minimum supported
9191
# Rust version in Cargo.toml and .clippy.toml.
92-
rust: ['1.46']
92+
rust: ['1.48']
9393
steps:
9494
- uses: actions/checkout@v3
9595
- name: Install Rust

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "async-io"
66
version = "1.7.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"
@@ -26,7 +26,7 @@ socket2 = { version = "0.4.2", features = ["all"] }
2626
waker-fn = "1.1.0"
2727

2828
[target."cfg(unix)".dependencies]
29-
libc = "0.2.77"
29+
rustix = { version = "0.35.6-beta.2", features = ["fs"] }
3030

3131
[target.'cfg(windows)'.dependencies]
3232
winapi = { version = "0.3.9", features = ["winsock2"] }
@@ -40,7 +40,6 @@ tempfile = "3"
4040

4141
[target.'cfg(target_os = "linux")'.dev-dependencies]
4242
inotify = { version = "0.10", default-features = false }
43-
nix = { version = "0.24", default-features = false }
4443
timerfd = "1"
4544

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

examples/linux-timerfd.rs

Lines changed: 7 additions & 1 deletion
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

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -525,21 +525,19 @@ impl<T: AsRawFd> Async<T> {
525525
/// # std::io::Result::Ok(()) });
526526
/// ```
527527
pub fn new(io: T) -> io::Result<Async<T>> {
528-
let fd = io.as_raw_fd();
528+
let raw = io.as_raw_fd();
529529

530530
// Put the file descriptor in non-blocking mode.
531-
unsafe {
532-
let mut res = libc::fcntl(fd, libc::F_GETFL);
533-
if res != -1 {
534-
res = libc::fcntl(fd, libc::F_SETFL, res | libc::O_NONBLOCK);
535-
}
536-
if res == -1 {
537-
return Err(io::Error::last_os_error());
538-
}
539-
}
531+
//
532+
// Safety: We assume `as_raw_fd()` returns a valid fd. When
533+
// `AsFd` is stabilized and `TimerFd` implements it, we can
534+
// remove this unsafe and simplify this.
535+
let fd = unsafe { rustix::fd::BorrowedFd::borrow_raw(raw) };
536+
let flags = rustix::fs::fcntl_getfl(&fd)?;
537+
rustix::fs::fcntl_setfl(&fd, flags | rustix::fs::OFlags::NONBLOCK)?;
540538

541539
Ok(Async {
542-
source: Reactor::get().insert_io(fd)?,
540+
source: Reactor::get().insert_io(raw)?,
543541
io: Some(io),
544542
})
545543
}
@@ -1779,7 +1777,7 @@ fn connect(addr: SockAddr, domain: Domain, protocol: Option<Protocol>) -> io::Re
17791777
match socket.connect(&addr) {
17801778
Ok(_) => {}
17811779
#[cfg(unix)]
1782-
Err(err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
1780+
Err(err) if err.raw_os_error() == Some(rustix::io::Errno::INPROGRESS.raw_os_error()) => {}
17831781
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
17841782
Err(err) => return Err(err),
17851783
}

0 commit comments

Comments
 (0)