diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f99feac78c279ae9cb3398bf18101ea2502bab8c
--- /dev/null
+++ b/src/error.rs
@@ -0,0 +1,34 @@
+use crate::platform::types::c_int;
+
+/// Positive error codes (EINVAL, not -EINVAL).
+#[derive(Debug, Eq, PartialEq)]
+// TODO: Move to a more generic place.
+pub struct Errno(pub c_int);
+
+#[cfg(target_os = "redox")]
+impl From<syscall::Error> for Errno {
+    fn from(value: syscall::Error) -> Self {
+        Errno(value.errno)
+    }
+}
+#[cfg(target_os = "redox")]
+impl From<Errno> for syscall::Error {
+    fn from(value: Errno) -> Self {
+        syscall::Error::new(value.0)
+    }
+}
+
+pub trait ResultExt<T> {
+    fn or_minus_one_errno(self) -> T;
+}
+impl<T: From<i8>> ResultExt<T> for Result<T, Errno> {
+    fn or_minus_one_errno(self) -> T {
+        match self {
+            Self::Ok(v) => v,
+            Self::Err(Errno(errno)) => unsafe {
+                crate::platform::ERRNO.set(errno);
+                T::from(-1)
+            },
+        }
+    }
+}
diff --git a/src/fs.rs b/src/fs.rs
index dcf77e2f13779df0b45438519875eb7b271d711b..534da570e004900f5f5a5665fb8bc1a66ada278f 100644
--- a/src/fs.rs
+++ b/src/fs.rs
@@ -1,12 +1,12 @@
 use crate::{
     c_str::CStr,
+    error::ResultExt,
     header::{
         fcntl::O_CREAT,
         unistd::{SEEK_CUR, SEEK_END, SEEK_SET},
     },
     io,
     platform::{types::*, Pal, Sys},
-    pthread::ResultExt,
 };
 use core::ops::Deref;
 
diff --git a/src/header/pthread/mod.rs b/src/header/pthread/mod.rs
index 0b8a6ba0308e8c710c53f6727e5b5721902466c1..ce58695290c92aad6250acaea033e31f0e410520 100644
--- a/src/header/pthread/mod.rs
+++ b/src/header/pthread/mod.rs
@@ -3,15 +3,16 @@
 use core::{cell::Cell, ptr::NonNull};
 
 use crate::{
+    error::Errno,
     header::{sched::*, time::timespec},
     platform::{types::*, Pal, Sys},
     pthread,
 };
 
-pub fn e(result: Result<(), pthread::Errno>) -> i32 {
+pub fn e(result: Result<(), Errno>) -> i32 {
     match result {
         Ok(()) => 0,
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 
@@ -75,7 +76,7 @@ pub use self::barrier::*;
 pub unsafe extern "C" fn pthread_cancel(thread: pthread_t) -> c_int {
     match pthread::cancel(&*thread.cast()) {
         Ok(()) => 0,
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 
@@ -96,7 +97,7 @@ pub unsafe extern "C" fn pthread_create(
             core::ptr::write(pthread, ptr);
             0
         }
-        Err(pthread::Errno(code)) => code,
+        Err(Errno(code)) => code,
     }
 }
 
@@ -104,7 +105,7 @@ pub unsafe extern "C" fn pthread_create(
 pub unsafe extern "C" fn pthread_detach(pthread: pthread_t) -> c_int {
     match pthread::detach(&*pthread.cast()) {
         Ok(()) => 0,
-        Err(pthread::Errno(errno)) => errno,
+        Err(Errno(errno)) => errno,
     }
 }
 
@@ -134,7 +135,7 @@ pub unsafe extern "C" fn pthread_getcpuclockid(
             clock_out.write(clock);
             0
         }
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 
@@ -151,7 +152,7 @@ pub unsafe extern "C" fn pthread_getschedparam(
 
             0
         }
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 
@@ -167,7 +168,7 @@ pub unsafe extern "C" fn pthread_join(thread: pthread_t, retval: *mut *mut c_voi
             }
             0
         }
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 
@@ -195,7 +196,7 @@ pub unsafe extern "C" fn pthread_setcancelstate(state: c_int, oldstate: *mut c_i
             }
             0
         }
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 #[no_mangle]
@@ -209,7 +210,7 @@ pub unsafe extern "C" fn pthread_setcanceltype(ty: c_int, oldty: *mut c_int) ->
             }
             0
         }
