143 lines
3.2 KiB
Rust
143 lines
3.2 KiB
Rust
#![warn(clippy::all, clippy::pedantic)]
|
|
#![allow(clippy::missing_errors_doc)]
|
|
use errno::Errno;
|
|
use libc::utsname;
|
|
use sc::syscall;
|
|
use std::{error::Error, ffi::CString, fs::File, os::fd::AsRawFd, ptr, u8};
|
|
|
|
fn new_utsname() -> utsname {
|
|
utsname {
|
|
sysname: [0; 65],
|
|
nodename: [0; 65],
|
|
release: [0; 65],
|
|
version: [0; 65],
|
|
machine: [0; 65],
|
|
domainname: [0; 65],
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::cast_sign_loss)]
|
|
pub fn gethostname() -> Result<String, Box<dyn Error>> {
|
|
let mut uts = new_utsname();
|
|
unsafe {
|
|
let ret = syscall!(UNAME, ptr::addr_of_mut!(uts));
|
|
if ret != 0 {
|
|
return Err(Errno::from(ret).into());
|
|
}
|
|
}
|
|
let name = uts
|
|
.nodename
|
|
.iter()
|
|
.map(|x| *x as u8)
|
|
.take_while(|x| *x != 0)
|
|
.collect();
|
|
String::from_utf8(name).map_err(Into::into)
|
|
}
|
|
|
|
pub fn sethostname(name: &str) -> Result<(), Errno> {
|
|
let ret = unsafe { syscall!(SETHOSTNAME, name.as_ptr(), name.len()) };
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(ret.into())
|
|
}
|
|
}
|
|
|
|
pub fn link(source: &str, dest: &str) -> Result<(), Box<dyn Error>> {
|
|
let ret = unsafe {
|
|
syscall!(
|
|
LINKAT,
|
|
libc::AT_FDCWD,
|
|
CString::new(source)?.as_ptr(),
|
|
libc::AT_FDCWD,
|
|
CString::new(dest)?.as_ptr(),
|
|
0
|
|
)
|
|
};
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(Errno::from(ret).into())
|
|
}
|
|
}
|
|
|
|
pub fn unlink(name: &str) -> Result<(), Box<dyn Error>> {
|
|
let ret = unsafe { syscall!(UNLINKAT, libc::AT_FDCWD, CString::new(name)?.as_ptr(), 0) };
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(Errno::from(ret).into())
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::cast_sign_loss)]
|
|
pub fn readlink(name: &str) -> Result<String, Box<dyn Error>> {
|
|
let mut buf = Vec::<i8>::with_capacity(1024);
|
|
let ret = unsafe {
|
|
syscall!(
|
|
READLINKAT,
|
|
libc::AT_FDCWD,
|
|
CString::new(name)?.as_ptr(),
|
|
buf.as_mut_ptr(),
|
|
1024
|
|
)
|
|
};
|
|
if ret == 0 {
|
|
let path = buf
|
|
.iter()
|
|
.map(|x| *x as u8)
|
|
.take_while(|x| *x != 0)
|
|
.collect();
|
|
String::from_utf8(path).map_err(Into::into)
|
|
} else {
|
|
Err(Errno::from(ret).into())
|
|
}
|
|
}
|
|
|
|
pub fn fdatasync(fd: &File) -> Result<(), Errno> {
|
|
let ret = unsafe { syscall!(FDATASYNC, fd.as_raw_fd()) };
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(ret.into())
|
|
}
|
|
}
|
|
|
|
pub fn syncfs(fd: &File) -> Result<(), Errno> {
|
|
let ret = unsafe { syscall!(SYNCFS, fd.as_raw_fd()) };
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(ret.into())
|
|
}
|
|
}
|
|
|
|
pub fn fsync(fd: &File) -> Result<(), Errno> {
|
|
let ret = unsafe { syscall!(FSYNC, fd.as_raw_fd()) };
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(ret.into())
|
|
}
|
|
}
|
|
|
|
pub fn sync() {
|
|
unsafe { syscall!(SYNC) };
|
|
}
|
|
|
|
pub fn symlink(source: &str, dest: &str) -> Result<(), Box<dyn Error>> {
|
|
let ret = unsafe {
|
|
syscall!(
|
|
SYMLINKAT,
|
|
CString::new(source)?.as_ptr(),
|
|
libc::AT_FDCWD,
|
|
CString::new(dest)?.as_ptr()
|
|
)
|
|
};
|
|
if ret == 0 {
|
|
Ok(())
|
|
} else {
|
|
Err(Errno::from(ret).into())
|
|
}
|
|
}
|