|
| 1 | +#![cfg(target_os = "linux")] |
| 2 | + |
| 3 | +use std::mem; |
| 4 | +use std::c_str::CString; |
| 5 | +use libc::{c_char}; |
| 6 | + |
| 7 | +mod ffi { |
| 8 | + use libc::c_int; |
| 9 | + use super::UtsName; |
| 10 | + |
| 11 | + extern { |
| 12 | + pub fn uname(buf: *mut UtsName) -> c_int; |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | + |
| 17 | +#[cfg(target_arch = "x86_64")] |
| 18 | +static UTSNAME_LEN: uint = 65; |
| 19 | + |
| 20 | +pub struct UtsName { |
| 21 | + sysname: [c_char, ..UTSNAME_LEN], |
| 22 | + nodename: [c_char, ..UTSNAME_LEN], |
| 23 | + release: [c_char, ..UTSNAME_LEN], |
| 24 | + version: [c_char, ..UTSNAME_LEN], |
| 25 | + machine: [c_char, ..UTSNAME_LEN], |
| 26 | + // ifdef _GNU_SOURCE |
| 27 | + domainname: [c_char, ..UTSNAME_LEN] |
| 28 | +} |
| 29 | + |
| 30 | +impl UtsName { |
| 31 | + pub fn sysname<'a>(&'a self) -> &'a str { |
| 32 | + to_str(&self.sysname as *const c_char) |
| 33 | + } |
| 34 | + |
| 35 | + pub fn nodename<'a>(&'a self) -> &'a str { |
| 36 | + to_str(&self.nodename as *const c_char) |
| 37 | + } |
| 38 | + |
| 39 | + pub fn release<'a>(&'a self) -> &'a str { |
| 40 | + to_str(&self.release as *const c_char) |
| 41 | + } |
| 42 | + |
| 43 | + pub fn version<'a>(&'a self) -> &'a str { |
| 44 | + to_str(&self.version as *const c_char) |
| 45 | + } |
| 46 | + |
| 47 | + pub fn machine<'a>(&'a self) -> &'a str { |
| 48 | + to_str(&self.machine as *const c_char) |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +pub fn uname() -> UtsName { |
| 53 | + unsafe { |
| 54 | + let mut ret: UtsName = mem::uninitialized(); |
| 55 | + ffi::uname(&mut ret as *mut UtsName); |
| 56 | + ret |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +#[inline] |
| 61 | +fn to_str<'a>(s: *const c_char) -> &'a str { |
| 62 | + unsafe { |
| 63 | + let res = CString::new(s, false); |
| 64 | + mem::transmute(res.as_str().expect("[BUG] uname field not UTF-8")) |
| 65 | + } |
| 66 | +} |
0 commit comments