From 05ce5422c01754c35de38f7e648a303c5295b45e Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 13 Feb 2023 00:26:13 -0500 Subject: [PATCH] Add `errno` workspace crate, fix error handling in `unistd` workspace crate --- Cargo.lock | 8 +- Cargo.toml | 12 +- errno/Cargo.toml | 8 + errno/src/lib.rs | 425 ++++++++++++++++++++++++++++++ hashbox/commands/sha224sum/mod.rs | 2 +- pw/src/lib.rs | 2 +- unistd/Cargo.toml | 4 + unistd/src/lib.rs | 46 ++-- 8 files changed, 478 insertions(+), 29 deletions(-) create mode 100644 errno/Cargo.toml create mode 100644 errno/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 002268d..bb82fcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,6 +272,10 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.1.0" + [[package]] name = "errno" version = "0.2.8" @@ -516,7 +520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ "bitflags", - "errno", + "errno 0.2.8", "io-lifetimes", "libc", "linux-raw-sys", @@ -579,6 +583,7 @@ dependencies = [ "clap_mangen", "data-encoding", "digest", + "errno 0.1.0", "lazy_static", "libc", "md-5", @@ -723,6 +728,7 @@ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" name = "unistd" version = "0.1.0" dependencies = [ + "errno 0.1.0", "libc", "sc", ] diff --git a/Cargo.toml b/Cargo.toml index bfe2f08..e2864f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [workspace] -members = [ "bitflags-mini", "mount", "pw", "unistd", "unix-mode" ] +members = [ "bitflags-mini", "errno", "mount", "pw", "unistd", "unix-mode" ] [[bin]] name = "corebox" @@ -45,9 +45,9 @@ walkdir = "2.3" package = "bitflags-mini" path = "bitflags-mini" -[dependencies.unistd] -package = "unistd" -path = "unistd" +[dependencies.errno] +package = "errno" +path = "errno" [dependencies.mode] package = "unix-mode" @@ -56,6 +56,10 @@ path = "unix-mode" [dependencies.mount] path = "mount" +[dependencies.unistd] +package = "unistd" +path = "unistd" + [dependencies.pw] path = "pw" diff --git a/errno/Cargo.toml b/errno/Cargo.toml new file mode 100644 index 0000000..44ec46f --- /dev/null +++ b/errno/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "errno" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/errno/src/lib.rs b/errno/src/lib.rs new file mode 100644 index 0000000..88e7ebc --- /dev/null +++ b/errno/src/lib.rs @@ -0,0 +1,425 @@ +use core::fmt; +use std::{error, ffi::c_long}; + +#[derive(Debug)] +#[repr(i64)] +pub enum Errno { + EPERM = 1, + ENOENT = 2, + ESRCH = 3, + EINTR = 4, + EIO = 5, + ENXIO = 6, + E2BIG = 7, + ENOEXEC = 8, + EBADF = 9, + ECHILD = 10, + EAGAIN = 11, + ENOMEM = 12, + EACCES = 13, + EFAULT = 14, + ENOTBLK = 15, + EBUSY = 16, + EEXIST = 17, + EXDEV = 18, + ENODEV = 19, + ENOTDIR = 20, + EISDIR = 21, + EINVAL = 22, + ENFILE = 23, + EMFILE = 24, + ENOTTY = 25, + ETXTBSY = 26, + EFBIG = 27, + ENOSPC = 28, + ESPIPE = 29, + EROFS = 30, + EMLINK = 31, + EPIPE = 32, + EDOM = 33, + ERANGE = 34, + EDEADLOCK = 35, + ENAMETOOLONG = 36, + ENOLCK = 37, + ENOSYS = 38, + ENOTEMPTY = 39, + ELOOP = 40, + ENOMSG = 42, + EIDRM = 43, + ECHRNG = 44, + EL2NSYNC = 45, + EL3HLT = 46, + EL3RST = 47, + ELNRNG = 48, + EUNATCH = 49, + ENOCSI = 50, + EL2HLT = 51, + EBADE = 52, + EBADR = 53, + EXFULL = 54, + ENOANO = 55, + EBADRQC = 56, + EBADSLT = 57, + EBFONT = 59, + ENOSTR = 60, + ENODATA = 61, + ETIME = 62, + ENOSR = 63, + ENONET = 64, + ENOPKG = 65, + EREMOTE = 66, + ENOLINK = 67, + EADV = 68, + ESRMNT = 69, + ECOMM = 70, + EPROTO = 71, + EMULTIHOP = 72, + EDOTDOT = 73, + EBADMSG = 74, + EOVERFLOW = 75, + ENOTUNIQ = 76, + EBADFD = 77, + EREMCHG = 78, + ELIBACC = 79, + ELIBBAD = 80, + ELIBSCN = 81, + ELIBMAX = 82, + ELIBEXEC = 83, + EILSEQ = 84, + ERESTART = 85, + ESTRPIPE = 86, + EUSERS = 87, + ENOTSOCK = 88, + EDESTADDRREQ = 89, + EMSGSIZE = 90, + EPROTOTYPE = 91, + ENOPROTOOPT = 92, + EPROTONOSUPPORT = 93, + ESOCKTNOSUPPORT = 94, + EOPNOTSUPP = 95, + EPFNOSUPPORT = 96, + EAFNOSUPPORT = 97, + EADDRINUSE = 98, + EADDRNOTAVAIL = 99, + ENETDOWN = 100, + ENETUNREACH = 101, + ENETRESET = 102, + ECONNABORTED = 103, + ECONNRESET = 104, + ENOBUFS = 105, + EISCONN = 106, + ENOTCONN = 107, + ESHUTDOWN = 108, + ETOOMANYREFS = 109, + ETIMEDOUT = 110, + ECONNREFUSED = 111, + EHOSTDOWN = 112, + EHOSTUNREACH = 113, + EALREADY = 114, + EINPROGRESS = 115, + ESTALE = 116, + EUCLEAN = 117, + ENOTNAM = 118, + ENAVAIL = 119, + EISNAM = 120, + EREMOTEIO = 121, + EDQUOT = 122, + ENOMEDIUM = 123, + EMEDIUMTYPE = 124, + ECANCELED = 125, + ENOKEY = 126, + EKEYEXPIRED = 127, + EKEYREVOKED = 128, + EKEYREJECTED = 129, + EOWNERDEAD = 130, + ENOTRECOVERABLE = 131, + ERFKILL = 132, + EHWPOISON = 133, + Unknown(i64), +} + +impl fmt::Display for Errno { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::EPERM => write!(f, "Operation not permitted"), + Self::ENOENT => write!(f, "No such file or directory"), + Self::ESRCH => write!(f, "No such process"), + Self::EINTR => write!(f, "Interrupted system call"), + Self::EIO => write!(f, "Input/output error"), + Self::ENXIO => write!(f, "No such device or address"), + Self::E2BIG => write!(f, "Argument list too long"), + Self::ENOEXEC => write!(f, "Exec format error"), + Self::EBADF => write!(f, "Bad file descriptor"), + Self::ECHILD => write!(f, "No child processes"), + Self::EAGAIN => write!(f, "Resource temporarily unavailable"), + Self::ENOMEM => write!(f, "Cannot allocate memory"), + Self::EACCES => write!(f, "Permission denied"), + Self::EFAULT => write!(f, "Bad address"), + Self::ENOTBLK => write!(f, "Block device required"), + Self::EBUSY => write!(f, "Device or resource busy"), + Self::EEXIST => write!(f, "File exists"), + Self::EXDEV => write!(f, "Invalid cross-device link"), + Self::ENODEV => write!(f, "No such device"), + Self::ENOTDIR => write!(f, "Not a directory"), + Self::EISDIR => write!(f, "Is a directory"), + Self::EINVAL => write!(f, "Invalid argument"), + Self::ENFILE => write!(f, "Too many open files in system"), + Self::EMFILE => write!(f, "Too many open files"), + Self::ENOTTY => write!(f, "Inappropriate ioctl for device"), + Self::ETXTBSY => write!(f, "Text file busy"), + Self::EFBIG => write!(f, "File too large"), + Self::ENOSPC => write!(f, "No space left on device"), + Self::ESPIPE => write!(f, "Illegal seek"), + Self::EROFS => write!(f, "Read-only file system"), + Self::EMLINK => write!(f, "Too many links"), + Self::EPIPE => write!(f, "Broken pipe"), + Self::EDOM => write!(f, "Numerical argument out of domain"), + Self::ERANGE => write!(f, "Numerical result out of range"), + Self::ENAMETOOLONG => write!(f, "File name too long"), + Self::ENOLCK => write!(f, "No locks available"), + Self::ENOSYS => write!(f, "Function not implemented"), + Self::ENOTEMPTY => write!(f, "Directory not empty"), + Self::ELOOP => write!(f, "Too many levels of symbolic links"), + Self::ENOMSG => write!(f, "No message of desired type"), + Self::EIDRM => write!(f, "Identifier removed"), + Self::ECHRNG => write!(f, "Channel number out of range"), + Self::EL2NSYNC => write!(f, "Level 2 not synchronized"), + Self::EL3HLT => write!(f, "Level 3 halted"), + Self::EL3RST => write!(f, "Level 3 reset"), + Self::ELNRNG => write!(f, "Link number out of range"), + Self::EUNATCH => write!(f, "Protocol driver not attached"), + Self::ENOCSI => write!(f, "No CSI structure available"), + Self::EL2HLT => write!(f, "Level 2 halted"), + Self::EBADE => write!(f, "Invalid exchange"), + Self::EBADR => write!(f, "Invalid request descriptor"), + Self::EXFULL => write!(f, "Exchange full"), + Self::ENOANO => write!(f, "No anode"), + Self::EBADRQC => write!(f, "Invalid request code"), + Self::EBADSLT => write!(f, "Invalid slot"), + Self::EDEADLOCK => write!(f, "Resource deadlock avoided"), + Self::EBFONT => write!(f, "Bad font file format"), + Self::ENOSTR => write!(f, "Device not a stream"), + Self::ENODATA => write!(f, "No data available"), + Self::ETIME => write!(f, "Timer expired"), + Self::ENOSR => write!(f, "Out of streams resources"), + Self::ENONET => write!(f, "Machine is not on the network"), + Self::ENOPKG => write!(f, "Package not installed"), + Self::EREMOTE => write!(f, "Object is remote"), + Self::ENOLINK => write!(f, "Link has been severed"), + Self::EADV => write!(f, "Advertise error"), + Self::ESRMNT => write!(f, "Srmount error"), + Self::ECOMM => write!(f, "Communication error on send"), + Self::EPROTO => write!(f, "Protocol error"), + Self::EMULTIHOP => write!(f, "Multihop attempted"), + Self::EDOTDOT => write!(f, "RFS specific error"), + Self::EBADMSG => write!(f, "Bad message"), + Self::EOVERFLOW => write!(f, "Value too large for defined data type"), + Self::ENOTUNIQ => write!(f, "Name not unique on network"), + Self::EBADFD => write!(f, "File descriptor in bad state"), + Self::EREMCHG => write!(f, "Remote address changed"), + Self::ELIBACC => write!(f, "Can not access a needed shared library"), + Self::ELIBBAD => write!(f, "Accessing a corrupted shared library"), + Self::ELIBSCN => write!(f, ".lib section in a.out corrupted"), + Self::ELIBMAX => write!(f, "Attempting to link in too many shared libraries"), + Self::ELIBEXEC => write!(f, "Cannot exec a shared library directly"), + Self::EILSEQ => write!(f, "Invalid or incomplete multibyte or wide character"), + Self::ERESTART => write!(f, "Interrupted system call should be restarted"), + Self::ESTRPIPE => write!(f, "Streams pipe error"), + Self::EUSERS => write!(f, "Too many users"), + Self::ENOTSOCK => write!(f, "Socket operation on non-socket"), + Self::EDESTADDRREQ => write!(f, "Destination address required"), + Self::EMSGSIZE => write!(f, "Message too long"), + Self::EPROTOTYPE => write!(f, "Protocol wrong type for socket"), + Self::ENOPROTOOPT => write!(f, "Protocol not available"), + Self::EPROTONOSUPPORT => write!(f, "Protocol not supported"), + Self::ESOCKTNOSUPPORT => write!(f, "Socket type not supported"), + Self::EOPNOTSUPP => write!(f, "Operation not supported"), + Self::EPFNOSUPPORT => write!(f, "Protocol family not supported"), + Self::EAFNOSUPPORT => write!(f, "Address family not supported by protocol"), + Self::EADDRINUSE => write!(f, "Address already in use"), + Self::EADDRNOTAVAIL => write!(f, "Cannot assign requested address"), + Self::ENETDOWN => write!(f, "Network is down"), + Self::ENETUNREACH => write!(f, "Network is unreachable"), + Self::ENETRESET => write!(f, "Network dropped connection on reset"), + Self::ECONNABORTED => write!(f, "Software caused connection abort"), + Self::ECONNRESET => write!(f, "Connection reset by peer"), + Self::ENOBUFS => write!(f, "No buffer space available"), + Self::EISCONN => write!(f, "Transport endpoint is already connected"), + Self::ENOTCONN => write!(f, "Transport endpoint is not connected"), + Self::ESHUTDOWN => write!(f, "Cannot send after transport endpoint shutdown"), + Self::ETOOMANYREFS => write!(f, "Too many references: cannot splice"), + Self::ETIMEDOUT => write!(f, "Connection timed out"), + Self::ECONNREFUSED => write!(f, "Connection refused"), + Self::EHOSTDOWN => write!(f, "Host is down"), + Self::EHOSTUNREACH => write!(f, "No route to host"), + Self::EALREADY => write!(f, "Operation already in progress"), + Self::EINPROGRESS => write!(f, "Operation now in progress"), + Self::ESTALE => write!(f, "Stale file handle"), + Self::EUCLEAN => write!(f, "Structure needs cleaning"), + Self::ENOTNAM => write!(f, "Not a XENIX named type file"), + Self::ENAVAIL => write!(f, "No XENIX semaphores available"), + Self::EISNAM => write!(f, "Is a named type file"), + Self::EREMOTEIO => write!(f, "Remote I/O error"), + Self::EDQUOT => write!(f, "Disk quota exceeded"), + Self::ENOMEDIUM => write!(f, "No medium found"), + Self::EMEDIUMTYPE => write!(f, "Wrong medium type"), + Self::ECANCELED => write!(f, "Operation canceled"), + Self::ENOKEY => write!(f, "Required key not available"), + Self::EKEYEXPIRED => write!(f, "Key has expired"), + Self::EKEYREVOKED => write!(f, "Key has been revoked"), + Self::EKEYREJECTED => write!(f, "Key was rejected by service"), + Self::EOWNERDEAD => write!(f, "Owner died"), + Self::ENOTRECOVERABLE => write!(f, "State not recoverable"), + Self::ERFKILL => write!(f, "Operation not possible due to RF-kill"), + Self::EHWPOISON => write!(f, "Memory page has hardware error"), + Self::Unknown(n) => write!(f, "Unknown error {n}"), + } + } +} + +impl error::Error for Errno {} + +impl From for Errno { + fn from(value: usize) -> Self { + (-(value as c_long)).into() + } +} + +impl From for Errno { + fn from(value: c_long) -> Self { + match value { + 1 => Self::EPERM, + 2 => Self::ENOENT, + 3 => Self::ESRCH, + 4 => Self::EINTR, + 5 => Self::EIO, + 6 => Self::ENXIO, + 7 => Self::E2BIG, + 8 => Self::ENOEXEC, + 9 => Self::EBADF, + 10 => Self::ECHILD, + 11 => Self::EAGAIN, + 12 => Self::ENOMEM, + 13 => Self::EACCES, + 14 => Self::EFAULT, + 15 => Self::ENOTBLK, + 16 => Self::EBUSY, + 17 => Self::EEXIST, + 18 => Self::EXDEV, + 19 => Self::ENODEV, + 20 => Self::ENOTDIR, + 21 => Self::EISDIR, + 22 => Self::EINVAL, + 23 => Self::ENFILE, + 24 => Self::EMFILE, + 25 => Self::ENOTTY, + 26 => Self::ETXTBSY, + 27 => Self::EFBIG, + 28 => Self::ENOSPC, + 29 => Self::ESPIPE, + 30 => Self::EROFS, + 31 => Self::EMLINK, + 32 => Self::EPIPE, + 33 => Self::EDOM, + 34 => Self::ERANGE, + 35 => Self::EDEADLOCK, + 36 => Self::ENAMETOOLONG, + 37 => Self::ENOLCK, + 38 => Self::ENOSYS, + 39 => Self::ENOTEMPTY, + 40 => Self::ELOOP, + 42 => Self::ENOMSG, + 43 => Self::EIDRM, + 44 => Self::ECHRNG, + 45 => Self::EL2NSYNC, + 46 => Self::EL3HLT, + 47 => Self::EL3RST, + 48 => Self::ELNRNG, + 49 => Self::EUNATCH, + 50 => Self::ENOCSI, + 51 => Self::EL2HLT, + 52 => Self::EBADE, + 53 => Self::EBADR, + 54 => Self::EXFULL, + 55 => Self::ENOANO, + 56 => Self::EBADRQC, + 57 => Self::EBADSLT, + 59 => Self::EBFONT, + 60 => Self::ENOSTR, + 61 => Self::ENODATA, + 62 => Self::ETIME, + 63 => Self::ENOSR, + 64 => Self::ENONET, + 65 => Self::ENOPKG, + 66 => Self::EREMOTE, + 67 => Self::ENOLINK, + 68 => Self::EADV, + 69 => Self::ESRMNT, + 70 => Self::ECOMM, + 71 => Self::EPROTO, + 72 => Self::EMULTIHOP, + 73 => Self::EDOTDOT, + 74 => Self::EBADMSG, + 75 => Self::EOVERFLOW, + 76 => Self::ENOTUNIQ, + 77 => Self::EBADFD, + 78 => Self::EREMCHG, + 79 => Self::ELIBACC, + 80 => Self::ELIBBAD, + 81 => Self::ELIBSCN, + 82 => Self::ELIBMAX, + 83 => Self::ELIBEXEC, + 84 => Self::EILSEQ, + 85 => Self::ERESTART, + 86 => Self::ESTRPIPE, + 87 => Self::EUSERS, + 88 => Self::ENOTSOCK, + 89 => Self::EDESTADDRREQ, + 90 => Self::EMSGSIZE, + 91 => Self::EPROTOTYPE, + 92 => Self::ENOPROTOOPT, + 93 => Self::EPROTONOSUPPORT, + 94 => Self::ESOCKTNOSUPPORT, + 95 => Self::EOPNOTSUPP, + 96 => Self::EPFNOSUPPORT, + 97 => Self::EAFNOSUPPORT, + 98 => Self::EADDRINUSE, + 99 => Self::EADDRNOTAVAIL, + 100 => Self::ENETDOWN, + 101 => Self::ENETUNREACH, + 102 => Self::ENETRESET, + 103 => Self::ECONNABORTED, + 104 => Self::ECONNRESET, + 105 => Self::ENOBUFS, + 106 => Self::EISCONN, + 107 => Self::ENOTCONN, + 108 => Self::ESHUTDOWN, + 109 => Self::ETOOMANYREFS, + 110 => Self::ETIMEDOUT, + 111 => Self::ECONNREFUSED, + 112 => Self::EHOSTDOWN, + 113 => Self::EHOSTUNREACH, + 114 => Self::EALREADY, + 115 => Self::EINPROGRESS, + 116 => Self::ESTALE, + 117 => Self::EUCLEAN, + 118 => Self::ENOTNAM, + 119 => Self::ENAVAIL, + 120 => Self::EISNAM, + 121 => Self::EREMOTEIO, + 122 => Self::EDQUOT, + 123 => Self::ENOMEDIUM, + 124 => Self::EMEDIUMTYPE, + 125 => Self::ECANCELED, + 126 => Self::ENOKEY, + 127 => Self::EKEYEXPIRED, + 128 => Self::EKEYREVOKED, + 129 => Self::EKEYREJECTED, + 130 => Self::EOWNERDEAD, + 131 => Self::ENOTRECOVERABLE, + 132 => Self::ERFKILL, + 133 => Self::EHWPOISON, + n => Self::Unknown(n), + } + } +} diff --git a/hashbox/commands/sha224sum/mod.rs b/hashbox/commands/sha224sum/mod.rs index c654a86..caba637 100644 --- a/hashbox/commands/sha224sum/mod.rs +++ b/hashbox/commands/sha224sum/mod.rs @@ -3,7 +3,7 @@ use crate::hash::{self, HashType}; use clap::Command; use sha2::{Digest, Sha224}; use shitbox::args; -use std::{io, process}; +use std::io; #[derive(Debug, Default)] pub struct Sha224sum; diff --git a/pw/src/lib.rs b/pw/src/lib.rs index 9b5c203..eff1a7a 100644 --- a/pw/src/lib.rs +++ b/pw/src/lib.rs @@ -83,7 +83,7 @@ pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> { pub fn get_gid_for_groupname(groupname: &str) -> Option { let Ok(grp) = CString::new(groupname.as_bytes()) else { return None }; - unsafe { Some((*libc::getgrnam(grp.as_ptr())).gr_gid as u32) } + unsafe { Some((*libc::getgrnam(grp.as_ptr())).gr_gid) } } pub fn get_groupname_for_gid<'a>(gid: u32) -> Result<&'a str, std::str::Utf8Error> { diff --git a/unistd/Cargo.toml b/unistd/Cargo.toml index 5d5da8d..9c0711e 100644 --- a/unistd/Cargo.toml +++ b/unistd/Cargo.toml @@ -8,3 +8,7 @@ edition = "2021" [dependencies] libc = { workspace = true } sc = { workspace = true } + +[dependencies.errno] +package = "errno" +path = "../errno" diff --git a/unistd/src/lib.rs b/unistd/src/lib.rs index 183f862..11e2354 100644 --- a/unistd/src/lib.rs +++ b/unistd/src/lib.rs @@ -1,6 +1,7 @@ +use errno::Errno; use libc::utsname; use sc::syscall; -use std::{ffi::CString, fs::File, io, os::fd::AsRawFd, u8}; +use std::{error::Error, ffi::CString, fs::File, os::fd::AsRawFd, u8}; #[inline(always)] fn new_utsname() -> utsname { @@ -15,11 +16,12 @@ fn new_utsname() -> utsname { } #[inline(always)] -pub fn gethostname() -> io::Result { +pub fn gethostname() -> Result> { let mut uts = new_utsname(); unsafe { - if syscall!(UNAME, &mut uts as *mut utsname) != 0 { - return Err(io::Error::last_os_error()); + let ret = syscall!(UNAME, &mut uts as *mut utsname); + if ret != 0 { + return Err(Errno::from(ret).into()); } } let name = uts @@ -28,21 +30,21 @@ pub fn gethostname() -> io::Result { .map(|x| *x as u8) .take_while(|x| *x != 0) .collect(); - String::from_utf8(name).map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + String::from_utf8(name).map_err(|e| e.into()) } #[inline(always)] -pub fn sethostname(name: &str) -> io::Result<()> { +pub fn sethostname(name: &str) -> Result<(), Errno> { let ret = unsafe { syscall!(SETHOSTNAME, name.as_ptr(), name.len()) }; if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error().into()) + Err(ret.into()) } } #[inline(always)] -pub fn link(source: &str, dest: &str) -> io::Result<()> { +pub fn link(source: &str, dest: &str) -> Result<(), Box> { let ret = unsafe { syscall!( LINKAT, @@ -56,22 +58,22 @@ pub fn link(source: &str, dest: &str) -> io::Result<()> { if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error()) + Err(Errno::from(ret).into()) } } #[inline(always)] -pub fn unlink(name: &str) -> io::Result<()> { +pub fn unlink(name: &str) -> Result<(), Box> { let ret = unsafe { syscall!(UNLINKAT, libc::AT_FDCWD, CString::new(name)?.as_ptr(), 0) }; if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error().into()) + Err(Errno::from(ret).into()) } } #[inline(always)] -pub fn readlink(name: &str) -> io::Result { +pub fn readlink(name: &str) -> Result> { let mut buf = Vec::::with_capacity(1024); let ret = unsafe { syscall!( @@ -88,39 +90,39 @@ pub fn readlink(name: &str) -> io::Result { .map(|x| *x as u8) .take_while(|x| *x != 0) .collect(); - String::from_utf8(path).map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + String::from_utf8(path).map_err(|e| e.into()) } else { - Err(io::Error::last_os_error()) + Err(Errno::from(ret).into()) } } #[inline(always)] -pub fn fdatasync(fd: &File) -> io::Result<()> { +pub fn fdatasync(fd: &File) -> Result<(), Errno> { let ret = unsafe { syscall!(FDATASYNC, fd.as_raw_fd()) }; if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error()) + Err(ret.into()) } } #[inline(always)] -pub fn syncfs(fd: &File) -> io::Result<()> { +pub fn syncfs(fd: &File) -> Result<(), Errno> { let ret = unsafe { syscall!(SYNCFS, fd.as_raw_fd()) }; if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error()) + Err(ret.into()) } } #[inline(always)] -pub fn fsync(fd: &File) -> io::Result<()> { +pub fn fsync(fd: &File) -> Result<(), Errno> { let ret = unsafe { syscall!(FSYNC, fd.as_raw_fd()) }; if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error()) + Err(ret.into()) } } @@ -130,7 +132,7 @@ pub fn sync() { } #[inline(always)] -pub fn symlink(source: &str, dest: &str) -> io::Result<()> { +pub fn symlink(source: &str, dest: &str) -> Result<(), Box> { let ret = unsafe { syscall!( SYMLINKAT, @@ -142,6 +144,6 @@ pub fn symlink(source: &str, dest: &str) -> io::Result<()> { if ret == 0 { Ok(()) } else { - Err(io::Error::last_os_error()) + Err(Errno::from(ret).into()) } }