mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-12 08:32:07 +00:00
Make FsPathBuf a trait and rename to FsPathBuilder
This commit is contained in:
@@ -358,11 +358,6 @@ impl Utf8CStr {
|
||||
self.0.as_ptr().cast()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_mut_ptr(&mut self) -> *mut c_char {
|
||||
self.0.as_mut_ptr().cast()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_cstr(&self) -> &CStr {
|
||||
// SAFETY: Already validated as null terminated during construction
|
||||
@@ -424,64 +419,6 @@ impl AsUtf8CStr for FsPathFollow {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FsPathBuf<'a, const N: usize>(pub Utf8CStrBuffer<'a, N>);
|
||||
|
||||
impl From<Utf8CString> for FsPathBuf<'static, 0> {
|
||||
fn from(value: Utf8CString) -> Self {
|
||||
FsPathBuf(From::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<Utf8CStrBufArr<N>> for FsPathBuf<'static, N> {
|
||||
fn from(value: Utf8CStrBufArr<N>) -> Self {
|
||||
FsPathBuf(From::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a mut dyn Utf8CStrBuf> for FsPathBuf<'a, 0> {
|
||||
fn from(value: &'a mut dyn Utf8CStrBuf) -> Self {
|
||||
FsPathBuf(From::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FsPathBuf<'static, 4096> {
|
||||
fn default() -> Self {
|
||||
FsPathBuf(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> FsPathBuf<'_, N> {
|
||||
pub fn clear(&mut self) {
|
||||
self.0.clear();
|
||||
}
|
||||
|
||||
pub fn join<T: AsRef<str>>(mut self, path: T) -> Self {
|
||||
fn inner(buf: &mut dyn Utf8CStrBuf, path: &str) {
|
||||
if path.starts_with('/') {
|
||||
buf.clear();
|
||||
}
|
||||
if !buf.is_empty() && !buf.ends_with('/') {
|
||||
buf.push_str("/");
|
||||
}
|
||||
buf.push_str(path);
|
||||
}
|
||||
inner(self.0.deref_mut(), path.as_ref());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn join_fmt<T: Display>(mut self, name: T) -> Self {
|
||||
self.0.write_fmt(format_args!("/{}", name)).ok();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> AsUtf8CStr for FsPathBuf<'_, N> {
|
||||
#[inline(always)]
|
||||
fn as_utf8_cstr(&self) -> &Utf8CStr {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
// impl<T: AsUtf8CStr> Deref<Target = Utf8CStr> for T { ... }
|
||||
macro_rules! impl_cstr_deref {
|
||||
($( ($t:ty, $($g:tt)*) )*) => {$(
|
||||
@@ -501,7 +438,6 @@ impl_cstr_deref!(
|
||||
(Utf8CStrBufArr<N>, const N: usize)
|
||||
(Utf8CString,)
|
||||
(FsPathFollow,)
|
||||
(FsPathBuf<'_, N>, const N: usize)
|
||||
);
|
||||
|
||||
// impl<T: Deref<Target = Utf8CStr>> BoilerPlate for T { ... }
|
||||
@@ -588,7 +524,6 @@ impl_cstr_misc!(
|
||||
(Utf8CStrBufArr<N>, const N: usize)
|
||||
(Utf8CString,)
|
||||
(FsPathFollow,)
|
||||
(FsPathBuf<'_, N>, const N: usize)
|
||||
);
|
||||
|
||||
fn copy_cstr_truncate(dest: &mut [u8], src: &[u8]) -> usize {
|
||||
@@ -688,7 +623,6 @@ impl_fs_path!(
|
||||
(Utf8CStrBufRef<'_>,)
|
||||
(Utf8CStrBufArr<N>, const N: usize)
|
||||
(Utf8CString,)
|
||||
(FsPathBuf<'_, N>, const N: usize)
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::cxx_extern::readlinkat;
|
||||
use crate::{
|
||||
FileAttr, FsPath, FsPathBuf, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr,
|
||||
FileAttr, FsPath, FsPathBuilder, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr,
|
||||
Utf8CStrBuf, cstr_buf, errno, fd_path, fd_set_attr,
|
||||
};
|
||||
use libc::{EEXIST, O_CLOEXEC, O_CREAT, O_RDONLY, O_TRUNC, O_WRONLY, dirent, mode_t};
|
||||
@@ -184,7 +184,7 @@ impl Directory {
|
||||
|
||||
fn path_at(&self, name: &Utf8CStr, buf: &mut dyn Utf8CStrBuf) -> OsResult<'static, ()> {
|
||||
self.path(buf)?;
|
||||
FsPathBuf::from(buf).join(name);
|
||||
buf.append_path(name);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -247,14 +247,14 @@ impl Directory {
|
||||
}
|
||||
|
||||
pub fn get_attr_at<'a>(&self, name: &'a Utf8CStr) -> OsResult<'a, FileAttr> {
|
||||
let mut path = FsPathBuf::default();
|
||||
self.path_at(name, path.0.deref_mut())?;
|
||||
let mut path = cstr_buf::default();
|
||||
self.path_at(name, &mut path)?;
|
||||
path.get_attr().map_err(|e| e.set_args(Some(name), None))
|
||||
}
|
||||
|
||||
pub fn set_attr_at<'a>(&self, name: &'a Utf8CStr, attr: &FileAttr) -> OsResult<'a, ()> {
|
||||
let mut path = FsPathBuf::default();
|
||||
self.path_at(name, path.0.deref_mut())?;
|
||||
let mut path = cstr_buf::default();
|
||||
self.path_at(name, &mut path)?;
|
||||
path.set_attr(attr)
|
||||
.map_err(|e| e.set_args(Some(name), None))
|
||||
}
|
||||
@@ -264,15 +264,15 @@ impl Directory {
|
||||
name: &'a Utf8CStr,
|
||||
con: &mut dyn Utf8CStrBuf,
|
||||
) -> OsResult<'a, ()> {
|
||||
let mut path = FsPathBuf::default();
|
||||
self.path_at(name, path.0.deref_mut())?;
|
||||
let mut path = cstr_buf::default();
|
||||
self.path_at(name, &mut path)?;
|
||||
path.get_secontext(con)
|
||||
.map_err(|e| e.set_args(Some(name), None))
|
||||
}
|
||||
|
||||
pub fn set_secontext_at<'a>(&self, name: &'a Utf8CStr, con: &'a Utf8CStr) -> OsResult<'a, ()> {
|
||||
let mut path = FsPathBuf::default();
|
||||
self.path_at(name, path.0.deref_mut())?;
|
||||
let mut path = cstr_buf::default();
|
||||
self.path_at(name, &mut path)?;
|
||||
path.set_secontext(con)
|
||||
.map_err(|e| e.set_args(Some(name), Some(con)))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
Directory, FsPathBuf, FsPathFollow, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr,
|
||||
Utf8CStrBuf, cstr_buf, errno, error,
|
||||
Directory, FsPathFollow, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr, Utf8CStrBuf,
|
||||
cstr_buf, errno, error,
|
||||
};
|
||||
use bytemuck::{Pod, bytes_of, bytes_of_mut};
|
||||
use libc::{
|
||||
@@ -11,6 +11,7 @@ use mem::MaybeUninit;
|
||||
use num_traits::AsPrimitive;
|
||||
use std::cmp::min;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt::Display;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write};
|
||||
use std::ops::Deref;
|
||||
@@ -138,7 +139,9 @@ macro_rules! open_fd {
|
||||
}
|
||||
|
||||
pub fn fd_path(fd: RawFd, buf: &mut dyn Utf8CStrBuf) -> OsResult<'static, ()> {
|
||||
let path = FsPathBuf::default().join("/proc/self/fd").join_fmt(fd);
|
||||
let path = cstr_buf::default()
|
||||
.join_path("/proc/self/fd")
|
||||
.join_path_fmt(fd);
|
||||
path.read_link(buf).map_err(|e| e.set_args(None, None))
|
||||
}
|
||||
|
||||
@@ -267,13 +270,13 @@ pub trait FsPath: Deref<Target = Utf8CStr> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut path = FsPathBuf::default();
|
||||
let mut path = cstr_buf::default();
|
||||
let mut components = self.split('/').filter(|s| !s.is_empty());
|
||||
loop {
|
||||
let Some(s) = components.next() else {
|
||||
break;
|
||||
};
|
||||
path = path.join(s);
|
||||
path.append_path(s);
|
||||
|
||||
unsafe {
|
||||
if libc::mkdir(path.as_ptr(), mode) < 0 && *errno() != EEXIST {
|
||||
@@ -548,6 +551,59 @@ impl FsPath for FsPathFollow {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FsPathBuilder {
|
||||
fn join_path<T: AsRef<str>>(mut self, path: T) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.append_path(path);
|
||||
self
|
||||
}
|
||||
fn join_path_fmt<T: Display>(mut self, name: T) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.append_path_fmt(name);
|
||||
self
|
||||
}
|
||||
fn append_path<T: AsRef<str>>(&mut self, path: T) -> &mut Self;
|
||||
fn append_path_fmt<T: Display>(&mut self, name: T) -> &mut Self;
|
||||
}
|
||||
|
||||
fn append_path_impl(buf: &mut dyn Utf8CStrBuf, path: &str) {
|
||||
if path.starts_with('/') {
|
||||
buf.clear();
|
||||
}
|
||||
if !buf.is_empty() && !buf.ends_with('/') {
|
||||
buf.push_str("/");
|
||||
}
|
||||
buf.push_str(path);
|
||||
}
|
||||
|
||||
impl<S: Utf8CStrBuf + Sized> FsPathBuilder for S {
|
||||
fn append_path<T: AsRef<str>>(&mut self, path: T) -> &mut Self {
|
||||
append_path_impl(self, path.as_ref());
|
||||
self
|
||||
}
|
||||
|
||||
fn append_path_fmt<T: Display>(&mut self, name: T) -> &mut Self {
|
||||
self.write_fmt(format_args!("/{}", name)).ok();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl FsPathBuilder for dyn Utf8CStrBuf + '_ {
|
||||
fn append_path<T: AsRef<str>>(&mut self, path: T) -> &mut Self {
|
||||
append_path_impl(self, path.as_ref());
|
||||
self
|
||||
}
|
||||
|
||||
fn append_path_fmt<T: Display>(&mut self, name: T) -> &mut Self {
|
||||
self.write_fmt(format_args!("/{}", name)).ok();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fd_get_attr(fd: RawFd) -> OsResult<'static, FileAttr> {
|
||||
let mut attr = FileAttr::new();
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user