mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-23 05:37:47 +00:00
Introduce CmdArgs for argument parsing in Rust
This commit is contained in:
@@ -300,6 +300,13 @@ impl Utf8CStr {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn from_raw_parts<'a>(ptr: *const c_char, len: usize) -> &'a Utf8CStr {
|
||||
unsafe {
|
||||
let bytes = slice::from_raw_parts(ptr.cast(), len);
|
||||
Self::from_bytes_unchecked(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_bytes_with_nul(&self) -> &[u8] {
|
||||
&self.0
|
||||
|
@@ -1,13 +1,16 @@
|
||||
use crate::{StrErr, Utf8CStr, ffi};
|
||||
use crate::{Utf8CStr, cstr, ffi};
|
||||
use argh::EarlyExit;
|
||||
use libc::c_char;
|
||||
use std::fmt::Arguments;
|
||||
use std::io::Write;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicPtr, Ordering};
|
||||
use std::{fmt, slice, str};
|
||||
use std::{
|
||||
fmt,
|
||||
fmt::Arguments,
|
||||
io::Write,
|
||||
mem::ManuallyDrop,
|
||||
process::exit,
|
||||
slice, str,
|
||||
sync::Arc,
|
||||
sync::atomic::{AtomicPtr, Ordering},
|
||||
};
|
||||
|
||||
pub fn errno() -> &'static mut i32 {
|
||||
unsafe { &mut *libc::__errno() }
|
||||
@@ -76,15 +79,6 @@ impl<T: AsMut<[u8]> + ?Sized> MutBytesExt for T {
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: libc guarantees argc and argv are properly setup and are static
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
pub fn map_args(argc: i32, argv: *const *const c_char) -> Result<Vec<&'static str>, StrErr> {
|
||||
unsafe { slice::from_raw_parts(argv, argc as usize) }
|
||||
.iter()
|
||||
.map(|s| unsafe { Utf8CStr::from_ptr(*s) }.map(|s| s.as_str()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub trait EarlyExitExt<T> {
|
||||
fn on_early_exit<F: FnOnce()>(self, print_help_msg: F) -> T;
|
||||
}
|
||||
@@ -227,3 +221,35 @@ impl Chunker {
|
||||
chunk
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CmdArgs(pub Vec<&'static str>);
|
||||
|
||||
impl CmdArgs {
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
pub fn new(argc: i32, argv: *const *const c_char) -> CmdArgs {
|
||||
CmdArgs(
|
||||
// SAFETY: libc guarantees argc and argv are properly setup and are static
|
||||
unsafe { slice::from_raw_parts(argv, argc as usize) }
|
||||
.iter()
|
||||
.map(|s| unsafe { Utf8CStr::from_ptr(*s) })
|
||||
.map(|r| r.unwrap_or(cstr!("<invalid>")))
|
||||
.map(Utf8CStr::as_str)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[&'static str] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> slice::Iter<'_, &'static str> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
pub fn cstr_iter(&self) -> impl Iterator<Item = &'static Utf8CStr> {
|
||||
// SAFETY: libc guarantees null terminated strings
|
||||
self.0
|
||||
.iter()
|
||||
.map(|s| unsafe { Utf8CStr::from_raw_parts(s.as_ptr().cast(), s.len() + 1) })
|
||||
}
|
||||
}
|
||||
|
@@ -7,8 +7,8 @@ use crate::payload::extract_boot_from_payload;
|
||||
use crate::sign::sha1_hash;
|
||||
use argh::FromArgs;
|
||||
use base::{
|
||||
EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, cmdline_logging, cstr,
|
||||
libc::umask, log_err, map_args,
|
||||
CmdArgs, EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, cmdline_logging, cstr,
|
||||
libc::umask, log_err,
|
||||
};
|
||||
use std::ffi::c_char;
|
||||
use std::str::FromStr;
|
||||
@@ -264,7 +264,7 @@ pub extern "C" fn main(argc: i32, argv: *const *const c_char, _envp: *const *con
|
||||
cmdline_logging();
|
||||
unsafe { umask(0) };
|
||||
let res: LoggedResult<()> = try {
|
||||
let mut cmds = map_args(argc, argv)?;
|
||||
let mut cmds = CmdArgs::new(argc, argv).0;
|
||||
if argc < 2 {
|
||||
print_usage(cmds.first().unwrap_or(&"magiskboot"));
|
||||
return 1;
|
||||
|
@@ -2,8 +2,8 @@ use crate::ffi::SePolicy;
|
||||
use crate::statement::format_statement_help;
|
||||
use argh::FromArgs;
|
||||
use base::{
|
||||
EarlyExitExt, FmtAdaptor, LoggedResult, Utf8CStr, cmdline_logging, cstr, libc::umask, log_err,
|
||||
map_args,
|
||||
CmdArgs, EarlyExitExt, FmtAdaptor, LoggedResult, Utf8CStr, cmdline_logging, cstr, libc::umask,
|
||||
log_err,
|
||||
};
|
||||
use std::ffi::c_char;
|
||||
use std::io::stderr;
|
||||
@@ -79,7 +79,8 @@ pub unsafe extern "C" fn main(
|
||||
}
|
||||
|
||||
let res: LoggedResult<()> = try {
|
||||
let cmds = map_args(argc, argv)?;
|
||||
let cmds = CmdArgs::new(argc, argv);
|
||||
let cmds = cmds.as_slice();
|
||||
if argc < 2 {
|
||||
print_usage(cmds.first().unwrap_or(&"magiskpolicy"));
|
||||
return 1;
|
||||
|
Reference in New Issue
Block a user