opt: Optimize the kpm && uid_scanner (#549)
* opt: Optimize the structure of kpm.rs Signed-off-by: Tools-app <localhost.hutao@gmail.com> * opt: Optimize the uid_scanner startup logic in userspace && code style Signed-off-by: Tools-app <localhost.hutao@gmail.com> * opt: rename kpm's ioctl Signed-off-by: Tools-app <localhost.hutao@gmail.com> * opt: rename ksucalls::KsuKpmCmd's arg2..arg5 using ```rust pub struct KsuKpmCmd { pub control_code: u64, pub arg1: u64, pub arg2: u64, pub result_code: u64, } ``` This makes it easier to distinguish parameters. Signed-off-by: Tools-app <localhost.hutao@gmail.com> --------- Signed-off-by: Tools-app <localhost.hutao@gmail.com>
This commit is contained in:
@@ -1,6 +1,3 @@
|
|||||||
use crate::ksucalls;
|
|
||||||
use anyhow::{Result, anyhow, bail};
|
|
||||||
use notify::{RecursiveMode, Watcher};
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::{CStr, CString, OsStr},
|
ffi::{CStr, CString, OsStr},
|
||||||
fs,
|
fs,
|
||||||
@@ -8,19 +5,24 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use anyhow::{Result, anyhow, bail};
|
||||||
|
use notify::{RecursiveMode, Watcher};
|
||||||
|
|
||||||
|
use crate::ksucalls;
|
||||||
|
|
||||||
pub const KPM_DIR: &str = "/data/adb/kpm";
|
pub const KPM_DIR: &str = "/data/adb/kpm";
|
||||||
|
|
||||||
const SUKISU_KPM_LOAD: u64 = 1;
|
const KPM_LOAD: u64 = 1;
|
||||||
const SUKISU_KPM_UNLOAD: u64 = 2;
|
const KPM_UNLOAD: u64 = 2;
|
||||||
const SUKISU_KPM_NUM: u64 = 3;
|
const KPM_NUM: u64 = 3;
|
||||||
const SUKISU_KPM_LIST: u64 = 4;
|
const KPM_LIST: u64 = 4;
|
||||||
const SUKISU_KPM_INFO: u64 = 5;
|
const KPM_INFO: u64 = 5;
|
||||||
const SUKISU_KPM_CONTROL: u64 = 6;
|
const KPM_CONTROL: u64 = 6;
|
||||||
const SUKISU_KPM_VERSION: u64 = 7;
|
const KPM_VERSION: u64 = 7;
|
||||||
|
|
||||||
/// Convert raw kernel return code to `Result`.
|
/// Convert raw kernel return code to `Result`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn check_out(rc: i32) -> Result<i32> {
|
fn check_ret(rc: i32) -> Result<i32> {
|
||||||
if rc < 0 {
|
if rc < 0 {
|
||||||
bail!("KPM error: {}", std::io::Error::from_raw_os_error(-rc));
|
bail!("KPM error: {}", std::io::Error::from_raw_os_error(-rc));
|
||||||
}
|
}
|
||||||
@@ -34,14 +36,14 @@ pub fn kpm_load(path: &str, args: Option<&str>) -> Result<()> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_LOAD,
|
control_code: KPM_LOAD,
|
||||||
arg3: path_c.as_ptr() as u64,
|
arg1: path_c.as_ptr() as u64,
|
||||||
arg4: args_c.as_ref().map_or(0, |s| s.as_ptr() as u64),
|
arg2: args_c.as_ref().map_or(0, |s| s.as_ptr() as u64),
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)?;
|
check_ret(result)?;
|
||||||
println!("Success");
|
println!("Success");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -52,14 +54,14 @@ pub fn kpm_unload(name: &str) -> Result<()> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_UNLOAD,
|
control_code: KPM_UNLOAD,
|
||||||
arg3: name_c.as_ptr() as u64,
|
arg1: name_c.as_ptr() as u64,
|
||||||
arg4: 0,
|
arg2: 0,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)?;
|
check_ret(result)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +69,14 @@ pub fn kpm_unload(name: &str) -> Result<()> {
|
|||||||
pub fn kpm_num() -> Result<i32> {
|
pub fn kpm_num() -> Result<i32> {
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_NUM,
|
control_code: KPM_NUM,
|
||||||
arg3: 0,
|
arg1: 0,
|
||||||
arg4: 0,
|
arg2: 0,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
let n = check_out(result)?;
|
let n = check_ret(result)?;
|
||||||
println!("{n}");
|
println!("{n}");
|
||||||
Ok(n)
|
Ok(n)
|
||||||
}
|
}
|
||||||
@@ -85,14 +87,14 @@ pub fn kpm_list() -> Result<()> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_LIST,
|
control_code: KPM_LIST,
|
||||||
arg3: buf.as_mut_ptr() as u64,
|
arg1: buf.as_mut_ptr() as u64,
|
||||||
arg4: buf.len() as u64,
|
arg2: buf.len() as u64,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)?;
|
check_ret(result)?;
|
||||||
print!("{}", buf2str(&buf));
|
print!("{}", buf2str(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -104,14 +106,14 @@ pub fn kpm_info(name: &str) -> Result<()> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_INFO,
|
control_code: KPM_INFO,
|
||||||
arg3: name_c.as_ptr() as u64,
|
arg1: name_c.as_ptr() as u64,
|
||||||
arg4: buf.as_mut_ptr() as u64,
|
arg2: buf.as_mut_ptr() as u64,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)?;
|
check_ret(result)?;
|
||||||
println!("{}", buf2str(&buf));
|
println!("{}", buf2str(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -123,14 +125,14 @@ pub fn kpm_control(name: &str, args: &str) -> Result<i32> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_CONTROL,
|
control_code: KPM_CONTROL,
|
||||||
arg3: name_c.as_ptr() as u64,
|
arg1: name_c.as_ptr() as u64,
|
||||||
arg4: args_c.as_ptr() as u64,
|
arg2: args_c.as_ptr() as u64,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)
|
check_ret(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print loader version string.
|
/// Print loader version string.
|
||||||
@@ -139,14 +141,14 @@ pub fn kpm_version_loader() -> Result<()> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_VERSION,
|
control_code: KPM_VERSION,
|
||||||
arg3: buf.as_mut_ptr() as u64,
|
arg1: buf.as_mut_ptr() as u64,
|
||||||
arg4: buf.len() as u64,
|
arg2: buf.len() as u64,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)?;
|
check_ret(result)?;
|
||||||
print!("{}", buf2str(&buf));
|
print!("{}", buf2str(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -157,14 +159,14 @@ pub fn check_kpm_version() -> Result<String> {
|
|||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = ksucalls::KsuKpmCmd {
|
||||||
arg2: SUKISU_KPM_VERSION,
|
control_code: KPM_VERSION,
|
||||||
arg3: buf.as_mut_ptr() as u64,
|
arg1: buf.as_mut_ptr() as u64,
|
||||||
arg4: buf.len() as u64,
|
arg2: buf.len() as u64,
|
||||||
arg5: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||||
check_out(result)?;
|
check_ret(result)?;
|
||||||
let ver = buf2str(&buf);
|
let ver = buf2str(&buf);
|
||||||
if ver.is_empty() {
|
if ver.is_empty() {
|
||||||
bail!("KPM: invalid version response: {ver}");
|
bail!("KPM: invalid version response: {ver}");
|
||||||
@@ -177,6 +179,7 @@ pub fn check_kpm_version() -> Result<String> {
|
|||||||
pub fn ensure_kpm_dir() -> Result<()> {
|
pub fn ensure_kpm_dir() -> Result<()> {
|
||||||
fs::create_dir_all(KPM_DIR)?;
|
fs::create_dir_all(KPM_DIR)?;
|
||||||
let meta = fs::metadata(KPM_DIR)?;
|
let meta = fs::metadata(KPM_DIR)?;
|
||||||
|
|
||||||
if meta.permissions().mode() & 0o777 != 0o777 {
|
if meta.permissions().mode() & 0o777 != 0o777 {
|
||||||
fs::set_permissions(KPM_DIR, fs::Permissions::from_mode(0o777))?;
|
fs::set_permissions(KPM_DIR, fs::Permissions::from_mode(0o777))?;
|
||||||
}
|
}
|
||||||
@@ -187,6 +190,7 @@ pub fn ensure_kpm_dir() -> Result<()> {
|
|||||||
pub fn start_kpm_watcher() -> Result<()> {
|
pub fn start_kpm_watcher() -> Result<()> {
|
||||||
check_kpm_version()?; // bails if loader too old
|
check_kpm_version()?; // bails if loader too old
|
||||||
ensure_kpm_dir()?;
|
ensure_kpm_dir()?;
|
||||||
|
|
||||||
if crate::utils::is_safe_mode() {
|
if crate::utils::is_safe_mode() {
|
||||||
log::warn!("KPM: safe-mode – removing all modules");
|
log::warn!("KPM: safe-mode – removing all modules");
|
||||||
remove_all_kpms()?;
|
remove_all_kpms()?;
|
||||||
@@ -205,7 +209,10 @@ pub fn start_kpm_watcher() -> Result<()> {
|
|||||||
fn handle_kpm_event(evt: notify::Event) {
|
fn handle_kpm_event(evt: notify::Event) {
|
||||||
if let notify::EventKind::Create(_) = evt.kind {
|
if let notify::EventKind::Create(_) = evt.kind {
|
||||||
for p in evt.paths {
|
for p in evt.paths {
|
||||||
if p.extension() == Some(OsStr::new("kpm")) && load_kpm(&p).is_err() {
|
if let Some(ex) = p.extension()
|
||||||
|
&& ex == OsStr::new("kpm")
|
||||||
|
&& load_kpm(&p).is_err()
|
||||||
|
{
|
||||||
log::warn!("KPM: failed to load {}", p.display());
|
log::warn!("KPM: failed to load {}", p.display());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,22 +228,30 @@ pub fn load_kpm(path: &Path) -> Result<()> {
|
|||||||
/// Unload module and delete file.
|
/// Unload module and delete file.
|
||||||
pub fn unload_kpm(name: &str) -> Result<()> {
|
pub fn unload_kpm(name: &str) -> Result<()> {
|
||||||
kpm_unload(name)?;
|
kpm_unload(name)?;
|
||||||
|
|
||||||
if let Some(p) = find_kpm_file(name)? {
|
if let Some(p) = find_kpm_file(name)? {
|
||||||
let _ = fs::remove_file(&p);
|
let _ = fs::remove_file(&p);
|
||||||
log::info!("KPM: deleted {}", p.display());
|
log::info!("KPM: deleted {}", p.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locate `/data/adb/kpm/<name>.kpm`.
|
/// Locate `/data/adb/kpm/<name>.kpm`.
|
||||||
fn find_kpm_file(name: &str) -> Result<Option<PathBuf>> {
|
fn find_kpm_file(name: &str) -> Result<Option<PathBuf>> {
|
||||||
let dir = Path::new(KPM_DIR);
|
let dir = Path::new(KPM_DIR);
|
||||||
|
|
||||||
if !dir.is_dir() {
|
if !dir.is_dir() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
for entry in fs::read_dir(dir)? {
|
for entry in fs::read_dir(dir)? {
|
||||||
let p = entry?.path();
|
let p = entry?.path();
|
||||||
if p.extension() == Some(OsStr::new("kpm")) && p.file_stem() == Some(OsStr::new(name)) {
|
if let Some(ex) = p.extension()
|
||||||
|
&& ex == OsStr::new("kpm")
|
||||||
|
&& let Some(fs) = p.file_stem()
|
||||||
|
&& fs == OsStr::new(name)
|
||||||
|
{
|
||||||
return Ok(Some(p));
|
return Ok(Some(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,7 +266,8 @@ pub fn remove_all_kpms() -> Result<()> {
|
|||||||
}
|
}
|
||||||
for entry in fs::read_dir(dir)? {
|
for entry in fs::read_dir(dir)? {
|
||||||
let p = entry?.path();
|
let p = entry?.path();
|
||||||
if p.extension() == Some(OsStr::new("kpm"))
|
if let Some(ex) = p.extension()
|
||||||
|
&& ex == OsStr::new("kpm")
|
||||||
&& let Some(name) = p.file_stem().and_then(|s| s.to_str())
|
&& let Some(name) = p.file_stem().and_then(|s| s.to_str())
|
||||||
&& let Err(e) = unload_kpm(name)
|
&& let Err(e) = unload_kpm(name)
|
||||||
{
|
{
|
||||||
@@ -265,14 +281,19 @@ pub fn remove_all_kpms() -> Result<()> {
|
|||||||
pub fn load_kpm_modules() -> Result<()> {
|
pub fn load_kpm_modules() -> Result<()> {
|
||||||
check_kpm_version()?;
|
check_kpm_version()?;
|
||||||
ensure_kpm_dir()?;
|
ensure_kpm_dir()?;
|
||||||
|
|
||||||
let dir = Path::new(KPM_DIR);
|
let dir = Path::new(KPM_DIR);
|
||||||
if !dir.is_dir() {
|
if !dir.is_dir() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut ok, mut ng) = (0, 0);
|
let (mut ok, mut ng) = (0, 0);
|
||||||
|
|
||||||
for entry in fs::read_dir(dir)? {
|
for entry in fs::read_dir(dir)? {
|
||||||
let p = entry?.path();
|
let p = entry?.path();
|
||||||
if p.extension() == Some(OsStr::new("kpm")) {
|
if let Some(ex) = p.extension()
|
||||||
|
&& ex == OsStr::new("kpm")
|
||||||
|
{
|
||||||
match load_kpm(&p) {
|
match load_kpm(&p) {
|
||||||
Ok(_) => ok += 1,
|
Ok(_) => ok += 1,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -243,10 +243,10 @@ pub fn proxy_file(fd: RawFd) -> std::io::Result<RawFd> {
|
|||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct KsuKpmCmd {
|
pub struct KsuKpmCmd {
|
||||||
|
pub control_code: u64,
|
||||||
|
pub arg1: u64,
|
||||||
pub arg2: u64,
|
pub arg2: u64,
|
||||||
pub arg3: u64,
|
pub result_code: u64,
|
||||||
pub arg4: u64,
|
|
||||||
pub arg5: u64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
defs,
|
||||||
ksucalls::proxy_file,
|
ksucalls::proxy_file,
|
||||||
utils::{self, umask},
|
utils::{self, umask},
|
||||||
defs,
|
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Ok, Result, bail};
|
use anyhow::{Context, Ok, Result, bail};
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
|
|||||||
@@ -5,21 +5,20 @@ use std::{
|
|||||||
fs::{PermissionsExt, symlink},
|
fs::{PermissionsExt, symlink},
|
||||||
process::CommandExt,
|
process::CommandExt,
|
||||||
},
|
},
|
||||||
path::Path,
|
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
|
||||||
pub fn start_uid_scanner_daemon() -> Result<()> {
|
const SCANNER_PATH: &str = "/data/adb/uid_scanner";
|
||||||
const SCANNER_PATH: &str = "/data/adb/uid_scanner";
|
const LINK_DIR: &str = "/data/adb/ksu/bin";
|
||||||
const LINK_DIR: &str = "/data/adb/ksu/bin";
|
const LINK_PATH: &str = "/data/adb/ksu/bin/uid_scanner";
|
||||||
const LINK_PATH: &str = "/data/adb/ksu/bin/uid_scanner";
|
const SERVICE_DIR: &str = "/data/adb/service.d";
|
||||||
const SERVICE_DIR: &str = "/data/adb/service.d";
|
const SERVICE_PATH: &str = "/data/adb/service.d/uid_scanner.sh";
|
||||||
const SERVICE_PATH: &str = "/data/adb/service.d/uid_scanner.sh";
|
|
||||||
|
|
||||||
if !Path::new(SCANNER_PATH).exists() {
|
pub fn start_uid_scanner_daemon() -> Result<()> {
|
||||||
|
if !fs::exists(SCANNER_PATH)? {
|
||||||
warn!("uid scanner binary not found at {}", SCANNER_PATH);
|
warn!("uid scanner binary not found at {}", SCANNER_PATH);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -32,7 +31,7 @@ pub fn start_uid_scanner_daemon() -> Result<()> {
|
|||||||
{
|
{
|
||||||
if let Err(e) = fs::create_dir_all(LINK_DIR) {
|
if let Err(e) = fs::create_dir_all(LINK_DIR) {
|
||||||
warn!("failed to create {}: {}", LINK_DIR, e);
|
warn!("failed to create {}: {}", LINK_DIR, e);
|
||||||
} else if !Path::new(LINK_PATH).exists() {
|
} else if !fs::exists(LINK_PATH)? {
|
||||||
match symlink(SCANNER_PATH, LINK_PATH) {
|
match symlink(SCANNER_PATH, LINK_PATH) {
|
||||||
Ok(_) => info!("created symlink {} -> {}", SCANNER_PATH, LINK_PATH),
|
Ok(_) => info!("created symlink {} -> {}", SCANNER_PATH, LINK_PATH),
|
||||||
Err(e) => warn!("failed to create symlink: {}", e),
|
Err(e) => warn!("failed to create symlink: {}", e),
|
||||||
@@ -42,13 +41,11 @@ pub fn start_uid_scanner_daemon() -> Result<()> {
|
|||||||
|
|
||||||
if let Err(e) = fs::create_dir_all(SERVICE_DIR) {
|
if let Err(e) = fs::create_dir_all(SERVICE_DIR) {
|
||||||
warn!("failed to create {}: {}", SERVICE_DIR, e);
|
warn!("failed to create {}: {}", SERVICE_DIR, e);
|
||||||
} else if !Path::new(SERVICE_PATH).exists() {
|
}
|
||||||
let content = r#"#!/system/bin/sh
|
|
||||||
# KSU uid_scanner auto-restart script
|
if !fs::exists(SERVICE_PATH)? {
|
||||||
until [ -d "/sdcard/Android" ]; do sleep 1; done
|
let content = include_str!("uid_scanner.sh");
|
||||||
sleep 10
|
|
||||||
/data/adb/uid_scanner restart
|
|
||||||
"#;
|
|
||||||
match fs::OpenOptions::new()
|
match fs::OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create_new(true)
|
.create_new(true)
|
||||||
|
|||||||
5
userspace/ksud/src/uid_scanner.sh
Normal file
5
userspace/ksud/src/uid_scanner.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/system/bin/sh
|
||||||
|
# KSU uid_scanner auto-restart script
|
||||||
|
until [ -d "/sdcard/Android" ]; do sleep 1; done
|
||||||
|
sleep 10
|
||||||
|
/data/adb/uid_scanner restart
|
||||||
Reference in New Issue
Block a user