2
0
Эх сурвалжийг харах

Convert errors and set errno

Jeremy Soller 7 жил өмнө
parent
commit
a1ce114cd4

+ 4 - 0
src/platform/src/lib.rs

@@ -2,6 +2,7 @@
 
 #![no_std]
 #![allow(non_camel_case_types)]
+#![feature(thread_local)]
 
 #[cfg(all(not(feature = "no_std"), target_os = "linux"))]
 #[macro_use]
@@ -27,6 +28,9 @@ use core::fmt;
 
 use types::*;
 
+#[thread_local]
+pub static mut errno: c_int = 0;
+
 pub unsafe fn c_str(s: *const c_char) -> &'static [u8] {
     use core::slice;
 

+ 37 - 22
src/platform/src/linux/mod.rs

@@ -1,7 +1,21 @@
+use core::ptr;
+
+use errno;
 use types::*;
 
 const AT_FDCWD: c_int = -100;
 
+pub fn e(sys: usize) -> usize {
+    if (sys as isize) < 0 && (sys as isize) >= -256 {
+        unsafe {
+            errno = -(sys as isize) as c_int;
+        }
+        !0
+    } else {
+        sys
+    }
+}
+
 pub fn brk(addr: *const c_void) -> c_int {
     unsafe {
         let newbrk = syscall!(BRK, addr);
@@ -14,23 +28,23 @@ pub fn brk(addr: *const c_void) -> c_int {
 }
 
 pub fn chdir(path: *const c_char) -> c_int {
-    unsafe { syscall!(CHDIR, path) as c_int }
+    e(unsafe { syscall!(CHDIR, path) }) as c_int
 }
 
 pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
-    unsafe { syscall!(FCHOWNAT, AT_FDCWD, path, owner as u32, group as u32) as c_int }
+    e(unsafe { syscall!(FCHOWNAT, AT_FDCWD, path, owner as u32, group as u32) }) as c_int
 }
 
 pub fn close(fildes: c_int) -> c_int {
-    unsafe { syscall!(CLOSE, fildes) as c_int }
+    e(unsafe { syscall!(CLOSE, fildes) }) as c_int
 }
 
 pub fn dup(fildes: c_int) -> c_int {
-    unsafe { syscall!(DUP, fildes) as c_int }
+    e(unsafe { syscall!(DUP, fildes) }) as c_int
 }
 
 pub fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
-    unsafe { syscall!(DUP3, fildes, fildes2, 0) as c_int }
+    e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
 }
 
 pub fn exit(status: c_int) -> ! {
@@ -41,64 +55,65 @@ pub fn exit(status: c_int) -> ! {
 }
 
 pub fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
-    unsafe { syscall!(FCHOWN, fildes, owner, group) as c_int }
+    e(unsafe { syscall!(FCHOWN, fildes, owner, group) }) as c_int
 }
 
 pub fn fchdir(fildes: c_int) -> c_int {
-    unsafe { syscall!(FCHDIR, fildes) as c_int }
+    e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
 }
 
 pub fn fsync(fildes: c_int) -> c_int {
-    unsafe { syscall!(FSYNC, fildes) as c_int }
+    e(unsafe { syscall!(FSYNC, fildes) }) as c_int
 }
 
 pub fn ftruncate(fildes: c_int, length: off_t) -> c_int {
-    unsafe { syscall!(FTRUNCATE, fildes, length) as c_int }
+    e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int
 }
 
 pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
-    unsafe {
-        syscall!(GETCWD, buf, size);
-        buf as *mut c_char
+    if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 {
+        ptr::null_mut()
+    } else {
+        buf
     }
 }
 
 pub fn getegid() -> gid_t {
-    unsafe { syscall!(GETEGID) }
+    e(unsafe { syscall!(GETEGID) })
 }
 
 pub fn geteuid() -> uid_t {
-    unsafe { syscall!(GETEUID) }
+    e(unsafe { syscall!(GETEUID) })
 }
 
 pub fn getgid() -> gid_t {
-    unsafe { syscall!(GETGID) }
+    e(unsafe { syscall!(GETGID) })
 }
 
 pub fn getpgid(pid: pid_t) -> pid_t {
-    unsafe { syscall!(GETPGID, pid) }
+    e(unsafe { syscall!(GETPGID, pid) })
 }
 
 pub fn getpid() -> pid_t {
-    unsafe { syscall!(GETPID) }
+    e(unsafe { syscall!(GETPID) })
 }
 
 pub fn getppid() -> pid_t {
-    unsafe { syscall!(GETPPID) }
+    e(unsafe { syscall!(GETPPID) })
 }
 
 pub fn getuid() -> uid_t {
-    unsafe { syscall!(GETUID) }
+    e(unsafe { syscall!(GETUID) })
 }
 
 pub fn link(path1: *const c_char, path2: *const c_char) -> c_int {
-    unsafe { syscall!(LINKAT, AT_FDCWD, path1, path2) as c_int }
+    e(unsafe { syscall!(LINKAT, AT_FDCWD, path1, path2) }) as c_int
 }
 
 pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
-    unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) as c_int }
+    e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int
 }
 
 pub fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
-    unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) as ssize_t }
+    e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
 }

+ 42 - 31
src/platform/src/redox/mod.rs

@@ -1,34 +1,48 @@
+use core::ptr;
 use core::slice;
 use syscall;
