Skip to content

Commit

Permalink
Merge branch 'master' into no-vmin
Browse files Browse the repository at this point in the history
  • Loading branch information
estokes authored Dec 31, 2024
2 parents 67de90b + 5385318 commit 5f26edc
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 85 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/github-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
rust:
- stable
- beta
- 1.46.0
- 1.70.0
# - nightly
env:
TEST_PORT_A: /tmp/ttyS10
Expand Down Expand Up @@ -43,7 +43,7 @@ jobs:
rust:
- stable
- beta
- 1.46.0
- 1.70.0
# - nightly
env:
TEST_PORT_A: /tmp/ttyS10
Expand Down Expand Up @@ -81,7 +81,7 @@ jobs:
rust:
- stable
- beta
- 1.46.0
- 1.70.0
# - nightly
env:
TEST_PORT_A: COM10
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [5.0.3 and 5.0.4] 2023-01-12
- update dependencies

## [5.0.2] 2022-03-04
- merged [#28](https://github.com/berkowski/mio-serial/pull/28)
- update dependencies
Expand Down
15 changes: 8 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
[package]
name = "mio-serial"
version = "5.0.3"
version = "5.0.6"
authors = ["Zac Berkowitz <zac.berkowitz@gmail.com>"]
description = "A serial port implementation for mio"
license = "MIT"
homepage = "https://github.com/berkowski/mio-serial"
repository = "https://github.com/berkowski/mio-serial"
documentation = "http://docs.rs/mio-serial"
documentation = "https://docs.rs/mio-serial"
readme = "README.md"
keywords = ["rs232", "serial", "mio"]
categories = ["asynchronous", "hardware-support"]
edition = "2018"
edition = "2021"

[package.metadata]
msrv = "1.46.0" # Used by cargo-msrv
msrv = "1.70.0" # Used by cargo-msrv

[features]
default = []
libudev = ["serialport/libudev"]
serde = ["serialport/serde"]

[dependencies.mio]
version = "0.8"
version = "1"
features = ["os-poll", "os-ext"]

[dependencies.serialport]
Expand All @@ -31,7 +32,7 @@ default-features = false
version = "0.4"

[target.'cfg(unix)'.dependencies]
nix = "0.25"
nix = { version = "0.29", features = ["term"] }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = [
Expand All @@ -42,7 +43,7 @@ winapi = { version = "0.3", features = [
] }

[dev-dependencies.env_logger]
version = "0.9"
version = "0.11"

[[example]]
name = "read_serialport"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ cargo build --no-default-features
```

### MSRV
The Minimum Supported Rust Version is **1.46.0** as found using [cargo-msrv](https://crates.io/crates/cargo-msrv)
The Minimum Supported Rust Version is **1.70.0** as found using [cargo-msrv](https://crates.io/crates/cargo-msrv)

## Examples
A few examples can be found [here](https://github.com/berkowski/mio-serial/tree/master/examples).
Expand Down
22 changes: 11 additions & 11 deletions examples/read_serialport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
extern crate mio;
extern crate mio_serial;

use log::error;
use mio::{Events, Interest, Poll, Token};

use std::env;
Expand Down Expand Up @@ -32,7 +33,7 @@ pub fn main() -> io::Result<()> {
let mut events = Events::with_capacity(1);

// Create the serial port
println!("Opening {} at 9600,8N1", path);
println!("Opening {path} at 9600,8N1");
let mut rx = mio_serial::new(path, DEFAULT_BAUD).open_native_async()?;

// #[cfg(unix)]
Expand All @@ -55,28 +56,27 @@ pub fn main() -> io::Result<()> {
// Validate the token we registered our socket with,
// in this example it will only ever be one but we
// make sure it's valid none the less.
match event.token() {
SERIAL_TOKEN => loop {
if event.token() == SERIAL_TOKEN {
loop {
// In this loop we receive all packets queued for the socket.
match rx.read(&mut buf) {
Ok(count) => {
println!("{:?}", String::from_utf8_lossy(&buf[..count]))
println!("{:?}", String::from_utf8_lossy(&buf[..count]));
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
break;
}
Err(e) => {
println!("Quitting due to read error: {}", e);
println!("Quitting due to read error: {e}");
return Err(e);
}
}
},
_ => {
// This should never happen as we only registered our
// `UdpSocket` using the `UDP_SOCKET` token, but if it ever
// does we'll log it.
// warn!("Got event for unexpected token: {:?}", event);
}
} else {
// This should never happen as we only registered our
// `UdpSocket` using the `UDP_SOCKET` token, but if it ever
// does we'll log it.
error!("Got event for unexpected token: {:?}", event);
}
}
}
Expand Down
32 changes: 18 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ pub use serialport::available_ports;
pub use serialport::new;

use mio::{event::Source, Interest, Registry, Token};
use std::convert::TryFrom;
use std::io::{Error as StdIoError, ErrorKind as StdIoErrorKind, Result as StdIoResult};
use std::time::Duration;

Expand Down Expand Up @@ -74,7 +73,7 @@ mod os_prelude {
}
use os_prelude::*;

/// SerialStream
/// A [`SerialStream`].
#[derive(Debug)]
pub struct SerialStream {
#[cfg(unix)]
Expand Down Expand Up @@ -179,7 +178,7 @@ impl SerialStream {
/// https://github.com/tokio-rs/tokio/pull/3760#issuecomment-839854617) I would rather not
/// have any enabled code over a kind-of-works-maybe impl. So I'll leave this code here
/// for now but hard-code it disabled.
#[cfg(never)]
#[cfg(any())]
pub fn try_clone_native(&self) -> Result<SerialStream> {
// This works so long as the underlying serialport-rs method doesn't do anything but
// duplicate the low-level file descriptor. This is the case as of serialport-rs:4.0.1
Expand Down Expand Up @@ -487,12 +486,12 @@ impl crate::SerialPort for SerialStream {
///
/// This function returns an error if the serial port couldn't be cloned.
#[inline(always)]
#[cfg(never)]
#[cfg(any())]
fn try_clone(&self) -> crate::Result<Box<dyn crate::SerialPort>> {
Ok(Box::new(self.try_clone_native()?))
}

/// Cloning is not supported for SerialStream objects
/// Cloning is not supported for [`SerialStream`] objects
///
/// This logic has never really completely worked. Cloned file descriptors in asynchronous
/// code is a semantic minefield. Are you cloning the file descriptor? Are you cloning the
Expand All @@ -501,8 +500,8 @@ impl crate::SerialPort for SerialStream {
///
/// Maybe it can be done with more work, but until a clear use-case is required (or mio/tokio
/// gets an equivalent of the unix `AsyncFd` for async file handles, see
/// https://github.com/tokio-rs/tokio/issues/3781 and
/// https://github.com/tokio-rs/tokio/pull/3760#issuecomment-839854617) I would rather not
/// <https://github.com/tokio-rs/tokio/issues/3781> and
/// <https://github.com/tokio-rs/tokio/pull/3760#issuecomment-839854617>) I would rather not
/// have any code available over a kind-of-works-maybe impl. So I'll leave this code here
/// for now but hard-code it disabled.
fn try_clone(&self) -> crate::Result<Box<dyn crate::SerialPort>> {
Expand Down Expand Up @@ -585,7 +584,6 @@ impl TryFrom<NativeBlockingSerialPort> for SerialStream {
log::error!("unable to open new async file handle");
return Err(crate::Error::from(StdIoError::last_os_error()));
}
let handle = unsafe { mem::transmute(handle) };

// Construct NamedPipe and COMPort from Handle
//
Expand Down Expand Up @@ -656,7 +654,7 @@ mod io {
uninterruptibly!(match unsafe {
libc::write(
self.as_raw_fd(),
bytes.as_ptr() as *const libc::c_void,
bytes.as_ptr().cast::<libc::c_void>(),
bytes.len() as libc::size_t,
)
} {
Expand All @@ -666,7 +664,10 @@ mod io {
}

fn flush(&mut self) -> StdIoResult<()> {
uninterruptibly!(termios::tcdrain(self.inner.as_raw_fd()).map_err(StdIoError::from))
uninterruptibly!(termios::tcdrain(unsafe {
BorrowedFd::borrow_raw(self.inner.as_raw_fd())
})
.map_err(StdIoError::from))
}
}

Expand Down Expand Up @@ -700,7 +701,10 @@ mod io {
}

fn flush(&mut self) -> StdIoResult<()> {
uninterruptibly!(termios::tcdrain(self.inner.as_raw_fd()).map_err(StdIoError::from))
uninterruptibly!(termios::tcdrain(unsafe {
BorrowedFd::borrow_raw(self.inner.as_raw_fd())
})
.map_err(StdIoError::from))
}
}
}
Expand Down Expand Up @@ -863,13 +867,13 @@ impl Source for SerialStream {
}
}

/// An extension trait for SerialPortBuilder
/// An extension trait for [`SerialPortBuilder`]
///
/// This trait adds an additional method to SerialPortBuilder:
/// This trait adds an additional method to [`SerialPortBuilder`]:
///
/// - open_native_async
///
/// These methods mirror the `open_native` methods of SerialPortBuilder
/// These methods mirror the [`SerialPortBuilder::open_native`] methods
pub trait SerialPortBuilderExt {
/// Open a platform-specific interface to the port with the specified settings
fn open_native_async(self) -> Result<SerialStream>;
Expand Down
33 changes: 18 additions & 15 deletions tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ static LOGGING_INIT: Once = Once::new();

/// Default serial port names used for testing
#[cfg(unix)]
const DEFAULT_TEST_PORT_NAMES: &'static str = "/tty/USB0;/tty/USB1";
const DEFAULT_TEST_PORT_NAMES: &str = "USB0;USB1";

/// Default serial port names used for testing
#[cfg(windows)]
const DEFAULT_TEST_PORT_NAMES: &'static str = "COM1;COM2";
const DEFAULT_TEST_PORT_NAMES: &str = "COM1;COM2";

#[derive(Debug)]
pub struct Readiness(usize);
Expand All @@ -31,7 +31,7 @@ const READABLE: usize = 0b0000_0001;
const WRITABLE: usize = 0b0000_0010;
const AIO: usize = 0b0000_0100;
const LIO: usize = 0b0000_1000;
const ERROR: usize = 0b00010000;
const ERROR: usize = 0b0001_0000;
const READ_CLOSED: usize = 0b0010_0000;
const WRITE_CLOSED: usize = 0b0100_0000;
const PRIORITY: usize = 0b1000_0000;
Expand Down Expand Up @@ -92,6 +92,7 @@ impl From<Interest> for Readiness {
}
}

#[must_use]
pub fn init_with_poll() -> (Poll, Events) {
let poll = Poll::new().expect("unable to create poll object");
let events = Events::with_capacity(16);
Expand Down Expand Up @@ -148,16 +149,15 @@ pub fn expect_events(poll: &mut Poll, events: &mut Events, mut expected: Vec<Exp

assert!(
expected.is_empty(),
"the following expected events were not found: {:?}",
expected
"the following expected events were not found: {expected:?}",
);
}

pub fn assert_would_block(result: std::io::Result<usize>) {
match result {
Ok(_) => panic!("unexpected OK result, expected a `WouldBlock` error"),
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {}
Err(e) => panic!("unexpected error result: {}", e),
Err(e) => panic!("unexpected error result: {e}"),
}
}

Expand Down Expand Up @@ -185,20 +185,25 @@ pub struct Fixture {
impl Drop for Fixture {
fn drop(&mut self) {
log::trace!("stopping socat process (id: {})...", self.process.id());

self.process.kill().ok();
thread::sleep(Duration::from_millis(250));
log::trace!("removing link: {}", self.port_a);
std::fs::remove_file(self.port_a).ok();
log::trace!("removing link: {}", self.port_b);
std::fs::remove_file(self.port_b).ok();
thread::sleep(Duration::from_millis(1000));
log::trace!("removing link: {:?}", self.port_a);
std::fs::remove_file(&self.port_a).ok();
log::trace!("removing link: {:?}", self.port_b);
std::fs::remove_file(&self.port_b).ok();
thread::sleep(Duration::from_millis(1000));
}
}

impl Fixture {
#[cfg(unix)]
pub fn new(port_a: &'static str, port_b: &'static str) -> Self {
use std::sync::atomic::{AtomicUsize, Ordering};
static N: AtomicUsize = AtomicUsize::new(0);
LOGGING_INIT.call_once(|| env_logger::init());
let n = N.fetch_add(1, Ordering::Relaxed);
let port_a = format!("{}{}", port_a, n).leak();
let port_b = format!("{}{}", port_b, n).leak();
let args = [
format!("PTY,link={}", port_a),
format!("PTY,link={}", port_b),
Expand All @@ -210,9 +215,7 @@ impl Fixture {
.spawn()
.expect("unable to spawn socat process");
log::trace!(".... done! (pid: {:?})", process.id());

thread::sleep(Duration::from_millis(500));

thread::sleep(Duration::from_millis(1000));
Self {
process,
port_a,
Expand Down
Loading

0 comments on commit 5f26edc

Please sign in to comment.