From 3fcadd24b57ef31164b2410be869e998119db56c Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 15 Nov 2021 20:40:38 +0100 Subject: use idiomatic syscall error wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A simplified version of the function used in std which aren’t made public. --- src/lib.rs | 72 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index f8bef99..4030884 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,29 @@ use std::{convert::TryFrom, os::unix::io::{AsRawFd, RawFd}, path::{Path, PathBuf}}; +/** Convenience syscall wrapper based on its namesake found in the sadly +private ``std::sys::unix`` library. */ +fn cvt(t: libc::c_int) -> io::Result +{ + if t == -1 { + Err(Error::last_os_error()) + } else { + Ok(t) + } +} + +/** Convenience syscall wrapper based on its namesake found in the sadly +private ``std::sys::unix`` library. */ +fn cvt_r(f: &mut dyn FnMut() -> libc::c_int) -> io::Result +{ + loop { + match cvt((*f)()) { + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}, + other => return other, + } + } +} + #[derive(Debug)] pub struct Fd(libc::c_int); @@ -515,34 +538,35 @@ impl From<&RawPalette<'_>> for Palette pub fn ioctl_pio_cmap(fd: &F, pal: &Palette) -> io::Result<()> { - if unsafe { - ioctl( - fd.as_raw_fd(), - PIO_CMAP, - std::mem::transmute::<&Palette, *const libc::c_void>(&pal), - ) - } < 0 - { - Err(Error::last_os_error()) - } else { - Ok(()) - } + /* cvt_r because technically it can’t be ruled out that we hit EINTR. */ + cvt_r(&mut || { + unsafe { + ioctl( + fd.as_raw_fd(), + PIO_CMAP, + std::mem::transmute::<&Palette, *const libc::c_void>(&pal), + ) + } + }) + .map(|_| ()) } pub fn ioctl_gio_cmap(fd: &F) -> io::Result { let mut pal = Palette::new(); - if unsafe { - ioctl( - fd.as_raw_fd(), - GIO_CMAP, - std::mem::transmute::<&mut Palette, *mut libc::c_void>(&mut pal), - ) - } < 0 - { - Err(Error::last_os_error()) - } else { - Ok(pal) - } + /* cvt_r because technically it can’t be ruled out that we hit EINTR. */ + cvt_r(&mut || { + unsafe { + ioctl( + fd.as_raw_fd(), + GIO_CMAP, + std::mem::transmute::<&mut Palette, *mut libc::c_void>( + &mut pal, + ), + ) + } + }) + .map(|_| ())?; + Ok(pal) } -- cgit v1.2.3