mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-27 08:00:48 +00:00
Introduce BorrowedDirectory
This commit is contained in:
parent
30e79310ab
commit
55b036c071
@ -6,13 +6,14 @@ use crate::{
|
|||||||
use libc::{EEXIST, O_CLOEXEC, O_CREAT, O_RDONLY, O_TRUNC, O_WRONLY, dirent, mode_t};
|
use libc::{EEXIST, O_CLOEXEC, O_CREAT, O_RDONLY, O_TRUNC, O_WRONLY, dirent, mode_t};
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::ops::Deref;
|
use std::marker::PhantomData;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::{mem, slice};
|
use std::{mem, slice};
|
||||||
|
|
||||||
pub struct DirEntry<'a> {
|
pub struct DirEntry<'a> {
|
||||||
dir: &'a Directory,
|
dir: BorrowedDirectory<'a>,
|
||||||
entry: NonNull<dirent>,
|
entry: NonNull<dirent>,
|
||||||
d_name_len: usize,
|
d_name_len: usize,
|
||||||
}
|
}
|
||||||
@ -168,6 +169,30 @@ pub struct Directory {
|
|||||||
inner: NonNull<libc::DIR>,
|
inner: NonNull<libc::DIR>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct BorrowedDirectory<'a> {
|
||||||
|
inner: NonNull<libc::DIR>,
|
||||||
|
phantom: PhantomData<&'a Directory>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for BorrowedDirectory<'_> {
|
||||||
|
type Target = Directory;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Directory {
|
||||||
|
// SAFETY: layout of NonNull<libc::DIR> is the same as Directory
|
||||||
|
// SAFETY: the lifetime of the raw pointer is tracked in the PhantomData
|
||||||
|
unsafe { mem::transmute(&self.inner) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for BorrowedDirectory<'_> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Directory {
|
||||||
|
// SAFETY: layout of NonNull<libc::DIR> is the same as Directory
|
||||||
|
// SAFETY: the lifetime of the raw pointer is tracked in the PhantomData
|
||||||
|
unsafe { mem::transmute(&mut self.inner) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum WalkResult {
|
pub enum WalkResult {
|
||||||
Continue,
|
Continue,
|
||||||
Abort,
|
Abort,
|
||||||
@ -175,6 +200,13 @@ pub enum WalkResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Directory {
|
impl Directory {
|
||||||
|
fn borrow(&self) -> BorrowedDirectory {
|
||||||
|
BorrowedDirectory {
|
||||||
|
inner: self.inner,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn open(path: &Utf8CStr) -> OsResult<Directory> {
|
pub fn open(path: &Utf8CStr) -> OsResult<Directory> {
|
||||||
let dirp = unsafe { libc::opendir(path.as_ptr()) };
|
let dirp = unsafe { libc::opendir(path.as_ptr()) };
|
||||||
let dirp = dirp.as_os_result("opendir", Some(path), None)?;
|
let dirp = dirp.as_os_result("opendir", Some(path), None)?;
|
||||||
@ -199,7 +231,7 @@ impl Directory {
|
|||||||
self.read()
|
self.read()
|
||||||
} else {
|
} else {
|
||||||
let e = DirEntry {
|
let e = DirEntry {
|
||||||
dir: self,
|
dir: self.borrow(),
|
||||||
entry: NonNull::from(entry),
|
entry: NonNull::from(entry),
|
||||||
d_name_len: d_name.to_bytes_with_nul().len(),
|
d_name_len: d_name.to_bytes_with_nul().len(),
|
||||||
};
|
};
|
||||||
@ -304,7 +336,7 @@ impl Directory {
|
|||||||
.check_os_err("symlinkat", Some(&target), e.utf8_name())?;
|
.check_os_err("symlinkat", Some(&target), e.utf8_name())?;
|
||||||
}
|
}
|
||||||
let new_entry = DirEntry {
|
let new_entry = DirEntry {
|
||||||
dir,
|
dir: dir.borrow(),
|
||||||
entry: e.entry,
|
entry: e.entry,
|
||||||
d_name_len: e.d_name_len,
|
d_name_len: e.d_name_len,
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::cxx_extern::readlinkat;
|
use crate::cxx_extern::readlinkat;
|
||||||
use crate::{
|
use crate::{
|
||||||
CxxResultExt, Directory, FsPath, LibcReturn, Utf8CStr, cstr_buf, slice_from_ptr,
|
BorrowedDirectory, CxxResultExt, FsPath, LibcReturn, Utf8CStr, cstr_buf, slice_from_ptr,
|
||||||
slice_from_ptr_mut,
|
slice_from_ptr_mut,
|
||||||
};
|
};
|
||||||
use libc::{
|
use libc::{
|
||||||
@ -190,7 +190,7 @@ extern "C" fn xfdopendir(fd: RawFd) -> *mut libc::DIR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xreaddir(mut dir: ManuallyDrop<Directory>) -> *mut libc::dirent {
|
unsafe extern "C" fn xreaddir(mut dir: BorrowedDirectory) -> *mut libc::dirent {
|
||||||
dir.read()
|
dir.read()
|
||||||
.log_cxx()
|
.log_cxx()
|
||||||
.ok()
|
.ok()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user