-        Err(pthread::Errno(error)) => error,
+        Err(Errno(error)) => error,
     }
 }
 
diff --git a/src/header/pthread/mutex.rs b/src/header/pthread/mutex.rs
index 6b89f266c847cbf7d3fb009944f8c3ec0322e0b6..bdb87898806e998b824127f3a576f95d48746a2e 100644
--- a/src/header/pthread/mutex.rs
+++ b/src/header/pthread/mutex.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-use crate::pthread::Errno;
+use crate::error::Errno;
 
 // PTHREAD_MUTEX_INITIALIZER is defined in bits_pthread/cbindgen.toml
 
diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs
index 4c2db6b90bdc3c90f5dd7024908e66b82e2eed27..674df6bff207b77691376b2f6978330a70a08a59 100644
--- a/src/header/signal/mod.rs
+++ b/src/header/signal/mod.rs
@@ -5,9 +5,9 @@ use core::{mem, ptr};
 use cbitset::BitSet;
 
 use crate::{
+    error::{self, Errno, ResultExt},
     header::{errno, time::timespec},
     platform::{self, types::*, Pal, PalSignal, Sys},
-    pthread::{self, Errno, ResultExt},
 };
 
 pub use self::sys::*;
@@ -81,7 +81,7 @@ pub extern "C" fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
 #[no_mangle]
 pub unsafe extern "C" fn pthread_kill(thread: pthread_t, sig: c_int) -> c_int {
     let os_tid = {
-        let pthread = &*(thread as *const pthread::Pthread);
+        let pthread = &*(thread as *const crate::pthread::Pthread);
         pthread.os_tid.get().read()
     };
     crate::header::pthread::e(Sys::rlct_kill(os_tid, sig as usize))
diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs
index da7977e93a0db511519a65865e2c6df3e25add85..fdeb675fa69901bd572210301c53cf5c3970c32f 100644
--- a/src/header/unistd/mod.rs
+++ b/src/header/unistd/mod.rs
@@ -9,6 +9,7 @@ use core::{
 
 use crate::{
     c_str::CStr,
+    error::ResultExt,
     header::{
         crypt::{crypt_data, crypt_r},
         errno, fcntl, limits,
@@ -17,7 +18,6 @@ use crate::{
         time::timespec,
     },
     platform::{self, types::*, Pal, Sys},
-    pthread::ResultExt,
 };
 
 use alloc::collections::LinkedList;
diff --git a/src/lib.rs b/src/lib.rs
index 24afb6043204acfd402d9f95f18e97a8dc4b394b..1baebcaf2c94b3c75f35afd4b3e5690fbdac44f6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -47,6 +47,7 @@ pub mod c_str;
 pub mod c_vec;
 pub mod cxa;
 pub mod db;
+pub mod error;
 pub mod fs;
 pub mod header;
 pub mod io;
diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs
index 1a03cfb79e046620342d593349346b17116ffa4e..a84922afc71dd64e8b8c9cf05b13add19fee6c08 100644
--- a/src/platform/linux/mod.rs
+++ b/src/platform/linux/mod.rs
@@ -15,8 +15,8 @@ use crate::header::{
 };
 // use header::sys_times::tms;
 use crate::{
+    error::Errno,
     header::{sys_utsname::utsname, time::timespec},
-    pthread::Errno,
 };
 
 mod epoll;
@@ -243,7 +243,7 @@ impl Pal for Sys {
         addr: *mut u32,
         val: u32,
         deadline: Option<&timespec>,
-    ) -> Result<(), crate::pthread::Errno> {
+    ) -> Result<(), Errno> {
         let deadline = deadline.map_or(0, |d| d as *const _ as usize);
         e_raw(unsafe {
             syscall!(
diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs
index 8055904c9315bfd803fda35e57d5380892f998b2..8542b5c972366290dc6a26df1ee13f88d9a7f25f 100644
--- a/src/platform/linux/signal.rs
+++ b/src/platform/linux/signal.rs
@@ -5,12 +5,12 @@ use super::{
     e, e_raw, Sys,
 };
 use crate::{
+    error::Errno,
     header::{
         signal::{sigaction, siginfo_t, sigset_t, stack_t, NSIG, SA_RESTORER},
         sys_time::itimerval,
         time::timespec,
     },
-    pthread::Errno,
 };
 
 impl PalSignal for Sys {
diff --git a/src/platform/mod.rs b/src/platform/mod.rs
index 9b598d68a02d34e628a7572016e5037b166b6b78..0ce9a4c07454aed335c821e7dc9702f24126cd6e 100644
--- a/src/platform/mod.rs
+++ b/src/platform/mod.rs
@@ -1,6 +1,6 @@
 use crate::{
+    error::ResultExt,
     io::{self, Read, Write},
-    pthread::ResultExt,
 };
 use alloc::{boxed::Box, vec::Vec};
 use core::{cell::Cell, fmt, ptr};
diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs
index fb9d2dfc359118a64aef9796bfed56b97dea5e89..007a0724393434d2e8a69635a513a5750ae230d0 100644
--- a/src/platform/pal/mod.rs
+++ b/src/platform/pal/mod.rs
@@ -1,6 +1,7 @@
 use super::types::*;
 use crate::{
     c_str::CStr,
+    error::Errno,
     header::{
         dirent::dirent,
         sys_resource::rlimit,
@@ -10,7 +11,7 @@ use crate::{
         sys_utsname::utsname,
         time::timespec,
     },
-    pthread::{self, Errno},
+    pthread,
 };
 
 pub use self::epoll::PalEpoll;
@@ -83,8 +84,8 @@ pub trait Pal {
         addr: *mut u32,
         val: u32,
         deadline: Option<&timespec>,
-    ) -> Result<(), pthread::Errno>;
-    unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, pthread::Errno>;
+    ) -> Result<(), Errno>;
+    unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, Errno>;
 
     fn futimens(fd: c_int, times: *const timespec) -> c_int;
 
@@ -182,12 +183,8 @@ pub trait Pal {
 
     fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int;
 
-    unsafe fn rlct_clone(stack: *mut usize)
-        -> Result<crate::pthread::OsTid, crate::pthread::Errno>;
-    unsafe fn rlct_kill(
-        os_tid: crate::pthread::OsTid,
-        signal: usize,
-    ) -> Result<(), crate::pthread::Errno>;
+    unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno>;
+    unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno>;
     fn current_os_tid() -> crate::pthread::OsTid;
 
     fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno>;
diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs
index cd9151a50575e3e7efe69b96ab686e05ed2ee163..c03c5a9ac52b8893034d192628eb2da24aa73d14 100644
--- a/src/platform/pal/signal.rs
+++ b/src/platform/pal/signal.rs
@@ -1,11 +1,11 @@
 use super::super::{types::*, Pal};
 use crate::{
+    error::Errno,
     header::{
         signal::{sigaction, siginfo_t, sigset_t, stack_t},
         sys_time::itimerval,
         time::timespec,
     },
-    pthread::Errno,
 };
 
 pub trait PalSignal: Pal {
diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs
index 60eaca05a6b3ef802195035c41a08ef9101f735a..57c485c252315ffdf30af88e71d05b739fc4c0f5 100644
--- a/src/platform/redox/epoll.rs
+++ b/src/platform/redox/epoll.rs
@@ -4,11 +4,11 @@ use super::{
 };
 
 use crate::{
+    error::ResultExt,
     fs::File,
     header::{errno::*, fcntl::*, signal::sigset_t, sys_epoll::*},
     io::prelude::*,
     platform,
-    pthread::ResultExt,
 };
 use core::{mem, slice};
 use syscall::{
diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
index 8916d1702b8e66c424863f65a72c40d9c0e3eeea..6634c10dec005df4f1cbda15cf6b18e75b1ca4d4 100644
--- a/src/platform/redox/mod.rs
+++ b/src/platform/redox/mod.rs
@@ -8,6 +8,7 @@ use syscall::{
 
 use crate::{
     c_str::{CStr, CString},
+    error::{self, Errno, ResultExt},
     fs::File,
     header::{
         dirent::dirent,
@@ -25,7 +26,6 @@ use crate::{
         unistd::{F_OK, R_OK, W_OK, X_OK},
     },
     io::{self, prelude::*, BufReader},
-    pthread::{self, Errno, ResultExt},
 };
 
 pub use redox_rt::proc::FdGuard;
@@ -307,7 +307,7 @@ impl Pal for Sys {
         addr: *mut u32,
         val: u32,
         deadline: Option<&timespec>,
-    ) -> Result<(), pthread::Errno> {
+    ) -> Result<(), Errno> {
         let deadline = deadline.map(|d| syscall::TimeSpec {
             tv_sec: d.tv_sec,
             tv_nsec: d.tv_nsec as i32,
@@ -316,7 +316,7 @@ impl Pal for Sys {
         Ok(())
     }
     #[inline]
-    unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, pthread::Errno> {
+    unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, Errno> {
         Ok(redox_rt::sys::sys_futex_wake(addr, num)?)
     }
 
@@ -787,21 +787,16 @@ impl Pal for Sys {
         e(extra::pipe2(fds, flags as usize).map(|()| 0)) as c_int
     }
 
-    unsafe fn rlct_clone(
-        stack: *mut usize,
-    ) -> Result<crate::pthread::OsTid, crate::pthread::Errno> {
+    unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno> {
         let _guard = clone::rdlock();
         let res = clone::rlct_clone_impl(stack);
 
         res.map(|mut fd| crate::pthread::OsTid {
             thread_fd: fd.take(),
         })
-        .map_err(|error| crate::pthread::Errno(error.errno))
+        .map_err(|error| Errno(error.errno))
     }
-    unsafe fn rlct_kill(
-        os_tid: crate::pthread::OsTid,
-        signal: usize,
-    ) -> Result<(), crate::pthread::Errno> {
+    unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno> {
         redox_rt::sys::posix_kill_thread(os_tid.thread_fd, signal as u32)?;
         Ok(())
     }
diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs
index 5910f3e2beb1e0e0b66f689ab2f50ae50a4db97a..f88cd53454f0d54e50a97ae2841bf2a0f8668fdc 100644
--- a/src/platform/redox/signal.rs
+++ b/src/platform/redox/signal.rs
@@ -7,6 +7,7 @@ use super::{
     e, Sys,
 };
 use crate::{
+    error::Errno,
     header::{
         errno::{EINVAL, ENOSYS},
         signal::{
@@ -17,7 +18,6 @@ use crate::{
         time::timespec,
     },
     platform::ERRNO,
-    pthread::Errno,
 };
 
 impl PalSignal for Sys {
diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs
index 54798b4d6cd93e85f9db38d25416724f41623f69..6d91c53991406ca2ff2d3db3c7c3f055e2246407 100644
--- a/src/platform/redox/socket.rs
+++ b/src/platform/redox/socket.rs
@@ -7,6 +7,7 @@ use super::{
     e, Sys,
 };
 use crate::{
+    error::ResultExt,
     header::{
         arpa_inet::inet_aton,
         netinet_in::{in_addr, in_port_t, sockaddr_in},
@@ -15,7 +16,6 @@ use crate::{
         sys_time::timeval,
         sys_un::sockaddr_un,
     },
-    pthread::ResultExt,
 };
 
 macro_rules! bind_or_connect {
diff --git a/src/platform/rlb.rs b/src/platform/rlb.rs
index e9beaea52261911ec5302cbfb7585b1700d80f46..ec9ed09892e1c19adb26d64694273d8177a21a6c 100644
--- a/src/platform/rlb.rs
+++ b/src/platform/rlb.rs
@@ -3,8 +3,8 @@ use alloc::vec::Vec;
 use crate::platform::{types::*, Pal, Sys};
 
 use crate::{
+    error::ResultExt,
     header::unistd::{lseek, SEEK_SET},
-    pthread::ResultExt,
 };
 /// Implements an `Iterator` which returns on either newline or EOF.
 #[derive(Clone)]
diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs
index 01a3060094ead77c438767781576f3758dd79e35..2d2fc7b20fbb6c4ac0776384a7ecdce997bbd127 100644
--- a/src/pthread/mod.rs
+++ b/src/pthread/mod.rs
@@ -10,6 +10,7 @@ use core::{
 use alloc::{boxed::Box, collections::BTreeMap};
 
 use crate::{
+    error::Errno,
     header::{errno::*, pthread as header, sched::sched_param, sys_mman},
     ld_so::{
         linker::Linker,
@@ -82,39 +83,6 @@ pub struct OsTid {
 unsafe impl Send for Pthread {}
 unsafe impl Sync for Pthread {}
 
-/// Positive error codes (EINVAL, not -EINVAL).
-#[derive(Debug, Eq, PartialEq)]
-// TODO: Move to a more generic place.
-pub struct Errno(pub c_int);
-
-#[cfg(target_os = "redox")]
-impl From<syscall::Error> for Errno {
-    fn from(value: syscall::Error) -> Self {
-        Errno(value.errno)
-    }
-}
-#[cfg(target_os = "redox")]
-impl From<Errno> for syscall::Error {
-    fn from(value: Errno) -> Self {
-        syscall::Error::new(value.0)
-    }
-}
-
-pub trait ResultExt<T> {
-    fn or_minus_one_errno(self) -> T;
-}
-impl<T: From<i8>> ResultExt<T> for Result<T, Errno> {
-    fn or_minus_one_errno(self) -> T {
-        match self {
-            Self::Ok(v) => v,
-            Self::Err(Errno(errno)) => unsafe {
-                crate::platform::ERRNO.set(errno);
-                T::from(-1)
-            },
-        }
-    }
-}
-
 #[derive(Clone, Copy, Debug)]
 pub struct Retval(pub *mut c_void);
 
diff --git a/src/sync/cond.rs b/src/sync/cond.rs
index aa3b6247acb86d585274ca0164b1164e7741f036..1b3d846067697edbee87b24f3f00205ef30e90ae 100644
--- a/src/sync/cond.rs
+++ b/src/sync/cond.rs
@@ -1,8 +1,8 @@
 // Used design from https://www.remlab.net/op/futex-condvar.shtml
 
 use crate::{
+    error::Errno,
     header::{pthread::*, time::timespec},
-    pthread::Errno,
 };
 
 use core::sync::atomic::{AtomicU32 as AtomicUint, Ordering};
@@ -12,7 +12,7 @@ pub struct Cond {
     prev: AtomicUint,
 }
 
-type Result<T, E = crate::pthread::Errno> = core::result::Result<T, E>;
+type Result<T, E = Errno> = core::result::Result<T, E>;
 
 impl Cond {
     pub fn new() -> Self {
diff --git a/src/sync/mod.rs b/src/sync/mod.rs
index dc4ecd4fdbd77d99123747c191d15b8f7551f7e7..254bd68108c98700debaaa9a4eb9614b0f2a1b39 100644
--- a/src/sync/mod.rs
+++ b/src/sync/mod.rs
@@ -19,12 +19,12 @@ pub use self::{
 };
 
 use crate::{
+    error::Errno,
     header::{
         errno::{EAGAIN, ETIMEDOUT},
         time::timespec,
     },
     platform::{types::*, Pal, Sys},
-    pthread::Errno,
 };
 use core::{
     mem::MaybeUninit,
diff --git a/src/sync/pthread_mutex.rs b/src/sync/pthread_mutex.rs
index 030cac85830d8beb0641db19d26d8d6cf8d04308..cc9b011524c5fd6e083507edf763f3d3f7037ebf 100644
--- a/src/sync/pthread_mutex.rs
+++ b/src/sync/pthread_mutex.rs
@@ -4,6 +4,7 @@ use core::{
 };
 
 use crate::{
+    error::Errno,
     header::{errno::*, pthread::*, time::timespec},
     pthread::*,
 };