summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2021-11-15 20:40:38 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2021-11-15 20:14:17 +0100
commit3fcadd24b57ef31164b2410be869e998119db56c (patch)
tree0b821e7d50d5de3494d0598b4149320d32411ef9
parentc43c6aa562c5222477f66d50179e368ca0f25a9b (diff)
downloadvtcol-3fcadd24b57ef31164b2410be869e998119db56c.tar.gz
use idiomatic syscall error wrappers
A simplified version of the function used in std which aren’t made public.
-rw-r--r--src/lib.rs72
1 files changed, 48 insertions, 24 deletions
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<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)
}