Files
SukiSU-Ultra/userspace/ksud/src/uid_scanner.rs

91 lines
2.7 KiB
Rust

use anyhow::Result;
use log::{info, warn};
use std::{
fs,
io::Write,
os::unix::{
fs::{symlink, PermissionsExt},
process::CommandExt,
},
path::Path,
process::{Command, Stdio},
};
pub fn start_uid_scanner_daemon() -> Result<()> {
const SCANNER_PATH: &str = "/data/adb/uid_scanner";
const LINK_DIR: &str = "/data/adb/ksu/bin";
const LINK_PATH: &str = "/data/adb/ksu/bin/uid_scanner";
const SERVICE_DIR: &str = "/data/adb/service.d";
const SERVICE_PATH: &str = "/data/adb/service.d/uid_scanner.sh";
if !Path::new(SCANNER_PATH).exists() {
warn!("uid scanner binary not found at {}", SCANNER_PATH);
return Ok(());
}
if let Err(e) = fs::set_permissions(SCANNER_PATH, fs::Permissions::from_mode(0o755)) {
warn!("failed to set permissions for {}: {}", SCANNER_PATH, e);
}
#[cfg(unix)]
{
if let Err(e) = fs::create_dir_all(LINK_DIR) {
warn!("failed to create {}: {}", LINK_DIR, e);
} else if !Path::new(LINK_PATH).exists() {
match symlink(SCANNER_PATH, LINK_PATH) {
Ok(_) => info!("created symlink {} -> {}", SCANNER_PATH, LINK_PATH),
Err(e) => warn!("failed to create symlink: {}", e),
}
}
}
if let Err(e) = fs::create_dir_all(SERVICE_DIR) {
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
until [ -d "/sdcard/Android" ]; do sleep 1; done
sleep 10
/data/adb/uid_scanner restart
"#;
match fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(SERVICE_PATH)
.and_then(|mut f| {
f.write_all(content.as_bytes())?;
f.sync_all()?;
fs::set_permissions(SERVICE_PATH, fs::Permissions::from_mode(0o755))
}) {
Ok(_) => info!("created service script {}", SERVICE_PATH),
Err(e) => warn!("failed to write {}: {}", SERVICE_PATH, e),
}
}
info!("starting uid scanner daemon with highest priority");
let mut cmd = Command::new(SCANNER_PATH);
cmd.arg("start")
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.current_dir("/");
unsafe {
cmd.pre_exec(|| {
libc::nice(-20);
libc::setsid();
Ok(())
});
}
match cmd.spawn() {
Ok(child) => {
info!("uid scanner daemon started with pid: {}", child.id());
std::mem::drop(child);
}
Err(e) => warn!("failed to start uid scanner daemon: {}", e),
}
Ok(())
}