chiark / gitweb /
work around lack of io::ErrorKind::IsADirectory
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 22 Aug 2021 23:33:25 +0000 (00:33 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 22 Aug 2021 23:33:25 +0000 (00:33 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Cargo.lock
Cargo.toml
src/config.rs
src/lib.rs
src/utils.rs

index db9a23da18652ca483a847677dcab1f203e3f44c..79c9711001963bde12cb11d7ba792338ab0636e9 100644 (file)
@@ -427,6 +427,7 @@ dependencies = [
  "itertools",
  "lazy-regex",
  "lazy_static",
+ "libc",
  "log",
  "memchr",
  "mime",
index 477438317adb1752f35c3a64e99d610d21589c99..e6c0659bc93cee2c575a947cfba3055197168dec 100644 (file)
@@ -35,6 +35,7 @@ hyper = { version = "0.14", features = ["full"] }
 hyper-tls = "0.5"
 ipnet = "2"
 itertools = "0.10"
+libc = "0.2" # just for EISDIR due to IsADirectory
 mime = "0.3"
 parking_lot = "0.11"
 regex = "1.5"
@@ -49,6 +50,10 @@ tokio = { version = "1", features = ["full"] }
 thiserror = "1"
 void = "1"
 
+# for daemonic behaviours
+#  daemonize 0.4.1 in sid
+#  syslog    4.0 in sid, 5.0 in upstream, ideally want 5.0 (new API)
+
 # Not in sid:
 extend = "1"           # no deps not in sid
 eyre = "0.6"           # deps not in sid: indenter (see below)
index 7d0f91112a1927536776d389c1efaca3bccc0504..2b63b2e2951172fa17b3c534f1e39867566416aa 100644 (file)
@@ -163,13 +163,12 @@ struct Aggregate {
   sections: HashMap<SectionName, ini::Section>,
 }
 
-type OkAnyway<'f,A> = &'f dyn Fn(ErrorKind) -> Option<A>;
+type OkAnyway<'f,A> = &'f dyn Fn(&io::Error) -> Option<A>;
 #[ext]
 impl<'f,A> OkAnyway<'f,A> {
   fn ok<T>(self, r: &Result<T, io::Error>) -> Option<A> {
     let e = r.as_ref().err()?;
-    let k = e.kind();
-    let a = self(k)?;
+    let a = self(e)?;
     Some(a)
   }
 }
@@ -338,9 +337,9 @@ impl Aggregate {
   #[throws(AE)] // AE includes everything
   fn read_toplevel(&mut self, toplevel: &Path) {
     enum Anyway { None, Dir }
-    match self.read_file(toplevel, &|k| match k {
-      EK::NotFound => Some(Anyway::None),
-      EK::IsADirectory => Some(Anyway::Dir),
+    match self.read_file(toplevel, &|e| match e {
+      e if e.kind() == EK::NotFound => Some(Anyway::None),
+      e if e.is_is_a_directory() => Some(Anyway::Dir),
       _ => None,
     })
       .dcontext(toplevel).context("top-level config directory (or file)")?
@@ -349,8 +348,8 @@ impl Aggregate {
 
       Some(Anyway::Dir) => {
         struct AnywayNone;
-        let anyway_none = |k| match k {
-          EK::NotFound => Some(AnywayNone),
+        let anyway_none = |e: &io::Error| match e {
+          e if e.kind() == EK::NotFound => Some(AnywayNone),
           _ => None,
         };
 
@@ -391,8 +390,8 @@ impl Aggregate {
   fn read_extra(&mut self, extra: &Path) {
     struct AnywayDir;
 
-    match self.read_file(extra, &|k| match k {
-      EK::IsADirectory => Some(AnywayDir),
+    match self.read_file(extra, &|e| match e {
+      e if e.is_is_a_directory() => Some(AnywayDir),
       _ => None,
     })
       .dcontext(extra)?
index 443bd4b43341e2abf06669ba7e2ef764c74f06f6..89419bf063c31d93c8b43276366056e9d15fb06b 100644 (file)
@@ -2,8 +2,6 @@
 // SPDX-License-Identifier: GPL-3.0-or-later
 // There is NO WARRANTY.
 
-#![feature(io_error_more)] // EK::IsADirectory
-
 pub mod prelude;
 
 pub mod config;
index c210a7d3ce2ab7a0801653cbfb40060f9465058b..2df92b564a5926e66bf9dd06c24557752454b356 100644 (file)
@@ -38,6 +38,20 @@ impl<T> Result<T,ReadLimitedError> {
   }
 }
 
+// Works around the lack of ErrorKind::IsADirectory
+// #![feature(io_error_more)]
+// https://github.com/rust-lang/rust/issues/86442
+#[ext(pub)]
+impl io::Error {
+  fn is_is_a_directory(&self) -> bool {
+    self.raw_os_error()
+      .unwrap_or_else(|| panic!(
+ "trying to tell whether Kind is IsADirectory for non-OS error io::Error {}",
+        self))
+      == libc::EISDIR
+  }
+}
+
 #[throws(ReadLimitedError)]
 pub async fn read_limited_bytes<S>(limit: usize, initial: Box<[u8]>,
                                    capacity: usize,