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 anyhow::{bail, Context, Error, Ok, Result};
use std::{ use std::{
fs::{create_dir_all, remove_file, write, File, OpenOptions}, fs::{self, create_dir_all, remove_file, write, File, OpenOptions},
io::{ io::{
ErrorKind::{AlreadyExists, NotFound}, ErrorKind::{AlreadyExists, NotFound},
Write, Write,
}, },
path::Path, path::Path,
process::Command, process::Command,
sync::OnceLock,
}; };
use crate::{assets, boot_patch, defs, ksucalls, module, restorecon}; use crate::{assets, boot_patch, defs, ksucalls, module, restorecon};
@@ -188,14 +189,66 @@ pub fn has_magisk() -> bool {
which::which("magisk").is_ok() 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 { pub fn get_tmp_path() -> &'static str {
if metadata(defs::TEMP_DIR_LEGACY).is_ok() { static CHOSEN_TMP_PATH: OnceLock<String> = OnceLock::new();
return defs::TEMP_DIR_LEGACY;
} CHOSEN_TMP_PATH.get_or_init(|| {
if metadata(defs::TEMP_DIR).is_ok() { let r = find_temp_path();
return defs::TEMP_DIR; log::info!("Chosen temp_path: {}", r);
} r
"" })
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]