Skip to content

Commit

Permalink
Use rustix instead of direct calls to libc.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sunfishcode committed Jun 7, 2022
1 parent c9b3a29 commit c4786f4
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
msrv = "1.46"
msrv = "1.48"
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:
matrix:
# When updating this, the reminder to update the minimum supported
# Rust version in Cargo.toml and .clippy.toml.
rust: ['1.46']
rust: ['1.48']
steps:
- uses: actions/checkout@v3
- name: Install Rust
Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ name = "async-io"
version = "1.7.0"
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
edition = "2018"
rust-version = "1.46"
rust-version = "1.48"
description = "Async I/O and timers"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/smol-rs/async-io"
Expand All @@ -26,7 +26,7 @@ socket2 = { version = "0.4.2", features = ["all"] }
waker-fn = "1.1.0"

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

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

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

[target.'cfg(windows)'.dev-dependencies]
Expand Down
8 changes: 7 additions & 1 deletion examples/linux-timerfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ fn main() -> std::io::Result<()> {

use async_io::Async;
use futures_lite::future;
use rustix::fd::BorrowedFd;
use timerfd::{SetTimeFlags, TimerFd, TimerState};

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

// When the OS timer fires, a 64-bit integer can be read from it.
Async::new(timer)?
.read_with(|t| nix::unistd::read(t.as_raw_fd(), &mut [0u8; 8]).map_err(io::Error::from))
.read_with(|t| {
// Safety: Assume `as_raw_fd()` returns a valid fd; when `AsFd`
// is stabilized, we can remove this unsafe and simplify.
let fd = unsafe { BorrowedFd::borrow_raw(t.as_raw_fd()) };
rustix::io::read(&fd, &mut [0u8; 8]).map_err(io::Error::from)
})
.await?;
Ok(())
}
Expand Down
22 changes: 10 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,21 +525,19 @@ impl<T: AsRawFd> Async<T> {
/// # std::io::Result::Ok(()) });
/// ```
pub fn new(io: T) -> io::Result<Async<T>> {
let fd = io.as_raw_fd();
let raw = io.as_raw_fd();

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

Ok(Async {
source: Reactor::get().insert_io(fd)?,
source: Reactor::get().insert_io(raw)?,
io: Some(io),
})
}
Expand Down Expand Up @@ -1779,7 +1777,7 @@ fn connect(addr: SockAddr, domain: Domain, protocol: Option<Protocol>) -> io::Re
match socket.connect(&addr) {
Ok(_) => {}
#[cfg(unix)]
Err(err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
Err(err) if err.raw_os_error() == Some(rustix::io::Errno::INPROGRESS.raw_os_error()) => {}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
Err(err) => return Err(err),
}
Expand Down

0 comments on commit c4786f4

Please sign in to comment.