diff --git a/Cargo.toml b/Cargo.toml index a24938a..7ea4095 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ license = "MIT OR Apache-2.0" [dependencies] bitflags = "1.0" -error-chain = "0.12" libc = "0.2" nix = "0.14" [dev-dependencies] quicli = "0.2" +anyhow = "1.0" diff --git a/examples/blinky.rs b/examples/blinky.rs index 4236fdf..85dcaa0 100644 --- a/examples/blinky.rs +++ b/examples/blinky.rs @@ -15,6 +15,7 @@ use quicli::prelude::*; use std::thread::sleep; use std::time::{Duration, Instant}; + #[derive(Debug, StructOpt)] struct Cli { /// The gpiochip device (e.g. /dev/gpiochip0) @@ -27,7 +28,7 @@ struct Cli { duration_ms: u64, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; // NOTE: we set the default value to the desired state so diff --git a/examples/driveoutput.rs b/examples/driveoutput.rs index 910ae3c..f049bf7 100644 --- a/examples/driveoutput.rs +++ b/examples/driveoutput.rs @@ -23,7 +23,7 @@ struct Cli { value: u8, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; // NOTE: we set the default value to the desired state so diff --git a/examples/gpioevents.rs b/examples/gpioevents.rs index fc50776..4c0ffab 100644 --- a/examples/gpioevents.rs +++ b/examples/gpioevents.rs @@ -13,6 +13,7 @@ extern crate quicli; use gpio_cdev::*; use quicli::prelude::*; + #[derive(Debug, StructOpt)] struct Cli { /// The gpiochip device (e.g. /dev/gpiochip0) @@ -21,7 +22,7 @@ struct Cli { line: u32, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; let line = chip.get_line(args.line)?; diff --git a/examples/monitor.rs b/examples/monitor.rs index 672e8b1..803fab9 100644 --- a/examples/monitor.rs +++ b/examples/monitor.rs @@ -8,12 +8,14 @@ extern crate gpio_cdev; extern crate nix; -#[macro_use] extern crate quicli; +#[macro_use] +extern crate quicli; +extern crate anyhow; use gpio_cdev::*; -use quicli::prelude::*; use nix::poll::*; -use std::os::unix::io::{AsRawFd}; +use quicli::prelude::*; +use std::os::unix::io::AsRawFd; type PollEventFlags = nix::poll::PollFlags; @@ -25,27 +27,40 @@ struct Cli { lines: Vec, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> anyhow::Result<()> { let mut chip = Chip::new(args.chip)?; // Get event handles for each line to monitor. - let mut evt_handles: Vec = args.lines.into_iter().map(|off| { - let line = chip.get_line(off).unwrap(); - line.events(LineRequestFlags::INPUT, EventRequestFlags::BOTH_EDGES, - "monitor").unwrap() - }).collect(); + let mut evt_handles: Vec = args + .lines + .into_iter() + .map(|off| { + let line = chip.get_line(off).unwrap(); + line.events( + LineRequestFlags::INPUT, + EventRequestFlags::BOTH_EDGES, + "monitor", + ) + .unwrap() + }) + .collect(); // Create a vector of file descriptors for polling - let mut pollfds: Vec = evt_handles.iter().map(|h| { - PollFd::new(h.as_raw_fd(), PollEventFlags::POLLIN | PollEventFlags::POLLPRI) - }).collect(); + let mut pollfds: Vec = evt_handles + .iter() + .map(|h| { + PollFd::new( + h.as_raw_fd(), + PollEventFlags::POLLIN | PollEventFlags::POLLPRI, + ) + }) + .collect(); loop { // poll for an event on any of the lines if poll(&mut pollfds, -1)? == 0 { println!("Timeout?!?"); - } - else { + } else { for i in 0..pollfds.len() { if let Some(revts) = pollfds[i].revents() { let h = &mut evt_handles[i]; @@ -58,9 +73,8 @@ fn do_main(args: Cli) -> errors::Result<()> { // to read the value of the bit. let val = h.get_value()?; println!(" {}", val); - } - else if revts.contains(PollEventFlags::POLLPRI) { - println!("[{}] Got a POLLPRI", h.line().offset()); + } else if revts.contains(PollEventFlags::POLLPRI) { + println!("[{}] Got a POLLPRI", h.line().offset()); } } } @@ -70,7 +84,7 @@ fn do_main(args: Cli) -> errors::Result<()> { main!(|args: Cli| { match do_main(args) { - Ok(()) => {}, + Ok(()) => {} Err(e) => { println!("Error: {:?}", e); } diff --git a/examples/multioutput.rs b/examples/multioutput.rs index 5a1891e..9d17cd2 100644 --- a/examples/multioutput.rs +++ b/examples/multioutput.rs @@ -28,7 +28,7 @@ struct Cli { // to set lines 0, 1, & 3 high // 2 & 4 low // -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; let mut offsets = Vec::new(); let mut values = Vec::new(); diff --git a/examples/multiread.rs b/examples/multiread.rs index 1dc12f2..e17d7a9 100644 --- a/examples/multiread.rs +++ b/examples/multiread.rs @@ -21,7 +21,7 @@ struct Cli { lines: Vec, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; let ini_vals = vec![ 0; args.lines.len() ]; let handle = chip diff --git a/examples/readall.rs b/examples/readall.rs index b565d1e..7aac87d 100644 --- a/examples/readall.rs +++ b/examples/readall.rs @@ -19,9 +19,9 @@ struct Cli { chip: String, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; - let ini_vals = vec![ 0; chip.num_lines() as usize ]; + let ini_vals = vec![0; chip.num_lines() as usize]; let handle = chip .get_all_lines()? .request(LineRequestFlags::INPUT, &ini_vals, "readall")?; diff --git a/examples/readinput.rs b/examples/readinput.rs index 07b36dd..67bbd3a 100644 --- a/examples/readinput.rs +++ b/examples/readinput.rs @@ -21,7 +21,7 @@ struct Cli { line: u32, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; let handle = chip .get_line(args.line)? diff --git a/examples/tit_for_tat.rs b/examples/tit_for_tat.rs index 275fd52..8be9d89 100644 --- a/examples/tit_for_tat.rs +++ b/examples/tit_for_tat.rs @@ -15,6 +15,7 @@ use quicli::prelude::*; use std::thread::sleep; use std::time::Duration; + #[derive(Debug, StructOpt)] struct Cli { /// The gpiochip device (e.g. /dev/gpiochip0) @@ -27,7 +28,7 @@ struct Cli { sleeptime: u64, } -fn do_main(args: Cli) -> errors::Result<()> { +fn do_main(args: Cli) -> std::result::Result<(), errors::Error> { let mut chip = Chip::new(args.chip)?; let input = chip.get_line(args.inputline)?; let output = chip.get_line(args.outputline)?; diff --git a/src/errors.rs b/src/errors.rs index 6d92f27..2e59ba5 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,21 +1,101 @@ -// Copyright (c) 2018 The rust-gpio-cdev Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -error_chain! { - types { - Error, - ErrorKind, - ResultExt, - Result; - } - - foreign_links { - Nix(::nix::Error); - Io(::std::io::Error); +use std::error::Error as StdError; +use std::fmt; +use std::io::Error as IOError; + +pub(crate) type Result = std::result::Result; + +#[derive(Debug)] +pub struct Error { + kind: ErrorKind, +} + +#[derive(Debug)] +pub enum IoctlKind { + ChipInfo, + LineInfo, + LineHandle, + LineEvent, + GetLine, + SetLine, +} + +#[derive(Debug)] +pub enum ErrorKind { + Event(nix::Error), + Io(IOError), + Ioctl { kind: IoctlKind, cause: nix::Error }, + InvalidRequest(usize, usize), + Offset(u32), +} + +pub(crate) fn ioctl_err(kind: IoctlKind, cause: nix::Error) -> Error { + Error { + kind: ErrorKind::Ioctl { kind, cause }, + } +} + +pub(crate) fn invalid_err(n_lines: usize, n_values: usize) -> Error { + Error { + kind: ErrorKind::InvalidRequest(n_lines, n_values), + } +} + +pub(crate) fn offset_err(offset: u32) -> Error { + Error { + kind: ErrorKind::Offset(offset), + } +} + +pub(crate) fn event_err(err: nix::Error) -> Error { + Error { + kind: ErrorKind::Event(err), + } +} + +impl fmt::Display for IoctlKind { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + IoctlKind::ChipInfo => write!(f, "get chip info"), + IoctlKind::LineInfo => write!(f, "get line info"), + IoctlKind::LineHandle => write!(f, "get line handle"), + IoctlKind::LineEvent => write!(f, "get line event "), + IoctlKind::GetLine => write!(f, "get line value"), + IoctlKind::SetLine => write!(f, "set line value"), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.kind { + ErrorKind::Event(err) => write!(f, "Failed to read event: {}", err), + ErrorKind::Io(err) => err.fmt(f), + ErrorKind::Ioctl { cause, kind } => write!(f, "Ioctl to {} failed: {}", kind, cause), + ErrorKind::InvalidRequest(n_lines, n_values) => write!( + f, + "Invalid request: {} values requested to be set but only {} lines are open", + n_values, n_lines + ), + ErrorKind::Offset(offset) => write!(f, "Offset {} is out of range", offset), + } + } +} + +impl StdError for Error { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + match &self.kind { + ErrorKind::Event(err) => Some(err), + ErrorKind::Io(err) => Some(err), + ErrorKind::Ioctl { kind: _, cause } => Some(cause), + _ => None, + } + } +} + +impl From for Error { + fn from(err: IOError) -> Error { + Error { + kind: ErrorKind::Io(err), + } } } diff --git a/src/ffi.rs b/src/ffi.rs index 40691f5..c45a893 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -6,6 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use super::errors::IoctlKind; use libc; pub const GPIOHANDLES_MAX: usize = 64; @@ -56,10 +57,52 @@ pub struct gpioevent_data { pub id: u32, } -ioctl_read!(gpio_get_chipinfo_ioctl, 0xB4, 0x01, gpiochip_info); -ioctl_readwrite!(gpio_get_lineinfo_ioctl, 0xB4, 0x02, gpioline_info); -ioctl_readwrite!(gpio_get_linehandle_ioctl, 0xB4, 0x03, gpiohandle_request); -ioctl_readwrite!(gpio_get_lineevent_ioctl, 0xB4, 0x04, gpioevent_request); +macro_rules! wrap_ioctl { + ($ioctl_macro:ident!($name:ident, $ioty:expr, $nr:expr, $ty:ident), $ioctl_error_type:expr) => { + mod $name { + $ioctl_macro!($name, $ioty, $nr, super::$ty); + } -ioctl_readwrite!(gpiohandle_get_line_values_ioctl, 0xB4, 0x08, gpiohandle_data); -ioctl_readwrite!(gpiohandle_set_line_values_ioctl, 0xB4, 0x09, gpiohandle_data); + pub(crate) fn $name(fd: libc::c_int, data: &mut $ty) -> crate::errors::Result { + unsafe { + $name::$name(fd, data).map_err(|e| crate::errors::ioctl_err($ioctl_error_type, e)) + } + } + }; +} + +wrap_ioctl!( + ioctl_read!(gpio_get_chipinfo_ioctl, 0xB4, 0x01, gpiochip_info), + IoctlKind::ChipInfo +); +wrap_ioctl!( + ioctl_readwrite!(gpio_get_lineinfo_ioctl, 0xB4, 0x02, gpioline_info), + IoctlKind::LineInfo +); +wrap_ioctl!( + ioctl_readwrite!(gpio_get_linehandle_ioctl, 0xB4, 0x03, gpiohandle_request), + IoctlKind::LineHandle +); +wrap_ioctl!( + ioctl_readwrite!(gpio_get_lineevent_ioctl, 0xB4, 0x04, gpioevent_request), + IoctlKind::LineEvent +); + +wrap_ioctl!( + ioctl_readwrite!( + gpiohandle_get_line_values_ioctl, + 0xB4, + 0x08, + gpiohandle_data + ), + IoctlKind::GetLine +); +wrap_ioctl!( + ioctl_readwrite!( + gpiohandle_set_line_values_ioctl, + 0xB4, + 0x09, + gpiohandle_data + ), + IoctlKind::SetLine +); diff --git a/src/lib.rs b/src/lib.rs index dba292a..6a8cac4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,10 +26,11 @@ //! state to another line/pin. //! //! ```no_run +//! # type Result = std::result::Result; //! use gpio_cdev::{Chip, LineRequestFlags, EventRequestFlags, EventType}; //! //! // Lines are offset within gpiochip0; see docs for more info on chips/lines -//! fn mirror_gpio(inputline: u32, outputline: u32) -> gpio_cdev::errors::Result<()> { +//! fn mirror_gpio(inputline: u32, outputline: u32) -> Result<()> { //! let mut chip = Chip::new("/dev/gpiochip0")?; //! let input = chip.get_line(inputline)?; //! let output = chip.get_line(outputline)?; @@ -54,7 +55,7 @@ //! Ok(()) //! } //! -//! # fn main() -> gpio_cdev::errors::Result<()> { +//! # fn main() -> Result<()> { //! # mirror_gpio(0, 1) //! # } //! ``` @@ -62,9 +63,10 @@ //! To get the state of a GPIO Line on a given chip: //! //! ```no_run +//! # type Result = std::result::Result; //! use gpio_cdev::{Chip, LineRequestFlags}; //! -//! # fn main() -> gpio_cdev::errors::Result<()> { +//! # fn main() -> Result<()> { //! // Read the state of GPIO4 on a raspberry pi. /dev/gpiochip0 //! // maps to the driver for the SoC (builtin) GPIO controller. //! let mut chip = Chip::new("/dev/gpiochip0")?; @@ -81,8 +83,6 @@ #[macro_use] extern crate bitflags; -#[macro_use] -extern crate error_chain; extern crate libc; #[macro_use] extern crate nix; @@ -91,12 +91,12 @@ use std::cmp::min; use std::ffi::CStr; use std::fs::{read_dir, File, ReadDir}; use std::mem; -use std::os::unix::io::{RawFd, AsRawFd, FromRawFd}; +use std::ops::Index; +use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::path::{Path, PathBuf}; use std::ptr; use std::slice; use std::sync::Arc; -use std::ops::Index; pub mod errors; mod ffi; @@ -182,20 +182,16 @@ impl Iterator for ChipIterator { /// Iterate over all GPIO chips currently present on this system pub fn chips() -> Result { Ok(ChipIterator { - readdir: read_dir("/dev").chain_err(|| "unabled to read /dev directory")?, + readdir: read_dir("/dev")?, }) } impl Chip { /// Open the GPIO Chip at the provided path (e.g. `/dev/gpiochip`) pub fn new>(path: P) -> Result { - let f = File::open(path.as_ref()) - .chain_err(|| format!("Opening chip at path {:?} failed", path.as_ref()))?; + let f = File::open(path.as_ref())?; let mut info: ffi::gpiochip_info = unsafe { mem::uninitialized() }; - let _ = unsafe { - ffi::gpio_get_chipinfo_ioctl(f.as_raw_fd(), &mut info) - .chain_err(|| format!("Getting chip info failed for {:?}", path.as_ref()))? - }; + ffi::gpio_get_chipinfo_ioctl(f.as_raw_fd(), &mut info)?; Ok(Chip { inner: Arc::new(Box::new(InnerChip { @@ -390,9 +386,9 @@ unsafe fn cstrbuf_to_string(buf: &[libc::c_char]) -> Option { impl Line { fn new(chip: Arc>, offset: u32) -> Result { if offset >= chip.lines { - bail!("Offset out of range") + return Err(offset_err(offset)); } - Ok(Line { chip, offset, }) + Ok(Line { chip, offset }) } /// Get info about the line from the kernel. @@ -403,10 +399,7 @@ impl Line { name: [0; 32], consumer: [0; 32], }; - let _ = unsafe { - ffi::gpio_get_lineinfo_ioctl(self.chip.file.as_raw_fd(), &mut line_info) - .chain_err(|| "lineinfo ioctl failed")? - }; + ffi::gpio_get_lineinfo_ioctl(self.chip.file.as_raw_fd(), &mut line_info)?; Ok(LineInfo { line: self.clone(), @@ -444,14 +437,14 @@ impl Line { /// /// The main source of errors here is if the kernel returns an /// error to the ioctl performing the request here. This will - /// result in an [`Error`] being returned with [`ErrorKind::Io`]. + /// result in an [`Error`] being returned with [`ErrorKind::Ioctl`]. /// /// One possible cause for an error here would be if the line is /// already in use. One can check for this prior to making the /// request using [`is_kernel`]. /// /// [`Error`]: errors/struct.Error.html - /// [`ErrorKind::Io`]: errors/enum.ErrorKind.html#variant.Io + /// [`ErrorKind::Ioctl`]: errors/enum.ErrorKind.html#variant.Ioctl /// [`is_kernel`]: struct.Line.html#method.is_kernel pub fn request( &self, @@ -478,10 +471,7 @@ impl Line { request.consumer_label.len(), ) }; - unsafe { - ffi::gpio_get_linehandle_ioctl(self.chip.file.as_raw_fd(), &mut request) - .chain_err(|| "linehandle request ioctl failed")? - }; + ffi::gpio_get_linehandle_ioctl(self.chip.file.as_raw_fd(), &mut request)?; Ok(LineHandle { line: self.clone(), flags: flags, @@ -511,7 +501,8 @@ impl Line { /// use gpio_cdev::*; /// /// # use std::io; - /// # fn main() -> errors::Result<()> { + /// # type Result = std::result::Result; + /// # fn main() -> Result<()> { /// let mut chip = Chip::new("/dev/gpiochip0")?; /// let input = chip.get_line(0)?; /// @@ -547,10 +538,7 @@ impl Line { request.consumer_label.len(), ) }; - unsafe { - ffi::gpio_get_lineevent_ioctl(self.chip.file.as_raw_fd(), &mut request) - .chain_err(|| "lineevent ioctl failed")? - }; + ffi::gpio_get_lineevent_ioctl(self.chip.file.as_raw_fd(), &mut request)?; Ok(LineEventHandle { line: self.clone(), @@ -651,10 +639,7 @@ impl LineHandle { /// line has been marked as being ACTIVE_LOW. pub fn get_value(&self) -> Result { let mut data: ffi::gpiohandle_data = unsafe { mem::zeroed() }; - let _ = unsafe { - ffi::gpiohandle_get_line_values_ioctl(self.file.as_raw_fd(), &mut data) - .chain_err(|| "getting line value failed")? - }; + ffi::gpiohandle_get_line_values_ioctl(self.file.as_raw_fd(), &mut data)?; Ok(data.values[0]) } @@ -669,10 +654,7 @@ impl LineHandle { pub fn set_value(&self, value: u8) -> Result<()> { let mut data: ffi::gpiohandle_data = unsafe { mem::zeroed() }; data.values[0] = value; - let _ = unsafe { - ffi::gpiohandle_set_line_values_ioctl(self.file.as_raw_fd(), &mut data) - .chain_err(|| "setting line value failed")? - }; + ffi::gpiohandle_set_line_values_ioctl(self.file.as_raw_fd(), &mut data)?; Ok(()) } @@ -700,11 +682,12 @@ pub struct Lines { impl Lines { fn new(chip: Arc>, offsets: &[u32]) -> Result { - let res: Result> = offsets.iter() + let res: Result> = offsets + .iter() .map(|off| Line::new(chip.clone(), *off)) .collect(); let lines = res?; - Ok(Lines { lines, }) + Ok(Lines { lines }) } /// Get a handle to the parent chip for the lines @@ -733,14 +716,14 @@ impl Lines { /// /// The main source of errors here is if the kernel returns an /// error to the ioctl performing the request here. This will - /// result in an [`Error`] being returned with [`ErrorKind::Io`]. + /// result in an [`Error`] being returned with [`ErrorKind::Ioctl`]. /// /// One possible cause for an error here would be if the lines are /// already in use. One can check for this prior to making the /// request using [`is_kernel`]. /// /// [`Error`]: errors/struct.Error.html - /// [`ErrorKind::Io`]: errors/enum.ErrorKind.html#variant.Io + /// [`ErrorKind::Ioctl`]: errors/enum.ErrorKind.html#variant.Ioctl /// [`is_kernel`]: struct.Line.html#method.is_kernel pub fn request( &self, @@ -750,7 +733,7 @@ impl Lines { ) -> Result { let n = self.lines.len(); if default.len() != n { - bail!(nix::Error::Sys(nix::errno::Errno::EINVAL)); + return Err(invalid_err(n, default.len())); } // prepare the request; the kernel consumes some of these values and will // set the fd for us. @@ -773,13 +756,10 @@ impl Lines { request.consumer_label.len(), ) }; - unsafe { - ffi::gpio_get_linehandle_ioctl(self.lines[0].chip().inner.file.as_raw_fd(), &mut request) - .chain_err(|| "linehandle request ioctl failed")? - }; + ffi::gpio_get_linehandle_ioctl(self.lines[0].chip().inner.file.as_raw_fd(), &mut request)?; let lines = self.lines.clone(); Ok(MultiLineHandle { - lines: Lines { lines, }, + lines: Lines { lines }, flags: flags, file: unsafe { File::from_raw_fd(request.fd) }, }) @@ -824,10 +804,7 @@ impl MultiLineHandle { /// line has been marked as being ACTIVE_LOW. pub fn get_values(&self) -> Result> { let mut data: ffi::gpiohandle_data = unsafe { mem::zeroed() }; - let _ = unsafe { - ffi::gpiohandle_get_line_values_ioctl(self.file.as_raw_fd(), &mut data) - .chain_err(|| "getting line value failed")? - }; + ffi::gpiohandle_get_line_values_ioctl(self.file.as_raw_fd(), &mut data)?; let n = self.num_lines(); let values: Vec = (0..n).map(|i| data.values[i]).collect(); Ok(values) @@ -844,16 +821,13 @@ impl MultiLineHandle { pub fn set_values(&self, values: &[u8]) -> Result<()> { let n = self.num_lines(); if values.len() != n { - bail!(nix::Error::Sys(nix::errno::Errno::EINVAL)); + return Err(invalid_err(n, values.len())); } let mut data: ffi::gpiohandle_data = unsafe { mem::zeroed() }; for i in 0..n { data.values[i] = values[i]; } - let _ = unsafe { - ffi::gpiohandle_set_line_values_ioctl(self.file.as_raw_fd(), &mut data) - .chain_err(|| "setting line value failed")? - }; + ffi::gpiohandle_set_line_values_ioctl(self.file.as_raw_fd(), &mut data)?; Ok(()) } @@ -875,7 +849,6 @@ impl AsRawFd for MultiLineHandle { } } - /// Did the Line rise (go active) or fall (go inactive)? /// /// Maps to kernel [`GPIOEVENT_EVENT_*`] definitions. @@ -960,11 +933,12 @@ impl LineEventHandle { mem::size_of::(), ) }; - let bytes_read = nix::unistd::read(self.file.as_raw_fd(), &mut data_as_buf)?; + let bytes_read = + nix::unistd::read(self.file.as_raw_fd(), &mut data_as_buf).map_err(event_err)?; if bytes_read != mem::size_of::() { let e = nix::Error::Sys(nix::errno::Errno::EIO); - Err(e.into()) + Err(event_err(e)) } else { Ok(LineEvent(data)) } @@ -978,7 +952,7 @@ impl LineEventHandle { /// line has been marked as being ACTIVE_LOW. pub fn get_value(&self) -> Result { let mut data: ffi::gpiohandle_data = unsafe { mem::zeroed() }; - let _ = unsafe { ffi::gpiohandle_get_line_values_ioctl(self.file.as_raw_fd(), &mut data)? }; + ffi::gpiohandle_get_line_values_ioctl(self.file.as_raw_fd(), &mut data)?; Ok(data.values[0]) } @@ -1007,13 +981,14 @@ impl Iterator for LineEventHandle { ) }; match nix::unistd::read(self.file.as_raw_fd(), &mut data_as_buf) { - Ok(bytes_read) => if bytes_read != mem::size_of::() { - None - } else { - Some(Ok(LineEvent(data))) - }, - Err(e) => Some(Err(e.into())), + Ok(bytes_read) => { + if bytes_read != mem::size_of::() { + None + } else { + Some(Ok(LineEvent(data))) + } + } + Err(e) => Some(Err(event_err(e))), } } } -