diff options
-rw-r--r-- | src/lib.rs | 72 |
1 files changed, 48 insertions, 24 deletions
@@ -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<libc::c_int> +{ + 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<libc::c_int> +{ + 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<F: AsRawFd>(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<F: AsRawFd>(fd: &F) -> io::Result<Palette> { 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) } |