diff --git a/src/header/sys_utsname/mod.rs b/src/header/sys_utsname/mod.rs index 9e74d6f181fb56d229773d67a1f2e661687a9f36..032998d58634fd6e238cd24ce916696557b6164b 100644 --- a/src/header/sys_utsname/mod.rs +++ b/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::*; diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 721c96de21fa9e173041a81165fa59b1133e2064..ce1443c5ceef0af2cb50b85ee193175b8f89b4ce 100644 --- a/src/platform/linux/mod.rs +++ b/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 } diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 14f579cc116b066237c50fa162435ed2e19c8c0a..0866f1f4f3921b76ec741354e025f201b9d40932 100644 --- a/src/platform/pal/mod.rs +++ b/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; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index d53cbeb12469adc4b4927b52f7af60bba5ee61c4..df33302644f3e1ca55896a3938151ee0bab986ad 100644 --- a/src/platform/redox/mod.rs +++ b/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 } diff --git a/tests/Makefile b/tests/Makefile index 2a8cb5aefce53abd421bb08c786a9750218fd420..e8e4684da49853a94a1b9800a0cd0ed5a34ae325 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -91,6 +91,7 @@ BINS=\ stdlib/bsearch \ stdlib/mktemp \ stdlib/realpath \ + sys_utsname/uname \ time/gettimeofday \ unistd/chdir \ unistd/getcwd \ diff --git a/tests/sys_utsname/uname.c b/tests/sys_utsname/uname.c new file mode 100644 index 0000000000000000000000000000000000000000..c58c8cb1922b5b138116db27af1846ae6fc96a1f --- /dev/null +++ b/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); + } +}