mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-13 22:32:13 +00:00
Move more I/O operations into Rust
This commit is contained in:
@@ -3,12 +3,15 @@
|
||||
use std::io;
|
||||
use std::os::fd::{BorrowedFd, OwnedFd, RawFd};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use cxx::private::c_char;
|
||||
use libc::mode_t;
|
||||
|
||||
use crate::logging::CxxResultExt;
|
||||
pub(crate) use crate::xwrap::*;
|
||||
use crate::{fd_path, map_fd, map_file, Directory, FsPath, Utf8CStr, Utf8CStrSlice};
|
||||
use crate::{
|
||||
clone_attr, fclone_attr, fd_path, map_fd, map_file, Directory, FsPath, Utf8CStr, Utf8CStrSlice,
|
||||
};
|
||||
|
||||
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||
let mut buf = Utf8CStrSlice::from(buf);
|
||||
@@ -69,3 +72,102 @@ pub(crate) fn map_fd_for_cxx(fd: RawFd, sz: usize, rw: bool) -> &'static mut [u8
|
||||
.unwrap_or(&mut [])
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn readlinkat_for_cxx(
|
||||
dirfd: RawFd,
|
||||
path: *const c_char,
|
||||
buf: *mut u8,
|
||||
bufsz: usize,
|
||||
) -> isize {
|
||||
// readlinkat() may fail on x86 platform, returning random value
|
||||
// instead of number of bytes placed in buf (length of link)
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
|
||||
libc::memset(buf.cast(), 0, bufsz);
|
||||
let mut r = libc::readlinkat(dirfd, path, buf.cast(), bufsz - 1);
|
||||
if r > 0 {
|
||||
r = libc::strlen(buf.cast()) as isize;
|
||||
}
|
||||
} else {
|
||||
let r = libc::readlinkat(dirfd, path, buf.cast(), bufsz - 1);
|
||||
if r >= 0 {
|
||||
*buf.offset(r) = b'\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
#[export_name = "cp_afc"]
|
||||
unsafe extern "C" fn cp_afc_for_cxx(src: *const c_char, dest: *const c_char) -> bool {
|
||||
if let Ok(src) = Utf8CStr::from_ptr(src) {
|
||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||
let src = FsPath::from(src);
|
||||
let dest = FsPath::from(dest);
|
||||
return src
|
||||
.copy_to(dest)
|
||||
.log_cxx_with_msg(|w| {
|
||||
w.write_fmt(format_args!("cp_afc {} -> {} failed", src, dest))
|
||||
})
|
||||
.is_ok();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[export_name = "mv_path"]
|
||||
unsafe extern "C" fn mv_path_for_cxx(src: *const c_char, dest: *const c_char) -> bool {
|
||||
if let Ok(src) = Utf8CStr::from_ptr(src) {
|
||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||
let src = FsPath::from(src);
|
||||
let dest = FsPath::from(dest);
|
||||
return src
|
||||
.move_to(dest)
|
||||
.log_cxx_with_msg(|w| {
|
||||
w.write_fmt(format_args!("mv_path {} -> {} failed", src, dest))
|
||||
})
|
||||
.is_ok();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[export_name = "link_path"]
|
||||
unsafe extern "C" fn link_path_for_cxx(src: *const c_char, dest: *const c_char) -> bool {
|
||||
if let Ok(src) = Utf8CStr::from_ptr(src) {
|
||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||
let src = FsPath::from(src);
|
||||
let dest = FsPath::from(dest);
|
||||
return src
|
||||
.link_to(dest)
|
||||
.log_cxx_with_msg(|w| {
|
||||
w.write_fmt(format_args!("link_path {} -> {} failed", src, dest))
|
||||
})
|
||||
.is_ok();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[export_name = "clone_attr"]
|
||||
unsafe extern "C" fn clone_attr_for_cxx(src: *const c_char, dest: *const c_char) -> bool {
|
||||
if let Ok(src) = Utf8CStr::from_ptr(src) {
|
||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||
let src = FsPath::from(src);
|
||||
let dest = FsPath::from(dest);
|
||||
return clone_attr(src, dest)
|
||||
.log_cxx_with_msg(|w| {
|
||||
w.write_fmt(format_args!("clone_attr {} -> {} failed", src, dest))
|
||||
})
|
||||
.is_ok();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[export_name = "fclone_attr"]
|
||||
unsafe extern "C" fn fclone_attr_for_cxx(a: RawFd, b: RawFd) -> bool {
|
||||
fclone_attr(a, b)
|
||||
.log_cxx_with_msg(|w| w.write_str("fclone_attr failed"))
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user