Remove open_fd macro

This commit is contained in:
topjohnwu 2025-04-23 14:16:46 -07:00 committed by John Wu
parent ddf5474917
commit 610945ac54
5 changed files with 24 additions and 46 deletions

View File

@ -117,7 +117,7 @@ impl<T: Write> WriteExt for T {
} }
} }
pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> OsResult<OwnedFd> { fn open_fd(path: &Utf8CStr, flags: i32, mode: mode_t) -> OsResult<OwnedFd> {
unsafe { unsafe {
let fd = libc::open(path.as_ptr(), flags, mode as c_uint).as_os_result( let fd = libc::open(path.as_ptr(), flags, mode as c_uint).as_os_result(
"open", "open",
@ -128,18 +128,8 @@ pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> OsResult<Own
} }
} }
#[macro_export]
macro_rules! open_fd {
($path:expr, $flags:expr) => {
$crate::__open_fd_impl($path, $flags, 0)
};
($path:expr, $flags:expr, $mode:expr) => {
$crate::__open_fd_impl($path, $flags, $mode)
};
}
pub fn fd_path(fd: RawFd, buf: &mut dyn Utf8CStrBuf) -> OsResult<'static, ()> { pub fn fd_path(fd: RawFd, buf: &mut dyn Utf8CStrBuf) -> OsResult<'static, ()> {
let path = cstr::buf::default() let path = cstr::buf::new::<64>()
.join_path("/proc/self/fd") .join_path("/proc/self/fd")
.join_path_fmt(fd); .join_path_fmt(fd);
path.read_link(buf).map_err(|e| e.set_args(None, None)) path.read_link(buf).map_err(|e| e.set_args(None, None))
@ -203,11 +193,11 @@ pub trait FsPath: Deref<Target = Utf8CStr> {
} }
fn open(&self, flags: i32) -> OsResult<File> { fn open(&self, flags: i32) -> OsResult<File> {
Ok(File::from(open_fd!(self, flags)?)) Ok(File::from(open_fd(self, flags, 0)?))
} }
fn create(&self, flags: i32, mode: mode_t) -> OsResult<File> { fn create(&self, flags: i32, mode: mode_t) -> OsResult<File> {
Ok(File::from(open_fd!(self, O_CREAT | flags, mode)?)) Ok(File::from(open_fd(self, O_CREAT | flags, mode)?))
} }
fn exists(&self) -> bool { fn exists(&self) -> bool {
@ -234,7 +224,7 @@ pub trait FsPath: Deref<Target = Utf8CStr> {
fn remove_all(&self) -> OsResultStatic<()> { fn remove_all(&self) -> OsResultStatic<()> {
let attr = self.get_attr()?; let attr = self.get_attr()?;
if attr.is_dir() { if attr.is_dir() {
let mut dir = Directory::try_from(open_fd!(self, O_RDONLY | O_CLOEXEC)?)?; let mut dir = Directory::try_from(open_fd(self, O_RDONLY | O_CLOEXEC, 0)?)?;
dir.remove_all()?; dir.remove_all()?;
} }
Ok(self.remove()?) Ok(self.remove()?)
@ -291,7 +281,7 @@ pub trait FsPath: Deref<Target = Utf8CStr> {
// Inspired by https://android.googlesource.com/platform/bionic/+/master/libc/bionic/realpath.cpp // Inspired by https://android.googlesource.com/platform/bionic/+/master/libc/bionic/realpath.cpp
fn realpath(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { fn realpath(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> {
let fd = open_fd!(self, O_PATH | O_CLOEXEC)?; let fd = self.open(O_PATH | O_CLOEXEC)?;
let mut st1: libc::stat; let mut st1: libc::stat;
let mut st2: libc::stat; let mut st2: libc::stat;
let mut skip_check = false; let mut skip_check = false;
@ -851,8 +841,7 @@ fn parse_mount_info_line(line: &str) -> Option<MountInfo> {
pub fn parse_mount_info(pid: &str) -> Vec<MountInfo> { pub fn parse_mount_info(pid: &str) -> Vec<MountInfo> {
let mut res = vec![]; let mut res = vec![];
let mut path = format!("/proc/{}/mountinfo", pid); let mut path = format!("/proc/{}/mountinfo", pid);
if let Ok(fd) = open_fd!(Utf8CStr::from_string(&mut path), O_RDONLY | O_CLOEXEC) { if let Ok(file) = Utf8CStr::from_string(&mut path).open(O_RDONLY | O_CLOEXEC) {
let file = File::from(fd);
BufReader::new(file).foreach_lines(|line| { BufReader::new(file).foreach_lines(|line| {
parse_mount_info_line(line) parse_mount_info_line(line)
.map(|info| res.push(info)) .map(|info| res.push(info))

View File

@ -12,9 +12,7 @@ use crate::su::SuInfo;
use base::libc::{O_CLOEXEC, O_RDONLY}; use base::libc::{O_CLOEXEC, O_RDONLY};
use base::{ use base::{
AtomicArc, BufReadExt, FsPath, FsPathBuilder, ResultExt, Utf8CStr, cstr, error, info, libc, AtomicArc, BufReadExt, FsPath, FsPathBuilder, ResultExt, Utf8CStr, cstr, error, info, libc,
open_fd,
}; };
use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
use std::os::unix::net::UnixStream; use std::os::unix::net::UnixStream;
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
@ -274,8 +272,7 @@ pub fn daemon_entry() {
} }
fn check_data() -> bool { fn check_data() -> bool {
if let Ok(fd) = open_fd!(cstr!("/proc/mounts"), O_RDONLY | O_CLOEXEC) { if let Ok(file) = cstr!("/proc/mounts").open(O_RDONLY | O_CLOEXEC) {
let file = File::from(fd);
let mut mnt = false; let mut mnt = false;
BufReader::new(file).foreach_lines(|line| { BufReader::new(file).foreach_lines(|line| {
if line.contains(" /data ") && !line.contains("tmpfs") { if line.contains(" /data ") && !line.contains("tmpfs") {

View File

@ -5,7 +5,7 @@ use base::WalkResult::{Abort, Continue, Skip};
use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_TRUNC, O_WRONLY}; use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_TRUNC, O_WRONLY};
use base::{ use base::{
BufReadExt, Directory, FsPath, FsPathBuilder, LoggedResult, ReadExt, ResultExt, Utf8CStrBuf, BufReadExt, Directory, FsPath, FsPathBuilder, LoggedResult, ReadExt, ResultExt, Utf8CStrBuf,
cstr, error, fd_get_attr, open_fd, warn, cstr, error, fd_get_attr, warn,
}; };
use bit_set::BitSet; use bit_set::BitSet;
use cxx::CxxString; use cxx::CxxString;
@ -326,12 +326,9 @@ impl ManagerInfo {
let tmp_apk = cstr!("/data/stub.apk"); let tmp_apk = cstr!("/data/stub.apk");
let result: LoggedResult<()> = try { let result: LoggedResult<()> = try {
{ {
let mut tmp_fd = File::from(open_fd!( let mut tmp_apk_file =
tmp_apk, tmp_apk.create(O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0o600)?;
O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, io::copy(stub_fd, &mut tmp_apk_file)?;
0o600
)?);
io::copy(stub_fd, &mut tmp_fd)?;
} }
// Seek the fd back to start // Seek the fd back to start
stub_fd.seek(SeekFrom::Start(0))?; stub_fd.seek(SeekFrom::Start(0))?;

View File

@ -6,8 +6,8 @@ use crate::ffi::{
use crate::socket::{IpcRead, UnixSocketExt}; use crate::socket::{IpcRead, UnixSocketExt};
use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY, STDOUT_FILENO}; use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY, STDOUT_FILENO};
use base::{ use base::{
Directory, FsPathBuilder, LoggedError, LoggedResult, ResultExt, WriteExt, cstr, error, Directory, FsPath, FsPathBuilder, LoggedError, LoggedResult, ResultExt, WriteExt, cstr, error,
fork_dont_care, libc, open_fd, raw_cstr, warn, fork_dont_care, libc, raw_cstr, warn,
}; };
use std::fmt::Write; use std::fmt::Write;
use std::os::fd::{AsRawFd, FromRawFd, RawFd}; use std::os::fd::{AsRawFd, FromRawFd, RawFd};
@ -207,7 +207,7 @@ impl MagiskD {
let dir = cstr::buf::default() let dir = cstr::buf::default()
.join_path(MODULEROOT) .join_path(MODULEROOT)
.join_path(&module.name); .join_path(&module.name);
let fd = open_fd!(&dir, O_RDONLY | O_CLOEXEC)?; let fd = dir.open(O_RDONLY | O_CLOEXEC)?;
client.send_fds(&[fd.as_raw_fd()])?; client.send_fds(&[fd.as_raw_fd()])?;
Ok(()) Ok(())
} }

View File

@ -1,15 +1,15 @@
use base::{ use base::{
FsPath, LOGGER, LogLevel, Logger, Utf8CStr, cstr, FsPath, LOGGER, LogLevel, Logger, SilentResultExt, Utf8CStr, cstr,
libc::{ libc::{
O_CLOEXEC, O_RDWR, O_WRONLY, S_IFCHR, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, SYS_dup3, O_CLOEXEC, O_RDWR, O_WRONLY, S_IFCHR, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, SYS_dup3,
makedev, mknod, syscall, makedev, mknod, syscall,
}, },
open_fd, raw_cstr, raw_cstr,
}; };
use std::mem::ManuallyDrop;
use std::{ use std::{
fs::File, fs::File,
io::{IoSlice, Write}, io::{IoSlice, Write},
mem,
os::fd::{FromRawFd, IntoRawFd, RawFd}, os::fd::{FromRawFd, IntoRawFd, RawFd},
}; };
@ -19,10 +19,10 @@ static mut KMSG: RawFd = -1;
pub fn setup_klog() { pub fn setup_klog() {
unsafe { unsafe {
// Shut down first 3 fds // Shut down first 3 fds
let mut fd = open_fd!(cstr!("/dev/null"), O_RDWR | O_CLOEXEC); let mut fd = cstr!("/dev/null").open(O_RDWR | O_CLOEXEC).silent();
if fd.is_err() { if fd.is_err() {
mknod(raw_cstr!("/null"), S_IFCHR | 0o666, makedev(1, 3)); mknod(raw_cstr!("/null"), S_IFCHR | 0o666, makedev(1, 3));
fd = open_fd!(cstr!("/null"), O_RDWR | O_CLOEXEC); fd = cstr!("/null").open(O_RDWR | O_CLOEXEC).silent();
cstr!("/null").remove().ok(); cstr!("/null").remove().ok();
} }
if let Ok(ref fd) = fd { if let Ok(ref fd) = fd {
@ -32,21 +32,17 @@ pub fn setup_klog() {
} }
// Then open kmsg fd // Then open kmsg fd
let mut fd = open_fd!(cstr!("/dev/kmsg"), O_WRONLY | O_CLOEXEC); let mut fd = cstr!("/dev/kmsg").open(O_WRONLY | O_CLOEXEC).silent();
if fd.is_err() { if fd.is_err() {
mknod(raw_cstr!("/kmsg"), S_IFCHR | 0o666, makedev(1, 11)); mknod(raw_cstr!("/kmsg"), S_IFCHR | 0o666, makedev(1, 11));
fd = open_fd!(cstr!("/kmsg"), O_WRONLY | O_CLOEXEC); fd = cstr!("/kmsg").open(O_WRONLY | O_CLOEXEC).silent();
cstr!("/kmsg").remove().ok(); cstr!("/kmsg").remove().ok();
} }
KMSG = fd.map(|fd| fd.into_raw_fd()).unwrap_or(-1); KMSG = fd.map(|fd| fd.into_raw_fd()).unwrap_or(-1);
} }
// Disable kmsg rate limiting // Disable kmsg rate limiting
if let Ok(rate) = open_fd!( if let Ok(mut rate) = cstr!("/proc/sys/kernel/printk_devkmsg").open(O_WRONLY | O_CLOEXEC) {
cstr!("/proc/sys/kernel/printk_devkmsg"),
O_WRONLY | O_CLOEXEC
) {
let mut rate = File::from(rate);
writeln!(rate, "on").ok(); writeln!(rate, "on").ok();
} }
@ -55,9 +51,8 @@ pub fn setup_klog() {
if fd >= 0 { if fd >= 0 {
let io1 = IoSlice::new("magiskinit: ".as_bytes()); let io1 = IoSlice::new("magiskinit: ".as_bytes());
let io2 = IoSlice::new(msg.as_bytes()); let io2 = IoSlice::new(msg.as_bytes());
let mut kmsg = unsafe { File::from_raw_fd(fd) }; let mut kmsg = ManuallyDrop::new(unsafe { File::from_raw_fd(fd) });
let _ = kmsg.write_vectored(&[io1, io2]).ok(); let _ = kmsg.write_vectored(&[io1, io2]).ok();
mem::forget(kmsg);
} }
} }