Skip to content

Commit

Permalink
Replace ioctl-rs crate with libc definitions
Browse files Browse the repository at this point in the history
Constants from tty_ioctl(4) were added to the libc crate in v0.2.19. In
particular, TIOCEXCL, TIOCNXCL, TIOCMBIS, TIOCMBIC, and TIOCMGET are
relevant to this crate. These definitions were previously provided by
the ioctl-rs crate. As the diffstat for this commit shows, the remaining
utility of ioctl-rs (providing a safe wrapper around ioctl) isn't enough
of a value-add to warrant keeping it as a dependency.

Less is more.
  • Loading branch information
dcuddeback authored and KoffeinFlummi committed Aug 23, 2020
1 parent 7df0772 commit 5fe2a1b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 42 deletions.
1 change: 0 additions & 1 deletion serial-unix/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ categories = ["hardware-support", "os", "os::unix-apis"]
[dependencies]
serial-core = { version = "0.4", path = "../serial-core" }
libc = "0.2.21"
ioctl-rs = "0.1.5"
12 changes: 0 additions & 12 deletions serial-unix/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

use core;

use std::error::Error;
use std::ffi::CStr;
use std::io;
use std::str;
Expand All @@ -47,17 +46,6 @@ pub fn from_raw_os_error(errno: i32) -> core::Error {
core::Error::new(kind, error_string(errno))
}

pub fn from_io_error(io_error: io::Error) -> core::Error {
match io_error.raw_os_error() {
Some(errno) => from_raw_os_error(errno),
None => {
let description = io_error.description().to_string();

core::Error::new(core::ErrorKind::Io(io_error.kind()), description)
}
}
}

// the rest of this module is borrowed from libstd

const TMPBUF_SZ: usize = 128;
Expand Down
1 change: 0 additions & 1 deletion serial-unix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
extern crate serial_core as core;
extern crate libc;
extern crate ioctl_rs as ioctl;

pub use tty::*;

Expand Down
69 changes: 41 additions & 28 deletions serial-unix/src/tty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

use core;
use libc;
use ioctl;

use std::ffi::CString;
use std::fmt;
Expand Down Expand Up @@ -63,7 +62,7 @@ impl TTYPort {
/// * `InvalidInput` if `port` is not a valid device name.
/// * `Io` for any other error while opening or initializing the device.
pub fn open(path: &Path) -> core::Result<Self> {
use libc::{O_RDWR, O_NOCTTY, O_NONBLOCK, F_SETFL, EINVAL};
use libc::{O_RDWR, O_NOCTTY, O_NONBLOCK, TIOCEXCL, F_SETFL, EINVAL};

let cstr = match CString::new(path.as_os_str().as_bytes()) {
Ok(s) => s,
Expand All @@ -80,14 +79,16 @@ impl TTYPort {
timeout: Duration::from_millis(100),
};

// get exclusive access to device
if let Err(err) = ioctl::tiocexcl(port.fd) {
return Err(super::error::from_io_error(err));
}
unsafe {
// get exclusive access to device
if libc::ioctl(port.fd, TIOCEXCL) < 0 {
return Err(super::error::last_os_error());
}

// clear O_NONBLOCK flag
if unsafe { libc::fcntl(port.fd, F_SETFL, 0) } < 0 {
return Err(super::error::last_os_error());
// clear O_NONBLOCK flag
if libc::fcntl(port.fd, F_SETFL, 0) < 0 {
return Err(super::error::last_os_error());
}
}

// apply initial settings
Expand All @@ -98,33 +99,45 @@ impl TTYPort {
}

fn set_pin(&mut self, pin: c_int, level: bool) -> core::Result<()> {
let retval = if level {
ioctl::tiocmbis(self.fd, pin)
}
else {
ioctl::tiocmbic(self.fd, pin)
use libc::{TIOCMBIS, TIOCMBIC};

let retval = unsafe {
if level {
libc::ioctl(self.fd, TIOCMBIS, &pin)
}
else {
libc::ioctl(self.fd, TIOCMBIC, &pin)
}
};

match retval {
Ok(()) => Ok(()),
Err(err) => Err(super::error::from_io_error(err)),
if retval < 0 {
return Err(super::error::last_os_error());
}

Ok(())
}

fn read_pin(&mut self, pin: c_int) -> core::Result<bool> {
match ioctl::tiocmget(self.fd) {
Ok(pins) => Ok(pins & pin != 0),
Err(err) => Err(super::error::from_io_error(err)),
use libc::{TIOCMGET};

unsafe {
let mut pins: c_int = mem::uninitialized();

if libc::ioctl(self.fd, TIOCMGET, &mut pins) < 0 {
return Err(super::error::last_os_error());
}

Ok(pins & pin != 0)
}
}
}

impl Drop for TTYPort {
fn drop(&mut self) {
#![allow(unused_must_use)]
ioctl::tiocnxcl(self.fd);
use libc::{TIOCNXCL};

unsafe {
libc::ioctl(self.fd, TIOCNXCL);
libc::close(self.fd);
}
}
Expand Down Expand Up @@ -238,27 +251,27 @@ impl SerialDevice for TTYPort {
}

fn set_rts(&mut self, level: bool) -> core::Result<()> {
self.set_pin(ioctl::TIOCM_RTS, level)
self.set_pin(libc::TIOCM_RTS, level)
}

fn set_dtr(&mut self, level: bool) -> core::Result<()> {
self.set_pin(ioctl::TIOCM_DTR, level)
self.set_pin(libc::TIOCM_DTR, level)
}

fn read_cts(&mut self) -> core::Result<bool> {
self.read_pin(ioctl::TIOCM_CTS)
self.read_pin(libc::TIOCM_CTS)
}

fn read_dsr(&mut self) -> core::Result<bool> {
self.read_pin(ioctl::TIOCM_DSR)
self.read_pin(libc::TIOCM_DSR)
}

fn read_ri(&mut self) -> core::Result<bool> {
self.read_pin(ioctl::TIOCM_RI)
self.read_pin(libc::TIOCM_RI)
}

fn read_cd(&mut self) -> core::Result<bool> {
self.read_pin(ioctl::TIOCM_CD)
self.read_pin(libc::TIOCM_CD)
}
}

Expand Down

0 comments on commit 5fe2a1b

Please sign in to comment.