use crate::{FromInner, IntoInner};
use std::ffi::CStr;
use uv::{
uv_os_free_passwd, uv_os_get_passwd, uv_os_gethostname, uv_os_getpid, uv_os_getppid,
uv_os_getpriority, uv_os_setpriority, uv_os_uname, uv_passwd_t, uv_utsname_t,
UV_MAXHOSTNAMESIZE,
};
pub type Pid = i32;
pub struct User {
pub username: String,
pub uid: Option<crate::Uid>,
pub gid: Option<crate::Gid>,
pub shell: Option<String>,
pub homedir: String,
}
impl FromInner<uv_passwd_t> for User {
fn from_inner(passwd: uv_passwd_t) -> User {
let username = unsafe { CStr::from_ptr(passwd.username) }
.to_string_lossy()
.into_owned();
let homedir = unsafe { CStr::from_ptr(passwd.homedir) }
.to_string_lossy()
.into_owned();
let shell = if passwd.shell.is_null() {
None
} else {
Some(
unsafe { CStr::from_ptr(passwd.shell) }
.to_string_lossy()
.into_owned(),
)
};
let uid = if passwd.uid >= 0 {
Some(passwd.uid as _)
} else {
None
};
let gid = if passwd.gid >= 0 {
Some(passwd.gid as _)
} else {
None
};
User {
username,
uid,
gid,
shell,
homedir,
}
}
}
pub struct SystemInfo {
pub sysname: String,
pub release: String,
pub version: String,
pub machine: String,
}
impl FromInner<uv_utsname_t> for SystemInfo {
fn from_inner(uname: uv_utsname_t) -> SystemInfo {
let sysname = unsafe { CStr::from_ptr(&uname.sysname as _) }
.to_string_lossy()
.into_owned();
let release = unsafe { CStr::from_ptr(&uname.release as _) }
.to_string_lossy()
.into_owned();
let version = unsafe { CStr::from_ptr(&uname.version as _) }
.to_string_lossy()
.into_owned();
let machine = unsafe { CStr::from_ptr(&uname.machine as _) }
.to_string_lossy()
.into_owned();
SystemInfo {
sysname,
release,
version,
machine,
}
}
}
pub fn get_passwd() -> crate::Result<User> {
let mut passwd: uv_passwd_t = unsafe { std::mem::zeroed() };
crate::uvret(unsafe { uv_os_get_passwd(&mut passwd as _) })?;
let result = passwd.into_inner();
unsafe { uv_os_free_passwd(&mut passwd as _) };
Ok(result)
}
pub fn gethostname() -> crate::Result<String> {
let mut size = UV_MAXHOSTNAMESIZE as usize;
let mut buf: Vec<std::os::raw::c_uchar> = Vec::with_capacity(size);
crate::uvret(unsafe { uv_os_gethostname(buf.as_mut_ptr() as _, &mut size as _) }).map(|_| {
unsafe { buf.set_len(size + 1) };
unsafe { CStr::from_bytes_with_nul_unchecked(&buf) }
.to_string_lossy()
.into_owned()
})
}
pub fn getpid() -> Pid {
unsafe { uv_os_getpid() as _ }
}
pub fn getppid() -> Pid {
unsafe { uv_os_getppid() as _ }
}
pub fn getpriority(pid: Pid) -> crate::Result<i32> {
let mut priority = 0i32;
crate::uvret(unsafe { uv_os_getpriority(pid as _, &mut priority as _) }).map(|_| priority)
}
pub fn setpriority(pid: Pid, priority: i32) -> crate::Result<()> {
crate::uvret(unsafe { uv_os_setpriority(pid as _, priority as _) })
}
pub fn uname() -> crate::Result<SystemInfo> {
let mut buf: uv_utsname_t = unsafe { std::mem::zeroed() };
crate::uvret(unsafe { uv_os_uname(&mut buf as _) })?;
Ok(buf.into_inner())
}