use sc::syscall;
use crate::platform::{Fd, Mode, OpenFlags, AT_FDCWD};
use crate::string::unix_str::UnixStr;
#[inline]
pub unsafe fn open_raw(name_addr: usize, flags: OpenFlags) -> crate::Result<Fd> {
let res = syscall!(OPENAT, AT_FDCWD, name_addr, flags.bits().0);
Fd::coerce_from_register(res, "`OPENAT` syscall failed")
}
pub fn open(path: &UnixStr, flags: OpenFlags) -> crate::Result<Fd> {
let res = unsafe { syscall!(OPENAT, AT_FDCWD, path.as_ptr(), flags.bits().0) };
Fd::coerce_from_register(res, "`OPENAT` syscall failed")
}
#[inline]
pub fn open_mode(path: &UnixStr, flags: OpenFlags, mode: Mode) -> crate::Result<Fd> {
let res = unsafe { syscall!(OPENAT, AT_FDCWD, path.as_ptr(), flags.bits().0, mode.bits()) };
Fd::coerce_from_register(res, "`OPENAT` syscall failed")
}
pub fn open_at(dir: Fd, path: &UnixStr, flags: OpenFlags) -> crate::Result<Fd> {
let res = unsafe { syscall!(OPENAT, dir.0, path.as_ptr(), flags.bits().0) };
Fd::coerce_from_register(res, "`OPENAT` syscall failed")
}
pub fn open_at_mode(dir: Fd, path: &UnixStr, flags: OpenFlags, mode: Mode) -> crate::Result<Fd> {
let res = unsafe { syscall!(OPENAT, dir.0, path.as_ptr(), flags.bits().0, mode.bits()) };
Fd::coerce_from_register(res, "`OPENAT` syscall failed")
}
#[cfg(test)]
mod tests {
use crate::string::unix_str::UnixStr;
#[test]
fn try_open_temp() {
let path = UnixStr::try_from_str("test-files\0").unwrap();
try_open_temp_at_path(path).unwrap();
}
fn try_open_temp_at_path(path: &UnixStr) -> crate::Result<()> {
use super::*;
let _fd = open_mode(
path,
OpenFlags::O_WRONLY | OpenFlags::O_TMPFILE,
Mode::S_IRUSR | Mode::S_IWUSR,
)?;
let _fd = open_mode(
path,
OpenFlags::O_RDWR | OpenFlags::O_TMPFILE,
Mode::S_IRGRP | Mode::S_IWGRP,
)?;
Ok(())
}
}