+
 use c_str;
+use errno;
 use types::*;
 
+pub fn e(sys: Result<usize, syscall::Error>) -> usize {
+    match sys {
+        Ok(ok) => ok,
+        Err(err) => {
+            unsafe {
+                errno = err.errno as c_int;
+            }
+            !0
+        }
+    }
+}
+
 pub fn brk(addr: *const c_void) -> c_int {
-    unsafe { syscall::brk(addr as usize).unwrap_or(0 - 1) as c_int }
+    e(unsafe { syscall::brk(addr as usize) }) as c_int
 }
 
 pub fn chdir(path: *const c_char) -> c_int {
     let path = unsafe { c_str(path) };
-    syscall::chdir(path).unwrap_or(-1) as c_int
+    e(syscall::chdir(path)) as c_int
 }
 
 pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
     let path = unsafe { c_str(path) };
     let fd = syscall::open(path, 0x0001).unwrap();
-    syscall::fchown(fd as usize, owner as u32, group as u32).unwrap_or(0 - 1) as c_int
+    e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
 }
 
 pub fn close(fd: c_int) -> c_int {
-    syscall::close(fd as usize);
-    0
+    e(syscall::close(fd as usize)) as c_int
 }
 
 pub fn dup(fd: c_int) -> c_int {
-    syscall::dup(fd as usize, &[]).unwrap_or(0 - 1) as c_int
+    e(syscall::dup(fd as usize, &[])) as c_int
 }
 
 pub fn dup2(fd1: c_int, fd2: c_int) -> c_int {
-    syscall::dup2(fd1 as usize, fd2 as usize, &[]).unwrap_or(0 - 1) as c_int
+    e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int
 }
 
 pub fn exit(status: c_int) -> ! {
@@ -37,77 +51,74 @@ pub fn exit(status: c_int) -> ! {
 }
 
 pub fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int {
-    syscall::fchown(fd as usize, owner as u32, group as u32).unwrap_or(0 - 1) as c_int
+    e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
 }
 
 pub fn fchdir(fd: c_int) -> c_int {
     let path: &mut [u8] = &mut [0; 4096];
-    let result = syscall::fpath(fd as usize, path);
-    if result.is_ok() {
-        syscall::chdir(path).unwrap_or(0 - 1) as c_int
+    if e(syscall::fpath(fd as usize, path)) == !0 {
+        !0
     } else {
-        -1
+        e(syscall::chdir(path)) as c_int
     }
 }
 
 pub fn fsync(fd: c_int) -> c_int {
-    syscall::fsync(fd as usize).unwrap_or(0 - 1) as c_int
+    e(syscall::fsync(fd as usize)) as c_int
 }
 
 pub fn ftruncate(fd: c_int, len: off_t) -> c_int {
-    syscall::ftruncate(fd as usize, len as usize).unwrap_or(0 - 1) as c_int
+    e(syscall::ftruncate(fd as usize, len as usize)) as c_int
 }
 
 pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
-    // XXX: do something with size maybe
-    let rbuf: &mut [u8] = &mut [0; 4096];
-    syscall::getcwd(rbuf);
-    unsafe {
-        let buf = *rbuf.as_ptr() as *mut c_char;
+    let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize) };
+    if e(syscall::getcwd(buf_slice)) == !0 {
+        ptr::null_mut()
+    } else {
+        buf
     }
-    buf
 }
 
 pub fn getegid() -> gid_t {
-    syscall::getegid().unwrap() as gid_t
+    e(syscall::getegid()) as gid_t
 }
 
 pub fn geteuid() -> uid_t {
-    syscall::geteuid().unwrap() as uid_t
+    e(syscall::geteuid()) as uid_t
 }
 
 pub fn getgid() -> gid_t {
-    syscall::getgid().unwrap() as gid_t
+    e(syscall::getgid()) as gid_t
 }
 
 pub fn getpgid(pid: pid_t) -> pid_t {
-    syscall::getpgid(pid as usize).unwrap() as pid_t
+    e(syscall::getpgid(pid as usize)) as pid_t
 }
 
 pub fn getpid() -> pid_t {
-    syscall::getpid().unwrap() as pid_t
+    e(syscall::getpid()) as pid_t
 }
 
 pub fn getppid() -> pid_t {
-    syscall::getppid().unwrap() as pid_t
+    e(syscall::getppid()) as pid_t
 }
 
 pub fn getuid() -> uid_t {
-    syscall::getuid().unwrap() as pid_t
+    e(syscall::getuid()) as pid_t
 }
 
 pub fn link(path1: *const c_char, path2: *const c_char) -> c_int {
     let path1 = unsafe { c_str(path1) };
     let path2 = unsafe { c_str(path2) };
-    unsafe { syscall::link(path1.as_ptr(), path2.as_ptr()).unwrap_or(0 - 1) as c_int }
+    e(unsafe { syscall::link(path1.as_ptr(), path2.as_ptr()) }) as c_int
 }
 
 pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
     let path = unsafe { c_str(path) };
-    syscall::open(path, (oflag as usize) | (mode as usize)).unwrap() as c_int
+    e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int
 }
 
 pub fn write(fd: c_int, buf: &[u8]) -> ssize_t {
-    syscall::write(fd as usize, buf);
-    buf.len() as ssize_t
+    e(syscall::write(fd as usize, buf)) as ssize_t
 }