Browse Source

Implement uname for Redox

Tibor Nagy 6 years ago
parent
commit
012a9b2eb3

+ 5 - 12
src/header/sys_utsname/mod.rs

@@ -1,5 +1,6 @@
-//! sys/utsname implementation for linux, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html
+//! sys/utsname implementation, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html
 
+use platform::{Pal, Sys};
 use platform::types::*;
 
 pub const UTSLENGTH: usize = 65;
@@ -14,15 +15,7 @@ pub struct utsname {
     pub domainname: [c_char; UTSLENGTH],
 }
 
-#[cfg(target_os = "linux")]
-mod inner {
-    use super::*;
-    use platform::Sys;
-
-    #[no_mangle]
-    pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int {
-        Sys::uname(uts)
-    }
+#[no_mangle]
+pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int {
+    Sys::uname(uts)
 }
-#[cfg(target_os = "linux")]
-pub use self::inner::*;

+ 4 - 4
src/platform/linux/mod.rs

@@ -60,10 +60,6 @@ impl Sys {
     // fn times(out: *mut tms) -> clock_t {
     //     unsafe { syscall!(TIMES, out) as clock_t }
     // }
-
-    pub fn uname(utsname: *mut utsname) -> c_int {
-        e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
-    }
 }
 
 impl Pal for Sys {
@@ -386,6 +382,10 @@ impl Pal for Sys {
         unsafe { syscall!(UMASK, mask) as mode_t }
     }
 
+    fn uname(utsname: *mut utsname) -> c_int {
+        e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
+    }
+
     fn unlink(path: &CStr) -> c_int {
         e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }) as c_int
     }

+ 3 - 0
src/platform/pal/mod.rs

@@ -4,6 +4,7 @@ use header::dirent::dirent;
 use header::sys_select::fd_set;
 use header::sys_stat::stat;
 use header::sys_time::{timeval, timezone};
+use header::sys_utsname::utsname;
 use header::termios::termios;
 use header::time::timespec;
 
@@ -139,6 +140,8 @@ pub trait Pal {
 
     fn umask(mask: mode_t) -> mode_t;
 
+    fn uname(utsname: *mut utsname) -> c_int;
+
     fn unlink(path: &CStr) -> c_int;
 
     fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t;

+ 57 - 0
src/platform/redox/mod.rs

@@ -3,6 +3,7 @@
 use alloc::collections::BTreeMap;
 use cbitset::BitSet;
 use core::{mem, ptr, slice};
+use core::result::Result as CoreResult;
 use spin::{Mutex, MutexGuard, Once};
 use syscall::data::Stat as redox_stat;
 use syscall::data::TimeSpec as redox_timespec;
@@ -20,6 +21,7 @@ const MAP_ANON: c_int = 1;
 use header::sys_select::fd_set;
 use header::sys_stat::stat;
 use header::sys_time::{timeval, timezone};
+use header::sys_utsname::{utsname, UTSLENGTH};
 use header::termios::termios;
 use header::time::timespec;
 use header::unistd::{F_OK, R_OK, SEEK_SET, W_OK, X_OK};
@@ -903,6 +905,61 @@ impl Pal for Sys {
         e(syscall::umask(mask as usize)) as mode_t
     }
 
+    fn uname(utsname: *mut utsname) -> c_int {
+        fn inner(utsname: *mut utsname) -> CoreResult<(), i32> {
+            let file_path = unsafe { CStr::from_bytes_with_nul_unchecked(b"sys:uname\0") };
+            let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
+                Ok(file) => file,
+                Err(_) => return Err(EIO),
+            };
+            let mut lines = BufReader::new(&mut file).lines();
+
+            let mut read_line = |dst: &mut [c_char]| {
+                let line = match lines.next() {
+                    Some(Ok(l)) => {
+                        match CString::new(l) {
+                            Ok(l) => l,
+                            Err(_) => return Err(EIO),
+                        }
+                    },
+                    None | Some(Err(_)) => return Err(EIO),
+                };
+
+                let line_slice: &[c_char] = unsafe {
+                    mem::transmute(line.as_bytes_with_nul())
+                };
+
+                if line_slice.len() <= UTSLENGTH {
+                    dst[..line_slice.len()].copy_from_slice(line_slice);
+                    Ok(())
+                } else {
+                    Err(EIO)
+                }
+            };
+
+            unsafe {
+                read_line(&mut (*utsname).sysname)?;
+                read_line(&mut (*utsname).nodename)?;
+                read_line(&mut (*utsname).release)?;
+                read_line(&mut (*utsname).version)?;
+                read_line(&mut (*utsname).machine)?;
+
+                // Redox doesn't provide domainname in sys:uname
+                //read_line(&mut (*utsname).domainname)?;
+                ptr::write_bytes((*utsname).domainname.as_mut_ptr(), 0, UTSLENGTH);
+            }
+            Ok(())
+        }
+
+        match inner(utsname) {
+            Ok(()) => 0,
+            Err(err) => unsafe {
+                errno = err;
+                -1
+            }
+        }
+    }
+
     fn unlink(path: &CStr) -> c_int {
         e(syscall::unlink(path.to_bytes())) as c_int
     }

+ 1 - 0
tests/Makefile

@@ -91,6 +91,7 @@ BINS=\
 	stdlib/bsearch \
 	stdlib/mktemp \
 	stdlib/realpath \
+	sys_utsname/uname \
 	time/gettimeofday \
 	unistd/chdir \
 	unistd/getcwd \

+ 19 - 0
tests/sys_utsname/uname.c

@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <sys/utsname.h>
+
+int main() {
+    struct utsname system_info;
+
+    int result = uname(&system_info);
+
+    if (result < 0) {
+        perror("uname");
+    } else {
+        printf("sysname: '%s'\n", system_info.sysname);
+        printf("nodename: '%s'\n", system_info.nodename);
+        printf("release: '%s'\n", system_info.release);
+        printf("version: '%s'\n", system_info.version);
+        printf("machine: '%s'\n", system_info.machine);
+        printf("domainname: '%s'\n", system_info.domainname);
+    }
+}