mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-12 10:26:04 +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)]
|
#[inline(always)]
|
||||||
pub fn as_bytes_with_nul(&self) -> &[u8] {
|
pub fn as_bytes_with_nul(&self) -> &[u8] {
|
||||||
&self.0
|
&self.0
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
use crate::{StrErr, Utf8CStr, ffi};
|
use crate::{Utf8CStr, cstr, ffi};
|
||||||
use argh::EarlyExit;
|
use argh::EarlyExit;
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
use std::fmt::Arguments;
|
use std::{
|
||||||
use std::io::Write;
|
fmt,
|
||||||
use std::mem::ManuallyDrop;
|
fmt::Arguments,
|
||||||
use std::process::exit;
|
io::Write,
|
||||||
use std::sync::Arc;
|
mem::ManuallyDrop,
|
||||||
use std::sync::atomic::{AtomicPtr, Ordering};
|
process::exit,
|
||||||
use std::{fmt, slice, str};
|
slice, str,
|
||||||
|
sync::Arc,
|
||||||
|
sync::atomic::{AtomicPtr, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
pub fn errno() -> &'static mut i32 {
|
pub fn errno() -> &'static mut i32 {
|
||||||
unsafe { &mut *libc::__errno() }
|
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> {
|
pub trait EarlyExitExt<T> {
|
||||||
fn on_early_exit<F: FnOnce()>(self, print_help_msg: F) -> T;
|
fn on_early_exit<F: FnOnce()>(self, print_help_msg: F) -> T;
|
||||||
}
|
}
|
||||||
@@ -227,3 +221,35 @@ impl Chunker {
|
|||||||
chunk
|
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 crate::sign::sha1_hash;
|
||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
use base::{
|
use base::{
|
||||||
EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, cmdline_logging, cstr,
|
CmdArgs, EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, cmdline_logging, cstr,
|
||||||
libc::umask, log_err, map_args,
|
libc::umask, log_err,
|
||||||
};
|
};
|
||||||
use std::ffi::c_char;
|
use std::ffi::c_char;
|
||||||
use std::str::FromStr;
|
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();
|
cmdline_logging();
|
||||||
unsafe { umask(0) };
|
unsafe { umask(0) };
|
||||||
let res: LoggedResult<()> = try {
|
let res: LoggedResult<()> = try {
|
||||||
let mut cmds = map_args(argc, argv)?;
|
let mut cmds = CmdArgs::new(argc, argv).0;
|
||||||
if argc < 2 {
|
if argc < 2 {
|
||||||
print_usage(cmds.first().unwrap_or(&"magiskboot"));
|
print_usage(cmds.first().unwrap_or(&"magiskboot"));
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use crate::ffi::SePolicy;
|
|||||||
use crate::statement::format_statement_help;
|
use crate::statement::format_statement_help;
|
||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
use base::{
|
use base::{
|
||||||
EarlyExitExt, FmtAdaptor, LoggedResult, Utf8CStr, cmdline_logging, cstr, libc::umask, log_err,
|
CmdArgs, EarlyExitExt, FmtAdaptor, LoggedResult, Utf8CStr, cmdline_logging, cstr, libc::umask,
|
||||||
map_args,
|
log_err,
|
||||||
};
|
};
|
||||||
use std::ffi::c_char;
|
use std::ffi::c_char;
|
||||||
use std::io::stderr;
|
use std::io::stderr;
|
||||||
@@ -79,7 +79,8 @@ pub unsafe extern "C" fn main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let res: LoggedResult<()> = try {
|
let res: LoggedResult<()> = try {
|
||||||
let cmds = map_args(argc, argv)?;
|
let cmds = CmdArgs::new(argc, argv);
|
||||||
|
let cmds = cmds.as_slice();
|
||||||
if argc < 2 {
|
if argc < 2 {
|
||||||
print_usage(cmds.first().unwrap_or(&"magiskpolicy"));
|
print_usage(cmds.first().unwrap_or(&"magiskpolicy"));
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user