pub fn reset_sigpipe() {
unsafe {
libc::signal(libc::SIGPIPE, libc::SIG_DFL);
}
}
pub fn get_mode(metadata: &std::fs::Metadata) -> u32 {
use std::os::unix::fs::PermissionsExt;
metadata.permissions().mode()
}
pub fn needs_sudo() -> bool {
!is_root() && which::which("sudo").is_ok()
}
pub fn is_root() -> bool {
(unsafe { libc::geteuid() }) == 0
}
pub fn path_is_writable(path: &std::path::Path) -> bool {
use std::os::unix::ffi::OsStrExt;
let Ok(cpath) = std::ffi::CString::new(path.as_os_str().as_bytes()) else {
return false;
};
unsafe { libc::access(cpath.as_ptr(), libc::W_OK) == 0 }
}
pub fn set_env(key: &str, value: &std::ffi::OsStr) {
unsafe { std::env::set_var(key, value) }
}
pub fn symlink_file(original: &std::path::Path, link: &std::path::Path) -> std::io::Result<()> {
std::os::unix::fs::symlink(original, link)
}
pub fn set_permissions_mode(path: &std::path::Path, mode: u32) -> std::io::Result<()> {
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(path, std::fs::Permissions::from_mode(mode))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct FileStamp {
pub mtime_secs: i64,
pub mtime_nanos: i64,
pub ctime_secs: i64,
pub ctime_nanos: i64,
pub size: u64,
pub inode: u64,
}
impl FileStamp {
pub const fn changed_within(&self, now_secs: i64, window_secs: i64) -> bool {
let latest = if self.ctime_secs > self.mtime_secs {
self.ctime_secs
} else {
self.mtime_secs
};
now_secs - latest < window_secs
}
}
pub fn file_stamp(metadata: &std::fs::Metadata) -> FileStamp {
use std::os::unix::fs::MetadataExt;
FileStamp {
mtime_secs: metadata.mtime(),
mtime_nanos: metadata.mtime_nsec(),
ctime_secs: metadata.ctime(),
ctime_nanos: metadata.ctime_nsec(),
size: metadata.size(),
inode: metadata.ino(),
}
}
pub fn interrupt_signal() -> std::io::Result<tokio::signal::unix::Signal> {
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::interrupt())
}