Skip to main content

tuwunel_core/utils/
sys.rs

1pub mod compute;
2pub mod limits;
3pub mod storage;
4pub mod usage;
5
6use std::path::PathBuf;
7
8pub use self::{
9	compute::available_parallelism,
10	limits::*,
11	usage::{statm, thread_usage, usage},
12};
13use crate::{Result, at};
14
15/// Return a possibly corrected std::env::current_exe() even if the path is
16/// marked deleted.
17pub fn current_exe() -> Result<PathBuf> {
18	let exe = std::env::current_exe()?;
19	match exe.to_str() {
20		| None => Ok(exe),
21		| Some(str) => Ok(str
22			.strip_suffix(" (deleted)")
23			.map(PathBuf::from)
24			.unwrap_or(exe)),
25	}
26}
27
28/// Determine if the server's executable was removed or replaced. This is a
29/// specific check; useful for successful restarts. May not be available or
30/// accurate on all platforms; defaults to false.
31#[must_use]
32pub fn current_exe_deleted() -> bool {
33	std::env::current_exe().is_ok_and(|exe| {
34		exe.to_str()
35			.is_some_and(|exe| exe.ends_with(" (deleted)"))
36	})
37}
38
39/// Parse the `KEY=VALUE` contents of a `uevent` file searching for `key` and
40/// returning the `value`.
41#[inline]
42#[must_use]
43pub fn uevent_find<'a>(uevent: &'a str, key: &'a str) -> Option<&'a str> {
44	uevent
45		.lines()
46		.filter_map(|line| line.split_once('='))
47		.find(|&(key_, _)| key.eq(key_))
48		.map(at!(1))
49}
50
51#[cfg(unix)]
52pub enum SocketFamily {
53	Inet,
54	Unix,
55}
56
57#[cfg(unix)]
58pub fn get_socket_family(fd: i32) -> Result<SocketFamily> {
59	use nix::sys::socket::{AddressFamily, SockaddrLike, SockaddrStorage};
60
61	use crate::{Err, err};
62
63	let sockname: SockaddrStorage = nix::sys::socket::getsockname(fd)?;
64
65	let family = sockname
66		.family()
67		.ok_or_else(|| err!("Invalid socket"))?;
68
69	match family {
70		| AddressFamily::Inet | AddressFamily::Inet6 => Ok(SocketFamily::Inet),
71		| AddressFamily::Unix => Ok(SocketFamily::Unix),
72		| _ => Err!("Unknown socket family: {family:?}"),
73	}
74}