Update FsPathBuf

This commit is contained in:
topjohnwu 2025-02-15 14:07:51 -08:00 committed by John Wu
parent 584f3820fe
commit dcf027884d
8 changed files with 82 additions and 70 deletions

View File

@ -449,15 +449,57 @@ impl DerefMut for FsPath {
}
}
pub struct FsPathBuf<'a>(&'a mut dyn Utf8CStrBuf);
enum Utf8CStrBufOwned<const N: usize> {
Dynamic(Utf8CString),
Fixed(Utf8CStrBufArr<N>),
}
impl<'a> FsPathBuf<'a> {
pub fn new(value: &'a mut dyn Utf8CStrBuf) -> Self {
value.clear();
FsPathBuf(value)
impl<const N: usize> Deref for Utf8CStrBufOwned<N> {
type Target = dyn Utf8CStrBuf;
fn deref(&self) -> &Self::Target {
match self {
Utf8CStrBufOwned::Dynamic(s) => s,
Utf8CStrBufOwned::Fixed(arr) => arr,
}
}
}
impl<const N: usize> DerefMut for Utf8CStrBufOwned<N> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Utf8CStrBufOwned::Dynamic(s) => s,
Utf8CStrBufOwned::Fixed(arr) => arr,
}
}
}
pub struct FsPathBuf<const N: usize>(Utf8CStrBufOwned<N>);
impl FsPathBuf<0> {
pub fn new_dynamic(capacity: usize) -> Self {
FsPathBuf(Utf8CStrBufOwned::Dynamic(Utf8CString::with_capacity(
capacity,
)))
}
}
impl Default for FsPathBuf<4096> {
fn default() -> Self {
FsPathBuf(Utf8CStrBufOwned::Fixed(Utf8CStrBufArr::default()))
}
}
impl<const N: usize> FsPathBuf<N> {
pub fn new() -> Self {
FsPathBuf(Utf8CStrBufOwned::Fixed(Utf8CStrBufArr::<N>::new()))
}
pub fn join<T: AsRef<str>>(self, path: T) -> Self {
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();
@ -466,30 +508,30 @@ impl<'a> FsPathBuf<'a> {
}
buf.push_str(path);
}
inner(self.0, path.as_ref());
inner(self.0.deref_mut(), path.as_ref());
self
}
pub fn join_fmt<T: Display>(self, name: T) -> Self {
pub fn join_fmt<T: Display>(mut self, name: T) -> Self {
fn inner(buf: &mut dyn Utf8CStrBuf, path: Arguments) {
buf.write_fmt(path).ok();
}
inner(self.0, format_args!("/{}", name));
inner(self.0.deref_mut(), format_args!("/{}", name));
self
}
}
impl Deref for FsPathBuf<'_> {
impl<const N: usize> Deref for FsPathBuf<N> {
type Target = FsPath;
fn deref(&self) -> &FsPath {
FsPath::from(&self.0)
FsPath::from(self.0.deref())
}
}
impl DerefMut for FsPathBuf<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
FsPath::from_mut(&mut self.0)
impl<const N: usize> DerefMut for FsPathBuf<N> {
fn deref_mut(&mut self) -> &mut FsPath {
FsPath::from_mut(self.0.deref_mut())
}
}
@ -575,7 +617,7 @@ macro_rules! impl_str {
impl_str!(
(Utf8CStr,)
(FsPath,)
(FsPathBuf<'_>,)
(FsPathBuf<N>, const N: usize)
(Utf8CStrBufRef<'_>,)
(Utf8CStrBufArr<N>, const N: usize)
(Utf8CString,)

View File

@ -38,8 +38,7 @@ macro_rules! open_fd {
}
pub fn fd_path(fd: RawFd, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> {
let mut arr = Utf8CStrBufArr::<40>::new();
let path = FsPathBuf::new(&mut arr).join("/proc/self/fd").join_fmt(fd);
let path = FsPathBuf::default().join("/proc/self/fd").join_fmt(fd);
path.read_link(buf)
}

View File

@ -11,8 +11,7 @@ use crate::package::ManagerInfo;
use crate::su::SuInfo;
use base::libc::{O_CLOEXEC, O_RDONLY};
use base::{
cstr, error, info, libc, open_fd, AtomicArc, BufReadExt, FsPath, FsPathBuf, ResultExt,
Utf8CStr, Utf8CStrBufArr,
cstr, error, info, libc, open_fd, AtomicArc, BufReadExt, FsPath, FsPathBuf, ResultExt, Utf8CStr,
};
use std::fs::File;
use std::io::BufReader;
@ -229,8 +228,7 @@ pub fn daemon_entry() {
|| get_prop(cstr!("ro.product.device"), false).contains("vsoc");
// Load config status
let mut buf = Utf8CStrBufArr::<64>::new();
let path = FsPathBuf::new(&mut buf)
let path = FsPathBuf::<64>::new()
.join(get_magisk_tmp())
.join(MAIN_CONFIG);
let mut is_recovery = false;

View File

@ -180,10 +180,7 @@ pub fn zygisk_get_logd() -> i32 {
let mut fd = ZYGISK_LOGD.load(Ordering::Relaxed);
if fd < 0 {
android_logging();
let mut buf = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut buf)
.join(get_magisk_tmp())
.join(LOG_PIPE);
let path = FsPathBuf::default().join(get_magisk_tmp()).join(LOG_PIPE);
// Open as RW as sometimes it may block
fd = unsafe { libc::open(path.as_ptr(), O_RDWR | O_CLOEXEC) };
if fd >= 0 {
@ -358,10 +355,7 @@ pub fn setup_logfile() {
}
pub fn start_log_daemon() {
let mut buf = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut buf)
.join(get_magisk_tmp())
.join(LOG_PIPE);
let path = FsPathBuf::default().join(get_magisk_tmp()).join(LOG_PIPE);
unsafe {
libc::mkfifo(path.as_ptr(), 0o666);

View File

@ -20,13 +20,9 @@ pub fn setup_mounts() {
info!("* Setup internal mounts");
let magisk_tmp = get_magisk_tmp();
let mut buf = Utf8CStrBufArr::default();
// Mount preinit directory
let mut dev_buf = Utf8CStrBufArr::<64>::new();
let dev_path = FsPathBuf::new(&mut dev_buf)
.join(magisk_tmp)
.join(PREINITDEV);
let dev_path = FsPathBuf::<64>::new().join(magisk_tmp).join(PREINITDEV);
let mut linked = false;
if let Ok(attr) = dev_path.get_attr() {
if attr.st.st_mode & libc::S_IFMT as c_uint == libc::S_IFBLK.as_() {
@ -36,7 +32,7 @@ pub fn setup_mounts() {
// What we do instead is to scan through the current mountinfo and find a pre-existing
// mount point mounting our desired partition, and then bind mount the target folder.
let preinit_dev = attr.st.st_rdev;
let mnt_path = FsPathBuf::new(&mut buf).join(magisk_tmp).join(PREINITMIRR);
let mnt_path = FsPathBuf::default().join(magisk_tmp).join(PREINITMIRR);
for info in parse_mount_info("self") {
if info.root == "/" && info.device == preinit_dev {
if !info.fs_option.split(',').any(|s| s == "rw") {
@ -74,7 +70,7 @@ pub fn setup_mounts() {
}
// Bind remount module root to clear nosuid
let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT);
let module_mnt = FsPathBuf::default().join(magisk_tmp).join(MODULEMNT);
let _: LoggedResult<()> = try {
module_mnt.mkdir(0o755)?;
unsafe {
@ -101,16 +97,15 @@ pub fn setup_mounts() {
pub fn clean_mounts() {
let magisk_tmp = get_magisk_tmp();
let mut buf = Utf8CStrBufArr::default();
let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT);
let mut module_mnt = FsPathBuf::default().join(magisk_tmp).join(MODULEMNT);
let _: LoggedResult<()> = try {
unsafe {
libc::umount2(module_mnt.as_ptr(), libc::MNT_DETACH).as_os_err()?;
}
};
let worker_dir = FsPathBuf::new(&mut buf).join(magisk_tmp).join(WORKERDIR);
module_mnt.clear();
let worker_dir = module_mnt.join(magisk_tmp).join(WORKERDIR);
let _: LoggedResult<()> = try {
unsafe {
libc::mount(
@ -218,8 +213,7 @@ pub fn find_preinit_device() -> String {
&& let Ok(tmp) = std::env::var("MAGISKTMP")
&& !tmp.is_empty()
{
let mut buf = Utf8CStrBufArr::default();
let mirror_dir = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITMIRR);
let mut mirror_dir = FsPathBuf::default().join(&tmp).join(PREINITMIRR);
let preinit_dir = FsPath::from(Utf8CStr::from_string(&mut preinit_dir));
let _: LoggedResult<()> = try {
preinit_dir.mkdirs(0o700)?;
@ -236,7 +230,8 @@ pub fn find_preinit_device() -> String {
}
};
if std::env::var_os("MAKEDEV").is_some() {
let dev_path = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITDEV);
mirror_dir.clear();
let dev_path = mirror_dir.join(&tmp).join(PREINITDEV);
unsafe {
libc::mknod(
dev_path.as_ptr(),

View File

@ -239,8 +239,7 @@ impl TrackedFile {
impl ManagerInfo {
fn check_dyn(&mut self, daemon: &MagiskD, user: i32, pkg: &str) -> Status {
let mut arr = Utf8CStrBufArr::default();
let apk = FsPathBuf::new(&mut arr)
let apk = FsPathBuf::default()
.join(daemon.app_data_dir())
.join_fmt(user)
.join(pkg)
@ -444,8 +443,7 @@ impl ManagerInfo {
impl MagiskD {
fn get_package_uid(&self, user: i32, pkg: &str) -> i32 {
let mut arr = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut arr)
let path = FsPathBuf::default()
.join(self.app_data_dir())
.join_fmt(user)
.join(pkg);
@ -457,10 +455,7 @@ impl MagiskD {
pub fn preserve_stub_apk(&self) {
let mut info = self.manager_info.lock().unwrap();
let mut arr = Utf8CStrBufArr::default();
let apk = FsPathBuf::new(&mut arr)
.join(get_magisk_tmp())
.join("stub.apk");
let apk = FsPathBuf::default().join(get_magisk_tmp()).join("stub.apk");
if let Ok(mut fd) = apk.open(O_RDONLY | O_CLOEXEC) {
info.trusted_cert = read_certificate(&mut fd, MAGISK_VER_CODE);

View File

@ -12,7 +12,7 @@ use quick_protobuf::{BytesReader, MessageRead, MessageWrite, Writer};
use base::libc::{O_CLOEXEC, O_RDONLY};
use base::{
clone_attr, cstr, debug, libc::mkstemp, Directory, FsPath, FsPathBuf, LibcReturn, LoggedResult,
MappedFile, SilentResultExt, Utf8CStr, Utf8CStrBufArr, WalkResult,
MappedFile, SilentResultExt, Utf8CStr, WalkResult,
};
use crate::ffi::{prop_cb_exec, PropCb};
@ -77,10 +77,7 @@ fn check_proto() -> bool {
}
fn file_get_prop(name: &Utf8CStr) -> LoggedResult<String> {
let mut buf = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut buf)
.join(PERSIST_PROP_DIR!())
.join(name);
let path = FsPathBuf::default().join(PERSIST_PROP_DIR!()).join(name);
let mut file = path.open(O_RDONLY | O_CLOEXEC).silent()?;
debug!("resetprop: read prop from [{}]", path);
let mut s = String::new();
@ -89,13 +86,9 @@ fn file_get_prop(name: &Utf8CStr) -> LoggedResult<String> {
}
fn file_set_prop(name: &Utf8CStr, value: Option<&Utf8CStr>) -> LoggedResult<()> {
let mut buf = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut buf)
.join(PERSIST_PROP_DIR!())
.join(name);
let path = FsPathBuf::default().join(PERSIST_PROP_DIR!()).join(name);
if let Some(value) = value {
let mut buf = Utf8CStrBufArr::default();
let mut tmp = FsPathBuf::new(&mut buf)
let mut tmp = FsPathBuf::default()
.join(PERSIST_PROP_DIR!())
.join("prop.XXXXXX");
{
@ -126,8 +119,7 @@ fn proto_read_props() -> LoggedResult<PersistentProperties> {
}
fn proto_write_props(props: &PersistentProperties) -> LoggedResult<()> {
let mut buf = Utf8CStrBufArr::default();
let mut tmp = FsPathBuf::new(&mut buf).join(concat!(PERSIST_PROP!(), ".XXXXXX"));
let mut tmp = FsPathBuf::default().join(concat!(PERSIST_PROP!(), ".XXXXXX"));
{
let f = unsafe {
let fd = mkstemp(tmp.as_mut_ptr()).check_os_err()?;

View File

@ -30,7 +30,6 @@ fn exec_zygiskd(is_64_bit: bool, remote: UnixStream) {
}
// Start building the exec arguments
let mut exe = Utf8CStrBufArr::<64>::new();
#[cfg(target_pointer_width = "64")]
let magisk = if is_64_bit { "magisk" } else { "magisk32" };
@ -38,7 +37,7 @@ fn exec_zygiskd(is_64_bit: bool, remote: UnixStream) {
#[cfg(target_pointer_width = "32")]
let magisk = "magisk";
let exe = FsPathBuf::new(&mut exe).join(get_magisk_tmp()).join(magisk);
let exe = FsPathBuf::<64>::new().join(get_magisk_tmp()).join(magisk);
let mut fd_str = Utf8CStrBufArr::<16>::new();
write!(fd_str, "{}", remote.as_raw_fd()).ok();
@ -184,8 +183,7 @@ impl MagiskD {
let failed_ids: Vec<i32> = client.read_decodable()?;
if let Some(module_list) = self.module_list.get() {
for id in failed_ids {
let mut buf = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut buf)
let path = FsPathBuf::default()
.join(MODULEROOT)
.join(&module_list[id as usize].name)
.join("zygisk");
@ -204,8 +202,7 @@ impl MagiskD {
fn get_mod_dir(&self, mut client: UnixStream) -> LoggedResult<()> {
let id: i32 = client.read_decodable()?;
let module = &self.module_list.get().unwrap()[id as usize];
let mut buf = Utf8CStrBufArr::default();
let dir = FsPathBuf::new(&mut buf).join(MODULEROOT).join(&module.name);
let dir = FsPathBuf::default().join(MODULEROOT).join(&module.name);
let fd = open_fd!(&dir, O_RDONLY | O_CLOEXEC)?;
client.send_fds(&[fd.as_raw_fd()])?;
Ok(())