diff options
Diffstat (limited to 'vendor/sysinfo/src/c_interface.rs')
-rw-r--r-- | vendor/sysinfo/src/c_interface.rs | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/vendor/sysinfo/src/c_interface.rs b/vendor/sysinfo/src/c_interface.rs new file mode 100644 index 000000000..e7cc5359b --- /dev/null +++ b/vendor/sysinfo/src/c_interface.rs @@ -0,0 +1,468 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{CpuExt, NetworkExt, NetworksExt, Pid, Process, ProcessExt, System, SystemExt}; +use libc::{self, c_char, c_float, c_uint, c_void, pid_t, size_t}; +use std::borrow::BorrowMut; +use std::ffi::CString; + +/// Equivalent of [`System`][crate::System] struct. +pub type CSystem = *mut c_void; +/// Equivalent of [`Process`][crate::Process] struct. +pub type CProcess = *const c_void; +/// C string returned from `CString::into_raw`. +pub type RString = *const c_char; +/// Callback used by [`processes`][crate::System#method.processes]. +pub type ProcessLoop = extern "C" fn(pid: pid_t, process: CProcess, data: *mut c_void) -> bool; + +/// Equivalent of [`System::new()`][crate::System#method.new]. +#[no_mangle] +pub extern "C" fn sysinfo_init() -> CSystem { + let system = Box::new(System::new()); + Box::into_raw(system) as CSystem +} + +/// Equivalent of `System::drop()`. Important in C to cleanup memory. +#[no_mangle] +pub extern "C" fn sysinfo_destroy(system: CSystem) { + assert!(!system.is_null()); + unsafe { + Box::from_raw(system as *mut System); + } +} + +/// Equivalent of [`System::refresh_system()`][crate::System#method.refresh_system]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_system(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_system(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_memory()`][crate::System#method.refresh_memory]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_memory(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_memory(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_cpu()`][crate::System#method.refresh_cpu]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_cpu(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_cpu(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_components()`][crate::System#method.refresh_temperatures]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_components(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_components(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_all()`][crate::System#method.refresh_all]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_all(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_all(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_processes()`][crate::System#method.refresh_processes]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_processes(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_processes(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_process()`][crate::System#method.refresh_process]. +#[cfg(target_os = "linux")] +#[no_mangle] +pub extern "C" fn sysinfo_refresh_process(system: CSystem, pid: pid_t) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_process(Pid(pid)); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_disks()`][crate::System#method.refresh_disks]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_disks(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_disks(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::refresh_disks_list()`][crate::System#method.refresh_disks_list]. +#[no_mangle] +pub extern "C" fn sysinfo_refresh_disks_list(system: CSystem) { + assert!(!system.is_null()); + unsafe { + let mut system: Box<System> = Box::from_raw(system as *mut System); + { + let system: &mut System = system.borrow_mut(); + system.refresh_disks_list(); + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::total_memory()`][crate::System#method.total_memory]. +#[no_mangle] +pub extern "C" fn sysinfo_total_memory(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.total_memory() as size_t; + Box::into_raw(system); + ret + } +} + +/// Equivalent of [`System::free_memory()`][crate::System#method.free_memory]. +#[no_mangle] +pub extern "C" fn sysinfo_free_memory(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.free_memory() as size_t; + Box::into_raw(system); + ret + } +} + +/// Equivalent of [`System::used_memory()`][crate::System#method.used_memory]. +#[no_mangle] +pub extern "C" fn sysinfo_used_memory(system: CSystem) -> size_t { + assert!(!system.is_null()); + let system: Box<System> = unsafe { Box::from_raw(system as *mut System) }; + let ret = system.used_memory() as size_t; + Box::into_raw(system); + ret +} + +/// Equivalent of [`System::total_swap()`][crate::System#method.total_swap]. +#[no_mangle] +pub extern "C" fn sysinfo_total_swap(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.total_swap() as size_t; + Box::into_raw(system); + ret + } +} + +/// Equivalent of [`System::free_swap()`][crate::System#method.free_swap]. +#[no_mangle] +pub extern "C" fn sysinfo_free_swap(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.free_swap() as size_t; + Box::into_raw(system); + ret + } +} + +/// Equivalent of [`System::used_swap()`][crate::System#method.used_swap]. +#[no_mangle] +pub extern "C" fn sysinfo_used_swap(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.used_swap() as size_t; + Box::into_raw(system); + ret + } +} + +/// Equivalent of +/// `system::networks().iter().fold(0, |acc, (_, data)| acc + data.received() as size_t)`. +#[no_mangle] +pub extern "C" fn sysinfo_networks_received(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.networks().iter().fold(0, |acc: size_t, (_, data)| { + acc.saturating_add(data.received() as size_t) + }); + Box::into_raw(system); + ret + } +} + +/// Equivalent of +/// `system::networks().iter().fold(0, |acc, (_, data)| acc + data.transmitted() as size_t)`. +#[no_mangle] +pub extern "C" fn sysinfo_networks_transmitted(system: CSystem) -> size_t { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = system.networks().iter().fold(0, |acc: size_t, (_, data)| { + acc.saturating_add(data.transmitted() as size_t) + }); + Box::into_raw(system); + ret + } +} + +/// Equivalent of [`System::cpus_usage()`][crate::System#method.cpus_usage]. +/// +/// * `length` will contain the number of cpu usage added into `procs`. +/// * `procs` will be allocated if it's null and will contain of cpu usage. +#[no_mangle] +pub extern "C" fn sysinfo_cpus_usage( + system: CSystem, + length: *mut c_uint, + procs: *mut *mut c_float, +) { + assert!(!system.is_null()); + if procs.is_null() || length.is_null() { + return; + } + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + { + let cpus = system.cpus(); + if (*procs).is_null() { + (*procs) = + libc::malloc(::std::mem::size_of::<c_float>() * cpus.len()) as *mut c_float; + } + for (pos, cpu) in cpus.iter().skip(1).enumerate() { + (*(*procs).offset(pos as isize)) = cpu.cpu_usage(); + } + *length = cpus.len() as c_uint - 1; + } + Box::into_raw(system); + } +} + +/// Equivalent of [`System::processes()`][crate::System#method.processes]. Returns an +/// array ended by a null pointer. Must be freed. +/// +/// # /!\ WARNING /!\ +/// +/// While having this method returned processes, you should *never* call any refresh method! +#[no_mangle] +pub extern "C" fn sysinfo_processes( + system: CSystem, + fn_pointer: Option<ProcessLoop>, + data: *mut c_void, +) -> size_t { + assert!(!system.is_null()); + if let Some(fn_pointer) = fn_pointer { + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let len = { + let entries = system.processes(); + for (pid, process) in entries { + if !fn_pointer(pid.0, process as *const Process as CProcess, data) { + break; + } + } + entries.len() as size_t + }; + Box::into_raw(system); + len + } + } else { + 0 + } +} + +/// Equivalent of [`System::process()`][crate::System#method.process]. +/// +/// # /!\ WARNING /!\ +/// +/// While having this method returned process, you should *never* call any +/// refresh method! +#[no_mangle] +pub extern "C" fn sysinfo_process_by_pid(system: CSystem, pid: pid_t) -> CProcess { + assert!(!system.is_null()); + unsafe { + let system: Box<System> = Box::from_raw(system as *mut System); + let ret = if let Some(process) = system.process(Pid(pid)) { + process as *const Process as CProcess + } else { + std::ptr::null() + }; + Box::into_raw(system); + ret + } +} + +/// Equivalent of iterating over [`Process::tasks()`][crate::Process#method.tasks]. +/// +/// # /!\ WARNING /!\ +/// +/// While having this method processes, you should *never* call any refresh method! +#[cfg(target_os = "linux")] +#[no_mangle] +pub extern "C" fn sysinfo_process_tasks( + process: CProcess, + fn_pointer: Option<ProcessLoop>, + data: *mut c_void, +) -> size_t { + assert!(!process.is_null()); + if let Some(fn_pointer) = fn_pointer { + unsafe { + let process = process as *const Process; + for (pid, process) in (*process).tasks.iter() { + if !fn_pointer(pid.0, process as *const Process as CProcess, data) { + break; + } + } + (*process).tasks.len() as size_t + } + } else { + 0 + } +} + +/// Equivalent of [`Process::pid()`][crate::Process#method.pid]. +#[no_mangle] +pub extern "C" fn sysinfo_process_pid(process: CProcess) -> pid_t { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { (*process).pid().0 } +} + +/// Equivalent of [`Process::parent()`][crate::Process#method.parent]. +/// +/// In case there is no known parent, it returns `0`. +#[no_mangle] +pub extern "C" fn sysinfo_process_parent_pid(process: CProcess) -> pid_t { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { (*process).parent().unwrap_or(Pid(0)).0 } +} + +/// Equivalent of [`Process::cpu_usage()`][crate::Process#method.cpu_usage]. +#[no_mangle] +pub extern "C" fn sysinfo_process_cpu_usage(process: CProcess) -> c_float { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { (*process).cpu_usage() } +} + +/// Equivalent of [`Process::memory()`][crate::Process#method.memory]. +#[no_mangle] +pub extern "C" fn sysinfo_process_memory(process: CProcess) -> size_t { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { (*process).memory() as usize } +} + +/// Equivalent of [`Process::virtual_memory()`][crate::Process#method.virtual_memory]. +#[no_mangle] +pub extern "C" fn sysinfo_process_virtual_memory(process: CProcess) -> size_t { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { (*process).virtual_memory() as usize } +} + +/// Equivalent of [`Process::exe()`][crate::Process#method.exe]. +#[no_mangle] +pub extern "C" fn sysinfo_process_executable_path(process: CProcess) -> RString { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { + if let Some(p) = (*process).exe().to_str() { + if let Ok(c) = CString::new(p) { + return c.into_raw() as _; + } + } + std::ptr::null() + } +} + +/// Equivalent of [`Process::root()`][crate::Process#method.root]. +#[no_mangle] +pub extern "C" fn sysinfo_process_root_directory(process: CProcess) -> RString { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { + if let Some(p) = (*process).root().to_str() { + if let Ok(c) = CString::new(p) { + return c.into_raw() as _; + } + } + std::ptr::null() + } +} + +/// Equivalent of [`Process::cwd()`][crate::Process#method.cwd]. +#[no_mangle] +pub extern "C" fn sysinfo_process_current_directory(process: CProcess) -> RString { + assert!(!process.is_null()); + let process = process as *const Process; + unsafe { + if let Some(p) = (*process).cwd().to_str() { + if let Ok(c) = CString::new(p) { + return c.into_raw() as _; + } + } + std::ptr::null() + } +} + +/// Frees a C string created with `CString::into_raw()`. +#[no_mangle] +pub extern "C" fn sysinfo_rstring_free(s: RString) { + if !s.is_null() { + unsafe { + let _ = CString::from_raw(s as usize as *mut i8); + } + } +} |