]>
git.proxmox.com Git - rustc.git/blob - vendor/sysinfo/src/freebsd/utils.rs
1 // Take a look at the license at the top of the repository in the LICENSE file.
3 use crate::{Pid, Process}
;
4 use libc
::{c_char, c_int, timeval}
;
5 use std
::cell
::UnsafeCell
;
6 use std
::collections
::HashMap
;
9 use std
::time
::SystemTime
;
11 /// This struct is used to switch between the "old" and "new" every time you use "get_mut".
13 pub(crate) struct VecSwitcher
<T
> {
19 impl<T
: Clone
> VecSwitcher
<T
> {
20 pub fn new(v1
: Vec
<T
>) -> Self {
30 pub fn get_mut(&mut self) -> &mut [T
] {
31 self.first
= !self.first
;
33 // It means that `v2` will be the "new".
36 // It means that `v1` will be the "new".
41 pub fn get_old(&self) -> &[T
] {
49 pub fn get_new(&self) -> &[T
] {
59 pub unsafe fn init_mib(name
: &[u8], mib
: &mut [c_int
]) {
60 let mut len
= mib
.len();
61 libc
::sysctlnametomib(name
.as_ptr() as _
, mib
.as_mut_ptr(), &mut len
);
64 pub(crate) fn boot_time() -> u64 {
65 let mut boot_time
= timeval
{
69 let mut len
= std
::mem
::size_of
::<timeval
>();
70 let mut mib
: [c_int
; 2] = [libc
::CTL_KERN
, libc
::KERN_BOOTTIME
];
75 &mut boot_time
as *mut timeval
as *mut _
,
88 pub(crate) unsafe fn get_sys_value
<T
: Sized
>(mib
: &[c_int
], value
: &mut T
) -> bool
{
89 let mut len
= mem
::size_of
::<T
>() as libc
::size_t
;
93 value
as *mut _
as *mut _
,
100 pub(crate) unsafe fn get_sys_value_array
<T
: Sized
>(mib
: &[c_int
], value
: &mut [T
]) -> bool
{
101 let mut len
= (mem
::size_of
::<T
>() * value
.len()) as libc
::size_t
;
105 value
.as_mut_ptr() as *mut _
,
107 std
::ptr
::null_mut(),
112 pub(crate) fn c_buf_to_str(buf
: &[libc
::c_char
]) -> Option
<&str> {
114 let buf
: &[u8] = std
::slice
::from_raw_parts(buf
.as_ptr() as _
, buf
.len());
115 if let Some(pos
) = buf
.iter().position(|x
| *x
== 0) {
116 // Shrink buffer to terminate the null bytes
117 std
::str::from_utf8(&buf
[..pos
]).ok()
119 std
::str::from_utf8(buf
).ok()
124 pub(crate) fn c_buf_to_string(buf
: &[libc
::c_char
]) -> Option
<String
> {
125 c_buf_to_str(buf
).map(|s
| s
.to_owned())
128 pub(crate) unsafe fn get_sys_value_str(mib
: &[c_int
], buf
: &mut [libc
::c_char
]) -> Option
<String
> {
129 let mut len
= (mem
::size_of
::<libc
::c_char
>() * buf
.len()) as libc
::size_t
;
133 buf
.as_mut_ptr() as *mut _
,
135 std
::ptr
::null_mut(),
141 c_buf_to_string(&buf
[..len
/ mem
::size_of
::<libc
::c_char
>()])
144 pub(crate) unsafe fn get_sys_value_by_name
<T
: Sized
>(name
: &[u8], value
: &mut T
) -> bool
{
145 let mut len
= mem
::size_of
::<T
>() as libc
::size_t
;
149 name
.as_ptr() as *const c_char
,
150 value
as *mut _
as *mut _
,
152 std
::ptr
::null_mut(),
158 pub(crate) fn get_sys_value_str_by_name(name
: &[u8]) -> Option
<String
> {
162 if libc
::sysctlbyname(
163 name
.as_ptr() as *const c_char
,
164 std
::ptr
::null_mut(),
166 std
::ptr
::null_mut(),
171 // now create a buffer with the size and get the real value
172 let mut buf
: Vec
<libc
::c_char
> = vec
![0; size
as _
];
174 if libc
::sysctlbyname(
175 name
.as_ptr() as *const c_char
,
176 buf
.as_mut_ptr() as *mut _
,
178 std
::ptr
::null_mut(),
183 c_buf_to_string(&buf
)
185 // getting the system value failed
194 pub(crate) fn get_system_info(mib
: &[c_int
], default: Option
<&str>) -> Option
<String
> {
198 // Call first to get size
202 std
::ptr
::null_mut(),
204 std
::ptr
::null_mut(),
208 // exit early if we did not update the size
210 default.map(|s
| s
.to_owned())
212 // set the buffer to the correct size
213 let mut buf
: Vec
<libc
::c_char
> = vec
![0; size
as _
];
218 buf
.as_mut_ptr() as _
,
220 std
::ptr
::null_mut(),
224 // If command fails return default
225 default.map(|s
| s
.to_owned())
227 c_buf_to_string(&buf
)
233 pub(crate) unsafe fn from_cstr_array(ptr
: *const *const c_char
) -> Vec
<String
> {
239 let ptr
= ptr
.add(max
);
240 if (*ptr
).is_null() {
248 let mut ret
= Vec
::with_capacity(max
);
251 let p
= ptr
.add(pos
);
252 if let Ok(s
) = CStr
::from_ptr(*p
).to_str() {
253 ret
.push(s
.to_owned());
259 pub(crate) fn get_now() -> u64 {
261 .duration_since(SystemTime
::UNIX_EPOCH
)
262 .map(|n
| n
.as_secs())
266 // All this is needed because `kinfo_proc` doesn't implement `Send` (because it contains pointers).
267 pub(crate) struct WrapMap
<'a
>(pub UnsafeCell
<&'a
mut HashMap
<Pid
, Process
>>);
269 unsafe impl<'a
> Send
for WrapMap
<'a
> {}
270 unsafe impl<'a
> Sync
for WrapMap
<'a
> {}
273 pub(crate) struct KInfoProc(libc
::kinfo_proc
);
274 unsafe impl Send
for KInfoProc {}
275 unsafe impl Sync
for KInfoProc {}
277 impl std
::ops
::Deref
for KInfoProc
{
278 type Target
= libc
::kinfo_proc
;
280 fn deref(&self) -> &Self::Target
{
285 pub(crate) unsafe fn get_frequency_for_cpu(cpu_nb
: c_int
) -> u64 {
286 let mut frequency
= 0;
288 // The information can be missing if it's running inside a VM.
289 if !get_sys_value_by_name(
290 format
!("dev.cpu.{cpu_nb}.freq\0").as_bytes(),