ksud: refine get_tmp_path (#1713)

Fixes #1710

What do you think?

* It first uses `TEMP_DIR` (`/debug_ramdisk`) if it exists + is is
empty.
* Otherwise it tries to create a random directory in `/dev`.
* If that fails, it goes through a list of directories (including
`TEMP_DIR_LEGACY`), and chooses the first one that is empty.
* If no empty directory it chooses the first one that exists

---------

Co-authored-by: user <user@localhost>
This commit is contained in:
powellnorma
2024-05-16 04:30:20 +02:00
committed by GitHub
parent fb6ce7ee62
commit 71cb86c2e9

View File

@@ -1,12 +1,13 @@
use anyhow::{bail, Context, Error, Ok, Result};
use std::{
fs::{create_dir_all, remove_file, write, File, OpenOptions},
fs::{self, create_dir_all, remove_file, write, File, OpenOptions},
io::{
ErrorKind::{AlreadyExists, NotFound},
Write,
},
path::Path,
process::Command,
sync::OnceLock,
};
use crate::{assets, boot_patch, defs, ksucalls, module, restorecon};
@@ -188,14 +189,66 @@ pub fn has_magisk() -> bool {
which::which("magisk").is_ok()
}
fn is_ok_empty(dir: &str) -> bool {
use std::result::Result::{Err, Ok};
match fs::read_dir(dir) {
Ok(mut entries) => entries.next().is_none(),
Err(_) => false,
}
}
fn find_temp_path() -> String {
use std::result::Result::{Err, Ok};
if is_ok_empty(defs::TEMP_DIR) {
return defs::TEMP_DIR.to_string();
}
// Try to create a random directory in /dev/
let r = tempdir::TempDir::new_in("/dev/", "");
match r {
Ok(tmp_dir) => {
if let Some(path) = tmp_dir.into_path().to_str() {
return path.to_string();
}
}
Err(_e) => {}
}
let dirs = [
defs::TEMP_DIR,
"/patch_hw",
"/oem",
"/root",
defs::TEMP_DIR_LEGACY,
];
// find empty directory
for dir in dirs {
if is_ok_empty(dir) {
return dir.to_string();
}
}
// Fallback to non-empty directory
for dir in dirs {
if metadata(dir).is_ok() {
return dir.to_string();
}
}
"".to_string()
}
pub fn get_tmp_path() -> &'static str {
if metadata(defs::TEMP_DIR_LEGACY).is_ok() {
return defs::TEMP_DIR_LEGACY;
}
if metadata(defs::TEMP_DIR).is_ok() {
return defs::TEMP_DIR;
}
""
static CHOSEN_TMP_PATH: OnceLock<String> = OnceLock::new();
CHOSEN_TMP_PATH.get_or_init(|| {
let r = find_temp_path();
log::info!("Chosen temp_path: {}", r);
r
})
}
#[cfg(target_os = "android")]