From 986754e7b3dd9d9503a7d142564dba057d4811ad Mon Sep 17 00:00:00 2001
From: 4lDO2 <4lDO2@protonmail.com>
Date: Fri, 27 Sep 2024 10:29:32 +0200
Subject: [PATCH] Remove all remaining errno interfaces from Pal.

---
 src/header/unistd/brk.rs  |  7 ++++---
 src/header/unistd/mod.rs  | 21 ++++++++++++---------
 src/platform/linux/mod.rs | 13 +++++--------
 src/platform/pal/mod.rs   | 11 +++++++++--
 src/platform/redox/mod.rs | 35 +++++++++++------------------------
 5 files changed, 41 insertions(+), 46 deletions(-)

diff --git a/src/header/unistd/brk.rs b/src/header/unistd/brk.rs
index 7efa5c2be..47907758c 100644
--- a/src/header/unistd/brk.rs
+++ b/src/header/unistd/brk.rs
@@ -1,6 +1,7 @@
 use core::ptr;
 
 use crate::{
+    error::ResultExtPtrMut,
     header::errno::ENOMEM,
     platform::{self, types::*, Pal, Sys},
 };
@@ -9,7 +10,7 @@ static mut BRK: *mut c_void = ptr::null_mut();
 
 #[no_mangle]
 pub unsafe extern "C" fn brk(addr: *mut c_void) -> c_int {
-    BRK = Sys::brk(addr);
+    BRK = Sys::brk(addr).or_errno_null_mut();
 
     if BRK < addr {
         platform::ERRNO.set(ENOMEM);
@@ -22,7 +23,7 @@ pub unsafe extern "C" fn brk(addr: *mut c_void) -> c_int {
 #[no_mangle]
 pub unsafe extern "C" fn sbrk(incr: intptr_t) -> *mut c_void {
     if BRK.is_null() {
-        BRK = Sys::brk(ptr::null_mut());
+        BRK = Sys::brk(ptr::null_mut()).or_errno_null_mut();
     }
 
     let old_brk = BRK;
@@ -30,7 +31,7 @@ pub unsafe extern "C" fn sbrk(incr: intptr_t) -> *mut c_void {
     if incr != 0 {
         let addr = old_brk.offset(incr);
 
-        BRK = Sys::brk(addr);
+        BRK = Sys::brk(addr).or_errno_null_mut();
 
         if BRK < addr {
             platform::ERRNO.set(ENOMEM);
diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs
index e987f43b8..1ead4b032 100644
--- a/src/header/unistd/mod.rs
+++ b/src/header/unistd/mod.rs
@@ -9,7 +9,7 @@ use core::{
 
 use crate::{
     c_str::CStr,
-    error::ResultExt,
+    error::{Errno, ResultExt},
     header::{
         crypt::{crypt_data, crypt_r},
         errno, fcntl, limits,
@@ -17,7 +17,7 @@ use crate::{
         sys_ioctl, sys_resource, sys_time, sys_utsname, termios,
         time::timespec,
     },
-    platform::{self, types::*, Pal, Sys},
+    platform::{self, types::*, Pal, Sys, ERRNO},
 };
 
 use alloc::collections::LinkedList;
@@ -377,7 +377,7 @@ pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int {
 }
 
 #[no_mangle]
-pub extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char {
+pub unsafe extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char {
     let alloc = buf.is_null();
     let mut stack_buf = [0; limits::PATH_MAX];
     if alloc {
@@ -385,10 +385,13 @@ pub extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char
         size = stack_buf.len();
     }
 
-    let ret = Sys::getcwd(buf, size);
-    if ret.is_null() {
-        return ptr::null_mut();
-    }
+    let ret = match Sys::getcwd(buf, size) {
+        Ok(()) => buf,
+        Err(Errno(errno)) => {
+            ERRNO.set(errno);
+            return ptr::null_mut();
+        }
+    };
 
     if alloc {
         let len = stack_buf
@@ -537,8 +540,8 @@ pub extern "C" fn getuid() -> uid_t {
 }
 
 #[no_mangle]
-pub extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char {
-    getcwd(path_name, limits::PATH_MAX)
+pub unsafe extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char {
+    unsafe { getcwd(path_name, limits::PATH_MAX) }
 }
 
 #[no_mangle]
diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs
index 4c505cebd..332244df9 100644
--- a/src/platform/linux/mod.rs
+++ b/src/platform/linux/mod.rs
@@ -92,8 +92,8 @@ impl Pal for Sys {
         e_raw(unsafe { syscall!(ACCESS, path.as_ptr(), mode) }).map(|_| ())
     }
 
-    unsafe fn brk(addr: *mut c_void) -> *mut c_void {
-        unsafe { syscall!(BRK, addr) as *mut c_void }
+    unsafe fn brk(addr: *mut c_void) -> Result<*mut c_void> {
+        Ok(e_raw(unsafe { syscall!(BRK, addr) })? as *mut c_void)
     }
 
     fn chdir(path: CStr) -> Result<()> {
@@ -273,12 +273,9 @@ impl Pal for Sys {
         e_raw(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path.as_ptr(), times, 0) }).map(|_| ())
     }
 
-    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
-        if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 {
-            ptr::null_mut()
-        } else {
-            buf
-        }
+    unsafe fn getcwd(buf: *mut c_char, size: size_t) -> Result<()> {
+        e_raw(unsafe { syscall!(GETCWD, buf, size) })?;
+        Ok(())
     }
 
     fn getdents(fd: c_int, buf: &mut [u8], _off: u64) -> Result<usize> {
diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs
index 071d644fb..e1f874d3d 100644
--- a/src/platform/pal/mod.rs
+++ b/src/platform/pal/mod.rs
@@ -28,7 +28,7 @@ mod socket;
 pub trait Pal {
     fn access(path: CStr, mode: c_int) -> Result<()>;
 
-    unsafe fn brk(addr: *mut c_void) -> *mut c_void;
+    unsafe fn brk(addr: *mut c_void) -> Result<*mut c_void>;
 
     fn chdir(path: CStr) -> Result<()>;
 
@@ -92,7 +92,7 @@ pub trait Pal {
 
     unsafe fn utimens(path: CStr, times: *const timespec) -> Result<()>;
 
-    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
+    unsafe fn getcwd(buf: *mut c_char, size: size_t) -> Result<()>;
 
     fn getdents(fd: c_int, buf: &mut [u8], opaque_offset: u64) -> Result<usize>;
     fn dir_seek(fd: c_int, opaque_offset: u64) -> Result<()>;
@@ -102,10 +102,13 @@ pub trait Pal {
     // possible this_dent slice is safe (and will be validated).
     unsafe fn dent_reclen_offset(this_dent: &[u8], offset: usize) -> Option<(u16, u64)>;
 
+    // Always successful
     fn getegid() -> gid_t;
 
+    // Always successful
     fn geteuid() -> uid_t;
 
+    // Always successful
     fn getgid() -> gid_t;
 
     unsafe fn getgroups(size: c_int, list: *mut gid_t) -> Result<c_int>;
@@ -117,8 +120,10 @@ pub trait Pal {
 
     fn getpgid(pid: pid_t) -> Result<pid_t>;
 
+    // Always successful
     fn getpid() -> pid_t;
 
+    // Always successful
     fn getppid() -> pid_t;
 
     fn getpriority(which: c_int, who: id_t) -> Result<c_int>;
@@ -133,6 +138,7 @@ pub trait Pal {
 
     fn getsid(pid: pid_t) -> Result<pid_t>;
 
+    // Always successful
     fn gettid() -> pid_t;
 
     unsafe fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> Result<()>;
@@ -224,6 +230,7 @@ pub trait Pal {
 
     fn sync() -> Result<()>;
 
+    // Always successful
     fn umask(mask: mode_t) -> mode_t;
 
     unsafe fn uname(utsname: *mut utsname) -> Result<()>;
diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
index 31b8adce3..264a09b11 100644
--- a/src/platform/redox/mod.rs
+++ b/src/platform/redox/mod.rs
@@ -74,6 +74,7 @@ macro_rules! path_from_c_str {
 
 use self::{exec::Executable, path::canonicalize};
 
+// TODO: Remove
 pub fn e(sys: syscall::error::Result<usize>) -> usize {
     match sys {
         Ok(ok) => ok,
@@ -118,27 +119,20 @@ impl Pal for Sys {
         Ok(())
     }
 
-    // TODO: Rustify
-    unsafe fn brk(addr: *mut c_void) -> *mut c_void {
+    unsafe fn brk(addr: *mut c_void) -> Result<*mut c_void> {
         // On first invocation, allocate a buffer for brk
         if BRK_CUR.is_null() {
             // 4 megabytes of RAM ought to be enough for anybody
             const BRK_MAX_SIZE: usize = 4 * 1024 * 1024;
 
-            let allocated = match Self::mmap(
+            let allocated = Self::mmap(
                 ptr::null_mut(),
                 BRK_MAX_SIZE,
                 PROT_READ | PROT_WRITE,
                 MAP_ANONYMOUS,
                 0,
                 0,
-            ) {
-                Ok(allocated) => allocated,
-                Err(Errno(errno)) => {
-                    ERRNO.set(errno);
-                    return !0 as *mut c_void;
-                }
-            };
+            )?;
 
             BRK_CUR = allocated;
             BRK_END = (allocated as *mut u8).add(BRK_MAX_SIZE) as *mut c_void;
@@ -146,15 +140,14 @@ impl Pal for Sys {
 
         if addr.is_null() {
             // Lookup what previous brk() invocations have set the address to
-            BRK_CUR
+            Ok(BRK_CUR)
         } else if BRK_CUR <= addr && addr < BRK_END {
             // It's inside buffer, return
             BRK_CUR = addr;
-            addr
+            Ok(addr)
         } else {
             // It was outside of valid range
-            ERRNO.set(ENOMEM);
-            ptr::null_mut()
+            Err(Errno(ENOMEM))
         }
     }
 
@@ -325,22 +318,16 @@ impl Pal for Sys {
         Self::futimens(*file, times)
     }
 
-    // FIXME: unsound
-    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
+    unsafe fn getcwd(buf: *mut c_char, size: size_t) -> Result<()> {
         // TODO: Not using MaybeUninit seems a little unsafe
 
         let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize) };
         if buf_slice.is_empty() {
-            ERRNO.set(EINVAL);
-            return ptr::null_mut();
-        }
-
-        if path::getcwd(buf_slice).is_none() {
-            ERRNO.set(ERANGE);
-            return ptr::null_mut();
+            return Err(Errno(EINVAL));
         }
 
-        buf
+        path::getcwd(buf_slice).ok_or(Errno(ERANGE))?;
+        Ok(())
     }
 
     fn getdents(fd: c_int, buf: &mut [u8], opaque: u64) -> Result<usize> {
-- 
GitLab