diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index bd114c8d0..6729768f0 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -20,12 +20,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "anyhow" -version = "1.0.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" - [[package]] name = "argh" version = "0.1.10" @@ -75,7 +69,6 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" name = "base" version = "0.0.0" dependencies = [ - "anyhow", "cfg-if", "cxx", "cxx-gen", @@ -222,7 +215,6 @@ dependencies = [ name = "magiskboot" version = "0.0.0" dependencies = [ - "anyhow", "argh", "base", "byteorder", @@ -247,7 +239,6 @@ dependencies = [ name = "magiskpolicy" version = "0.0.0" dependencies = [ - "anyhow", "base", "cxx", "cxx-gen", diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index fc89a0929..7050529e6 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -8,7 +8,6 @@ cxx = { path = "external/cxx-rs" } cxx-gen = { path = "external/cxx-rs/gen/lib" } libc = "0.2" cfg-if = "1.0" -anyhow = "1.0" num-traits = "0.2" num-derive = "0.3" thiserror = "1.0" diff --git a/native/src/base/Cargo.toml b/native/src/base/Cargo.toml index 26a05c956..371b53329 100644 --- a/native/src/base/Cargo.toml +++ b/native/src/base/Cargo.toml @@ -14,4 +14,3 @@ cxx = { workspace = true } libc = { workspace = true } cfg-if = { workspace = true } thiserror = { workspace = true } -anyhow = { workspace = true } \ No newline at end of file diff --git a/native/src/base/cxx_extern.rs b/native/src/base/cxx_extern.rs index b84fa28d9..2f845e45a 100644 --- a/native/src/base/cxx_extern.rs +++ b/native/src/base/cxx_extern.rs @@ -1,9 +1,9 @@ // Functions listed here are just to export to C++ +use std::fmt::Write; use std::io; use std::os::fd::{BorrowedFd, OwnedFd, RawFd}; -use anyhow::Context; use cxx::private::c_char; use libc::mode_t; @@ -14,8 +14,7 @@ use crate::{ pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize { fd_path(fd, buf) - .context("fd_path failed") - .log() + .log_cxx_with_msg(|w| w.write_str("fd_path failed")) .map_or(-1_isize, |v| v as isize) } @@ -54,7 +53,7 @@ unsafe extern "C" fn frm_rf(fd: OwnedFd) -> bool { pub(crate) fn map_file_for_cxx(path: &[u8], rw: bool) -> &'static mut [u8] { unsafe { map_file(Utf8CStr::from_bytes_unchecked(path), rw) - .log() + .log_cxx() .unwrap_or(&mut []) } } @@ -62,7 +61,7 @@ pub(crate) fn map_file_for_cxx(path: &[u8], rw: bool) -> &'static mut [u8] { pub(crate) fn map_fd_for_cxx(fd: RawFd, sz: usize, rw: bool) -> &'static mut [u8] { unsafe { map_fd(BorrowedFd::borrow_raw(fd), sz, rw) - .log() + .log_cxx() .unwrap_or(&mut []) } } diff --git a/native/src/base/lib.rs b/native/src/base/lib.rs index 5d2dbc9ce..d2de004ea 100644 --- a/native/src/base/lib.rs +++ b/native/src/base/lib.rs @@ -20,6 +20,7 @@ mod xwrap; pub mod ffi { #[derive(Copy, Clone)] pub enum LogLevel { + ErrorCxx, Error, Warn, Info, @@ -32,6 +33,7 @@ pub mod ffi { } extern "Rust" { + #[rust_name = "log_from_cxx"] fn log_with_rs(level: LogLevel, msg: &[u8]); fn exit_on_error(b: bool); fn set_log_level_state(level: LogLevel, enabled: bool); diff --git a/native/src/base/logging.cpp b/native/src/base/logging.cpp index fa031d0ed..41b165442 100644 --- a/native/src/base/logging.cpp +++ b/native/src/base/logging.cpp @@ -33,7 +33,7 @@ extern "C" int magisk_log_print(int prio, const char *tag, const char *fmt, ...) level = LogLevel::Warn; break; case ANDROID_LOG_ERROR: - level = LogLevel::Error; + level = LogLevel::ErrorCxx; break; default: return 0; @@ -70,9 +70,9 @@ void LOGD(const char *fmt, ...) {} #endif void LOGI(const char *fmt, ...) { LOG_BODY(Info) } void LOGW(const char *fmt, ...) { LOG_BODY(Warn) } -void LOGE(const char *fmt, ...) { LOG_BODY(Error) } +void LOGE(const char *fmt, ...) { LOG_BODY(ErrorCxx) } // Export raw symbol to fortify compat extern "C" void __vloge(const char* fmt, va_list ap) { - fmt_and_log_with_rs(LogLevel::Error, fmt, ap); + fmt_and_log_with_rs(LogLevel::ErrorCxx, fmt, ap); } diff --git a/native/src/base/logging.rs b/native/src/base/logging.rs index 913f7e787..16df41b31 100644 --- a/native/src/base/logging.rs +++ b/native/src/base/logging.rs @@ -1,9 +1,23 @@ -use std::fmt::{Arguments, Display}; +use std::fmt; +use std::fmt::{Arguments, Display, Write as fWrite}; use std::io::{stderr, stdout, Write}; use std::process::exit; use crate::ffi::LogLevel; -use crate::fmt_to_buf; +use crate::BufFormatter; + +// Error handling and logging throughout the Rust codebase in Magisk: +// +// All errors should be logged and consumed as soon as possible and converted into LoggedError. +// Implement `From for LoggedError` for non-standard error types so that we can +// directly use the `?` operator to propagate LoggedResult. +// +// To log an error with more information, use `ResultExt::log_with_msg()`. +// +// The "cxx" method variants in `ResultExt` are only used for C++ interop and +// should not be used directly in any Rust code. +// +// For general logging, use the !(...) macros. // Ugly hack to avoid using enum #[allow(non_snake_case, non_upper_case_globals)] @@ -41,7 +55,7 @@ pub fn exit_on_error(b: bool) { impl LogLevel { fn as_disable_flag(&self) -> u32 { match *self { - LogLevel::Error => LogFlag::DisableError, + LogLevel::Error | LogLevel::ErrorCxx => LogFlag::DisableError, LogLevel::Warn => LogFlag::DisableWarn, LogLevel::Info => LogFlag::DisableInfo, LogLevel::Debug => LogFlag::DisableDebug, @@ -61,28 +75,32 @@ pub fn set_log_level_state(level: LogLevel, enabled: bool) { } } -pub fn log_with_rs(level: LogLevel, msg: &[u8]) { +fn do_log(level: LogLevel, f: F) { let logger = unsafe { LOGGER }; if (logger.flags & level.as_disable_flag()) != 0 { return; } - (logger.write)(level, msg); - if level == LogLevel::Error && (logger.flags & LogFlag::ExitOnError) != 0 { + f(logger.write); + if level == LogLevel::ErrorCxx && (logger.flags & LogFlag::ExitOnError) != 0 { exit(1); } } -pub fn log_impl(level: LogLevel, args: Arguments) { - let logger = unsafe { LOGGER }; - if (logger.flags & level.as_disable_flag()) != 0 { - return; - } - let mut buf: [u8; 4096] = [0; 4096]; - let len = fmt_to_buf(&mut buf, args); - (logger.write)(level, &buf[..len]); - if level == LogLevel::Error && (logger.flags & LogFlag::ExitOnError) != 0 { - exit(1); - } +pub fn log_from_cxx(level: LogLevel, msg: &[u8]) { + do_log(level, |write| write(level, msg)); +} + +pub fn log_with_formatter fmt::Result>(level: LogLevel, f: F) { + do_log(level, |write| { + let mut buf = [0_u8; 4096]; + let mut w = BufFormatter::new(&mut buf); + let len = if f(&mut w).is_ok() { w.used } else { 0 }; + write(level, &buf[..len]); + }); +} + +pub fn log_with_args(level: LogLevel, args: Arguments) { + log_with_formatter(level, |w| w.write_fmt(args)); } pub fn cmdline_logging() { @@ -103,44 +121,33 @@ pub fn cmdline_logging() { } } -#[macro_export] -macro_rules! perror { - ($fmt:expr) => { - $crate::log_impl($crate::ffi::LogLevel::Error, format_args_nl!( - concat!($fmt, " failed with {}: {}"), - $crate::errno(), - $crate::error_str() - )) - }; - ($fmt:expr, $($args:tt)*) => { - $crate::log_impl($crate::ffi::LogLevel::Error, format_args_nl!( - concat!($fmt, " failed with {}: {}"), - $($args)*, - $crate::errno(), - $crate::error_str() - )) - }; -} - #[macro_export] macro_rules! error { - ($($args:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Error, format_args_nl!($($args)+))) + ($($args:tt)+) => { + $crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!($($args)+)) + } } #[macro_export] macro_rules! warn { - ($($args:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Warn, format_args_nl!($($args)+))) + ($($args:tt)+) => { + $crate::log_with_args($crate::ffi::LogLevel::Warn, format_args_nl!($($args)+)) + } } #[macro_export] macro_rules! info { - ($($args:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Info, format_args_nl!($($args)+))) + ($($args:tt)+) => { + $crate::log_with_args($crate::ffi::LogLevel::Info, format_args_nl!($($args)+)) + } } #[cfg(debug_assertions)] #[macro_export] macro_rules! debug { - ($($args:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Debug, format_args_nl!($($args)+))) + ($($args:tt)+) => { + $crate::log_with_args($crate::ffi::LogLevel::Debug, format_args_nl!($($args)+)) + } } #[cfg(not(debug_assertions))] @@ -149,15 +156,111 @@ macro_rules! debug { ($($args:tt)+) => {}; } -pub trait ResultExt { - fn log(self) -> Self; -} +#[derive(Default)] +pub struct LoggedError {} -impl ResultExt for Result { - fn log(self) -> Self { - if let Err(e) = &self { - error!("{:#}", e); - } - self +// Automatically handle all printable errors +impl From for LoggedError { + fn from(e: T) -> Self { + log_with_args(LogLevel::Error, format_args_nl!("{:#}", e)); + LoggedError::default() + } +} + +pub type LoggedResult = Result; + +#[macro_export] +macro_rules! log_err { + ($msg:literal $(,)?) => {{ + $crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!($msg)); + $crate::LoggedError::default() + }}; + ($err:expr $(,)?) => {{ + $crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!("{}", $err)); + $crate::LoggedError::default() + }}; + ($($args:tt)+) => {{ + $crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!($($args)+)); + $crate::LoggedError::default() + }}; +} + +pub trait ResultExt +where + Self: Sized, +{ + fn log(self) -> LoggedResult { + self.log_impl(LogLevel::Error) + } + fn log_cxx(self) -> LoggedResult { + self.log_impl(LogLevel::ErrorCxx) + } + fn log_with_msg fmt::Result>(self, f: F) -> LoggedResult { + self.log_with_msg_impl(LogLevel::Error, f) + } + fn log_cxx_with_msg fmt::Result>( + self, + f: F, + ) -> LoggedResult { + self.log_with_msg_impl(LogLevel::ErrorCxx, f) + } + + fn log_impl(self, level: LogLevel) -> LoggedResult; + fn log_with_msg_impl fmt::Result>( + self, + level: LogLevel, + f: F, + ) -> LoggedResult; +} + +impl ResultExt for LoggedResult { + fn log_impl(self, _: LogLevel) -> LoggedResult { + self + } + + fn log_with_msg_impl fmt::Result>( + self, + level: LogLevel, + f: F, + ) -> LoggedResult { + match self { + Ok(v) => Ok(v), + Err(_) => { + log_with_formatter(level, |w| { + f(w)?; + w.write_char('\n') + }); + Err(LoggedError::default()) + } + } + } +} + +impl ResultExt for Result { + fn log_impl(self, level: LogLevel) -> LoggedResult { + match self { + Ok(v) => Ok(v), + Err(e) => { + log_with_args(level, format_args_nl!("{:#}", e)); + Err(LoggedError::default()) + } + } + } + + fn log_with_msg_impl fmt::Result>( + self, + level: LogLevel, + f: F, + ) -> LoggedResult { + match self { + Ok(v) => Ok(v), + Err(e) => { + log_with_formatter(level, |w| { + f(w)?; + writeln!(w, ": {:#}", e) + }); + Err(LoggedError::default()) + } + } } } diff --git a/native/src/base/misc.rs b/native/src/base/misc.rs index 064347f89..d0cc45359 100644 --- a/native/src/base/misc.rs +++ b/native/src/base/misc.rs @@ -26,18 +26,18 @@ pub fn copy_cstr + ?Sized>(dest: &mut [u8], src: &T) -> usize { len - 1 } -struct BufFmtWriter<'a> { +pub struct BufFormatter<'a> { buf: &'a mut [u8], - used: usize, + pub used: usize, } -impl<'a> BufFmtWriter<'a> { - fn new(buf: &'a mut [u8]) -> Self { - BufFmtWriter { buf, used: 0 } +impl<'a> BufFormatter<'a> { + pub fn new(buf: &'a mut [u8]) -> Self { + BufFormatter { buf, used: 0 } } } -impl<'a> fmt::Write for BufFmtWriter<'a> { +impl<'a> fmt::Write for BufFormatter<'a> { // The buffer should always be null terminated fn write_str(&mut self, s: &str) -> fmt::Result { if self.used >= self.buf.len() - 1 { @@ -51,7 +51,7 @@ impl<'a> fmt::Write for BufFmtWriter<'a> { } pub fn fmt_to_buf(buf: &mut [u8], args: Arguments) -> usize { - let mut w = BufFmtWriter::new(buf); + let mut w = BufFormatter::new(buf); if let Ok(()) = fmt::write(&mut w, args) { w.used } else { diff --git a/native/src/base/xwrap.rs b/native/src/base/xwrap.rs index 31b012360..7cf30bee1 100644 --- a/native/src/base/xwrap.rs +++ b/native/src/base/xwrap.rs @@ -1,24 +1,45 @@ +use std::fmt::Write; use std::os::unix::io::RawFd; use std::ptr; -use anyhow::Context; use libc::{ c_char, c_uint, c_ulong, c_void, dev_t, mode_t, nfds_t, off_t, pollfd, sockaddr, socklen_t, ssize_t, SYS_dup3, }; -use crate::{cstr, errno, error, mkdirs, perror, ptr_to_str, raw_cstr, ResultExt, Utf8CStr}; +use crate::{cstr, errno, mkdirs, ptr_to_str, raw_cstr, ResultExt, Utf8CStr}; + +macro_rules! error_cxx { + ($($args:tt)+) => { + ($crate::log_with_args($crate::ffi::LogLevel::ErrorCxx, format_args_nl!($($args)+))) + } +} + +macro_rules! perror { + ($fmt:expr) => { + $crate::log_with_formatter($crate::ffi::LogLevel::ErrorCxx, |w| { + w.write_str($fmt)?; + w.write_fmt(format_args!(" failed with {}: {}", $crate::errno(), $crate::error_str())) + }) + }; + ($fmt:expr, $($args:tt)*) => { + $crate::log_with_formatter($crate::ffi::LogLevel::ErrorCxx, |w| { + w.write_fmt(format_args!($fmt, $($args)*))?; + w.write_fmt(format_args!(" failed with {}: {}", $crate::errno(), $crate::error_str())) + }) + }; +} mod unsafe_impl { + use std::fmt::Write; use std::os::unix::io::RawFd; - use anyhow::Context; use cfg_if::cfg_if; use libc::{c_char, nfds_t, off_t, pollfd}; use crate::{ - perror, ptr_to_str, readlink_unsafe, realpath, slice_from_ptr, slice_from_ptr_mut, - ResultExt, Utf8CStr, + ptr_to_str, readlink_unsafe, realpath, slice_from_ptr, slice_from_ptr_mut, ResultExt, + Utf8CStr, }; #[no_mangle] @@ -40,8 +61,7 @@ mod unsafe_impl { unsafe extern "C" fn xrealpath(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { match Utf8CStr::from_ptr(path) { Ok(p) => realpath(p, slice_from_ptr_mut(buf, bufsz)) - .with_context(|| format!("realpath {} failed", p)) - .log() + .log_cxx_with_msg(|w| w.write_fmt(format_args!("realpath {} failed", p))) .map_or(-1, |v| v as isize), Err(_) => -1, } @@ -172,7 +192,7 @@ pub fn xwrite(fd: RawFd, data: &[u8]) -> isize { } } if !remain.is_empty() { - error!("write ({} != {})", write_sz, data.len()) + error_cxx!("write ({} != {})", write_sz, data.len()) } write_sz as isize } @@ -211,7 +231,7 @@ pub fn xxread(fd: RawFd, data: &mut [u8]) -> isize { } } if !remain.is_empty() { - error!("read ({} != {})", read_sz, data.len()) + error_cxx!("read ({} != {})", read_sz, data.len()) } read_sz as isize } @@ -572,8 +592,7 @@ pub unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 { pub unsafe extern "C" fn xmkdirs(path: *const c_char, mode: mode_t) -> i32 { match Utf8CStr::from_ptr(path) { Ok(p) => mkdirs(p, mode) - .with_context(|| format!("mkdirs {} failed", p)) - .log() + .log_cxx_with_msg(|w| w.write_fmt(format_args!("mkdirs {} failed", p))) .map_or(-1, |_| 0), Err(_) => -1, } diff --git a/native/src/boot/Cargo.toml b/native/src/boot/Cargo.toml index 5024b25a4..32ca8e0ce 100644 --- a/native/src/boot/Cargo.toml +++ b/native/src/boot/Cargo.toml @@ -15,7 +15,6 @@ pb-rs = { workspace = true } base = { path = "../base" } cxx = { path = "../external/cxx-rs" } byteorder = { workspace = true } -anyhow = { workspace = true } size = { workspace = true } quick-protobuf = { workspace = true } argh = { workspace = true } diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index 1ea98804f..bf0819c7a 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; use std::ffi::CStr; -use std::fmt::{Display, Formatter}; +use std::fmt::{Display, Formatter, Write as FmtWrite}; use std::fs::{metadata, read, DirBuilder, File}; use std::io::Write; use std::mem::size_of; @@ -9,16 +9,15 @@ use std::path::Path; use std::process::exit; use std::slice; -use anyhow::{anyhow, Context}; +use argh::{EarlyExit, FromArgs}; use size::{Base, Size, Style}; -use argh::{EarlyExit, FromArgs}; use base::libc::{ c_char, dev_t, gid_t, major, makedev, minor, mknod, mode_t, uid_t, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR, }; -use base::{MappedFile, ResultExt, StrErr, Utf8CStr, WriteExt}; +use base::{log_err, LoggedResult, MappedFile, ResultExt, StrErr, Utf8CStr, WriteExt}; use crate::ramdisk::MagiskCpio; @@ -217,13 +216,13 @@ impl Cpio { } } - fn load_from_data(data: &[u8]) -> anyhow::Result { + fn load_from_data(data: &[u8]) -> LoggedResult { let mut cpio = Cpio::new(); let mut pos = 0usize; while pos < data.len() { let hdr = unsafe { &*(data.as_ptr().add(pos) as *const CpioHeader) }; if &hdr.magic != b"070701" { - return Err(anyhow!("invalid cpio magic")); + return Err(log_err!("invalid cpio magic")); } pos += size_of::(); let name = CStr::from_bytes_until_nul(&data[pos..])? @@ -257,13 +256,13 @@ impl Cpio { Ok(cpio) } - pub(crate) fn load_from_file(path: &Utf8CStr) -> anyhow::Result { + pub(crate) fn load_from_file(path: &Utf8CStr) -> LoggedResult { eprintln!("Loading cpio: [{}]", path); let file = MappedFile::open(path)?; Self::load_from_data(file.as_ref()) } - fn dump(&self, path: &str) -> anyhow::Result<()> { + fn dump(&self, path: &str) -> LoggedResult<()> { eprintln!("Dumping cpio: [{}]", path); let mut file = File::create(path)?; let mut pos = 0usize; @@ -324,8 +323,8 @@ impl Cpio { } } - fn extract_entry(&self, path: &str, out: &Path) -> anyhow::Result<()> { - let entry = self.entries.get(path).ok_or(anyhow!("No such file"))?; + fn extract_entry(&self, path: &str, out: &Path) -> LoggedResult<()> { + let entry = self.entries.get(path).ok_or(log_err!("No such file"))?; eprintln!("Extracting entry [{}] to [{}]", path, out.to_string_lossy()); if let Some(parent) = out.parent() { DirBuilder::new() @@ -358,13 +357,13 @@ impl Cpio { }; } _ => { - return Err(anyhow!("unknown entry type")); + return Err(log_err!("unknown entry type")); } } Ok(()) } - fn extract(&self, path: Option<&str>, out: Option<&str>) -> anyhow::Result<()> { + fn extract(&self, path: Option<&str>, out: Option<&str>) -> LoggedResult<()> { let path = path.map(norm_path); let out = out.map(Path::new); if let (Some(path), Some(out)) = (&path, &out) { @@ -384,9 +383,9 @@ impl Cpio { self.entries.contains_key(&norm_path(path)) } - fn add(&mut self, mode: &mode_t, path: &str, file: &str) -> anyhow::Result<()> { + fn add(&mut self, mode: &mode_t, path: &str, file: &str) -> LoggedResult<()> { if path.ends_with('/') { - return Err(anyhow!("path cannot end with / for add")); + return Err(log_err!("path cannot end with / for add")); } let file = Path::new(file); let content = read(file)?; @@ -403,7 +402,7 @@ impl Cpio { } else if metadata.file_type().is_char_device() { mode | S_IFCHR } else { - return Err(anyhow!("unsupported file type")); + return Err(log_err!("unsupported file type")); } }; self.entries.insert( @@ -451,11 +450,11 @@ impl Cpio { eprintln!("Create symlink [{}] -> [{}]", dst, src); } - fn mv(&mut self, from: &str, to: &str) -> anyhow::Result<()> { + fn mv(&mut self, from: &str, to: &str) -> LoggedResult<()> { let entry = self .entries .remove(&norm_path(from)) - .ok_or(anyhow!("no such entry {}", from))?; + .ok_or(log_err!("no such entry {}", from))?; self.entries.insert(norm_path(to), entry); eprintln!("Move [{}] -> [{}]", from, to); Ok(()) @@ -521,9 +520,9 @@ impl Display for CpioEntry { } pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { - fn inner(argc: i32, argv: *const *const c_char) -> anyhow::Result<()> { + fn inner(argc: i32, argv: *const *const c_char) -> LoggedResult<()> { if argc < 1 { - return Err(anyhow!("no arguments")); + return Err(log_err!("no arguments")); } let cmds: Result, StrErr> = @@ -556,7 +555,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { eprintln!("{}", output); exit(0) } - Err(_) => return Err(anyhow!(output)), + Err(_) => return Err(log_err!(output)), }, }; match &mut cli.command { @@ -580,7 +579,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { CpioCommands::Add(Add { mode, path, file }) => cpio.add(mode, path, file)?, CpioCommands::Extract(Extract { paths }) => { if !paths.is_empty() && paths.len() != 2 { - return Err(anyhow!("invalid arguments")); + return Err(log_err!("invalid arguments")); } cpio.extract( paths.get(0).map(|x| x.as_str()), @@ -597,20 +596,19 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { Ok(()) } inner(argc, argv) - .context("Failed to process cpio") - .log() + .log_with_msg(|w| w.write_str("Failed to process cpio")) .is_ok() } -fn x8u>(x: &[u8; 8]) -> anyhow::Result { +fn x8u>(x: &[u8; 8]) -> LoggedResult { // parse hex let mut ret = 0u32; for i in x { let c = *i as char; - let v = c.to_digit(16).ok_or(anyhow!("bad cpio header"))?; + let v = c.to_digit(16).ok_or(log_err!("bad cpio header"))?; ret = ret * 16 + v; } - ret.try_into().map_err(|_| anyhow!("bad cpio header")) + ret.try_into().map_err(|_| log_err!("bad cpio header")) } #[inline(always)] diff --git a/native/src/boot/patch.rs b/native/src/boot/patch.rs index bf38f0154..49a5e0b42 100644 --- a/native/src/boot/patch.rs +++ b/native/src/boot/patch.rs @@ -1,4 +1,4 @@ -use base::{MappedFile, MutBytesExt, ResultExt, Utf8CStr}; +use base::{LoggedResult, MappedFile, MutBytesExt, Utf8CStr}; // SAFETY: assert(buf.len() >= 1) && assert(len <= buf.len()) macro_rules! match_patterns { @@ -102,7 +102,7 @@ fn hex2byte(hex: &[u8]) -> Vec { } pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool { - fn inner(file: &[u8], from: &[u8], to: &[u8]) -> anyhow::Result { + fn inner(file: &[u8], from: &[u8], to: &[u8]) -> LoggedResult { let file = Utf8CStr::from_bytes(file)?; let from = Utf8CStr::from_bytes(from)?; let to = Utf8CStr::from_bytes(to)?; @@ -118,5 +118,5 @@ pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool { Ok(!v.is_empty()) } - inner(file, from, to).log().unwrap_or(false) + inner(file, from, to).unwrap_or(false) } diff --git a/native/src/boot/payload.rs b/native/src/boot/payload.rs index ede344b34..f4b48af3e 100644 --- a/native/src/boot/payload.rs +++ b/native/src/boot/payload.rs @@ -1,13 +1,13 @@ +use std::fmt::Write as FmtWrite; use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom, Write}; use std::os::fd::{AsRawFd, FromRawFd}; -use anyhow::{anyhow, Context}; use byteorder::{BigEndian, ReadBytesExt}; use quick_protobuf::{BytesReader, MessageRead}; use base::libc::c_char; -use base::{ReadSeekExt, StrErr, Utf8CStr}; +use base::{error, LoggedError, LoggedResult, ReadSeekExt, StrErr, Utf8CStr}; use base::{ResultExt, WriteExt}; use crate::ffi; @@ -15,12 +15,14 @@ use crate::proto::update_metadata::mod_InstallOperation::Type; use crate::proto::update_metadata::DeltaArchiveManifest; macro_rules! bad_payload { - ($msg:literal) => { - anyhow!(concat!("invalid payload: ", $msg)) - }; - ($($args:tt)*) => { - anyhow!("invalid payload: {}", format_args!($($args)*)) - }; + ($msg:literal) => {{ + error!(concat!("Invalid payload: ", $msg)); + LoggedError::default() + }}; + ($($args:tt)*) => {{ + error!("Invalid payload: {}", format_args!($($args)*)); + LoggedError::default() + }}; } const PAYLOAD_MAGIC: &str = "CrAU"; @@ -29,11 +31,11 @@ fn do_extract_boot_from_payload( in_path: &Utf8CStr, partition_name: Option<&Utf8CStr>, out_path: Option<&Utf8CStr>, -) -> anyhow::Result<()> { +) -> LoggedResult<()> { let mut reader = BufReader::new(if in_path == "-" { unsafe { File::from_raw_fd(0) } } else { - File::open(in_path).with_context(|| format!("cannot open '{in_path}'"))? + File::open(in_path).log_with_msg(|w| write!(w, "Cannot open '{}'", in_path))? }); let buf = &mut [0u8; 4]; @@ -88,13 +90,13 @@ fn do_extract_boot_from_payload( .iter() .find(|p| p.partition_name == "boot"), }; - boot.ok_or(anyhow!("boot partition not found"))? + boot.ok_or_else(|| bad_payload!("boot partition not found"))? } Some(name) => manifest .partitions .iter() .find(|p| p.partition_name.as_str() == name) - .ok_or(anyhow!("partition '{name}' not found"))?, + .ok_or_else(|| bad_payload!("partition '{}' not found", name))?, }; let out_str: String; @@ -107,7 +109,7 @@ fn do_extract_boot_from_payload( }; let mut out_file = - File::create(out_path).with_context(|| format!("cannot write to '{out_path}'"))?; + File::create(out_path).log_with_msg(|w| write!(w, "Cannot write to '{}'", out_path))?; // Skip the manifest signature reader.skip(manifest_sig_len as usize)?; @@ -121,11 +123,11 @@ fn do_extract_boot_from_payload( for operation in operations.iter() { let data_len = operation .data_length - .ok_or(bad_payload!("data length not found"))? as usize; + .ok_or_else(|| bad_payload!("data length not found"))? as usize; let data_offset = operation .data_offset - .ok_or(bad_payload!("data offset not found"))?; + .ok_or_else(|| bad_payload!("data offset not found"))?; let data_type = operation.type_pb; @@ -141,9 +143,9 @@ fn do_extract_boot_from_payload( let out_offset = operation .dst_extents .get(0) - .ok_or(bad_payload!("dst extents not found"))? + .ok_or_else(|| bad_payload!("dst extents not found"))? .start_block - .ok_or(bad_payload!("start block not found"))? + .ok_or_else(|| bad_payload!("start block not found"))? * block_size; match data_type { @@ -184,7 +186,7 @@ pub fn extract_boot_from_payload( in_path: *const c_char, partition: *const c_char, out_path: *const c_char, - ) -> anyhow::Result<()> { + ) -> LoggedResult<()> { let in_path = unsafe { Utf8CStr::from_ptr(in_path) }?; let partition = match unsafe { Utf8CStr::from_ptr(partition) } { Ok(s) => Some(s), @@ -197,8 +199,7 @@ pub fn extract_boot_from_payload( Err(e) => Err(e)?, }; do_extract_boot_from_payload(in_path, partition, out_path) - .context("Failed to extract from payload")?; - Ok(()) + .log_with_msg(|w| w.write_str("Failed to extract from payload")) } - inner(in_path, partition, out_path).log().is_ok() + inner(in_path, partition, out_path).is_ok() } diff --git a/native/src/boot/ramdisk.rs b/native/src/boot/ramdisk.rs index 9aa7e5efe..cb2110417 100644 --- a/native/src/boot/ramdisk.rs +++ b/native/src/boot/ramdisk.rs @@ -4,7 +4,7 @@ use std::env; use std::str::from_utf8; use base::libc::{S_IFDIR, S_IFMT, S_IFREG}; -use base::Utf8CStr; +use base::{LoggedResult, Utf8CStr}; use crate::cpio::{Cpio, CpioEntry}; use crate::patch::{patch_encryption, patch_verity}; @@ -12,8 +12,8 @@ use crate::patch::{patch_encryption, patch_verity}; pub trait MagiskCpio { fn patch(&mut self); fn test(&self) -> i32; - fn restore(&mut self) -> anyhow::Result<()>; - fn backup(&mut self, origin: &Utf8CStr) -> anyhow::Result<()>; + fn restore(&mut self) -> LoggedResult<()>; + fn backup(&mut self, origin: &Utf8CStr) -> LoggedResult<()>; } const MAGISK_PATCHED: i32 = 1 << 0; @@ -89,7 +89,7 @@ impl MagiskCpio for Cpio { ret } - fn restore(&mut self) -> anyhow::Result<()> { + fn restore(&mut self) -> LoggedResult<()> { let mut backups = HashMap::>::new(); let mut rm_list = String::new(); self.entries @@ -120,7 +120,7 @@ impl MagiskCpio for Cpio { Ok(()) } - fn backup(&mut self, origin: &Utf8CStr) -> anyhow::Result<()> { + fn backup(&mut self, origin: &Utf8CStr) -> LoggedResult<()> { let mut backups = HashMap::>::new(); let mut rm_list = String::new(); backups.insert( diff --git a/native/src/sepolicy/Cargo.toml b/native/src/sepolicy/Cargo.toml index 92c20b115..601ad337e 100644 --- a/native/src/sepolicy/Cargo.toml +++ b/native/src/sepolicy/Cargo.toml @@ -13,4 +13,3 @@ cxx-gen = { workspace = true } [dependencies] base = { path = "../base" } cxx = { workspace = true } -anyhow = { workspace = true } diff --git a/native/src/sepolicy/lib.rs b/native/src/sepolicy/lib.rs index e63f6d899..b10cf276d 100644 --- a/native/src/sepolicy/lib.rs +++ b/native/src/sepolicy/lib.rs @@ -38,13 +38,13 @@ impl SepolicyExt for sepolicy { } fn load_rule_file(self: Pin<&mut sepolicy>, filename: &[u8]) { - fn inner(sepol: Pin<&mut sepolicy>, filename: &[u8]) -> anyhow::Result<()> { + fn inner(sepol: Pin<&mut sepolicy>, filename: &[u8]) -> LoggedResult<()> { let filename = str::from_utf8(filename)?; let mut reader = BufReader::new(File::open(filename)?); sepol.load_rules_from_reader(&mut reader); Ok(()) } - inner(self, filename).log().ok(); + inner(self, filename).ok(); } fn load_rules_from_reader(mut self: Pin<&mut sepolicy>, reader: &mut T) {