diff --git a/native/src/base/files.rs b/native/src/base/files.rs index 2ad3a7cdb..d82e5e9fb 100644 --- a/native/src/base/files.rs +++ b/native/src/base/files.rs @@ -11,9 +11,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd}; use std::{io, mem, ptr, slice}; use bytemuck::{bytes_of_mut, Pod}; -use libc::{ - c_char, c_uint, dirent, mode_t, EEXIST, ENOENT, F_OK, O_CLOEXEC, O_PATH, O_RDONLY, O_RDWR, -}; +use libc::{c_uint, dirent, mode_t, EEXIST, ENOENT, F_OK, O_CLOEXEC, O_PATH, O_RDONLY, O_RDWR}; use crate::{ copy_cstr, cstr, errno, error, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrArr, @@ -37,14 +35,6 @@ macro_rules! open_fd { }; } -pub(crate) unsafe fn readlink_unsafe(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { - let r = libc::readlink(path, buf.cast(), bufsz - 1); - if r >= 0 { - *buf.offset(r) = b'\0'; - } - r -} - pub fn fd_path(fd: RawFd, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> { let mut arr = Utf8CStrArr::<40>::new(); let path = FsPathBuf::new(&mut arr).join("/proc/self/fd").join_fmt(fd); @@ -412,9 +402,10 @@ impl FsPath { pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> { buf.clear(); unsafe { - let c = readlink_unsafe(self.as_ptr(), buf.as_mut_ptr().cast(), buf.capacity()); - c.check_os_err()?; - buf.set_len(c as usize); + let r = libc::readlink(self.as_ptr(), buf.as_mut_ptr().cast(), buf.capacity() - 1) + .check_os_err()? as usize; + *buf.mut_buf().get_unchecked_mut(r) = b'\0'; + buf.set_len(r); } Ok(()) } diff --git a/native/src/base/xwrap.rs b/native/src/base/xwrap.rs index 31100db70..3365f43eb 100644 --- a/native/src/base/xwrap.rs +++ b/native/src/base/xwrap.rs @@ -10,7 +10,7 @@ use libc::{ ssize_t, SYS_dup3, }; -use crate::{cstr, errno, raw_cstr, readlink_unsafe, FsPath, ResultExt, Utf8CStr, Utf8CStrSlice}; +use crate::{cstr, errno, raw_cstr, FsPath, ResultExt, Utf8CStr, Utf8CStrSlice}; fn ptr_to_str<'a, T>(ptr: *const T) -> &'a str { if ptr.is_null() { @@ -77,11 +77,16 @@ unsafe extern "C" fn xrealpath(path: *const c_char, buf: *mut u8, bufsz: usize) #[no_mangle] unsafe extern "C" fn xreadlink(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { - let r = readlink_unsafe(path, buf, bufsz); - if r < 0 { - perror!("readlink"); + match Utf8CStr::from_ptr(path) { + Ok(p) => { + let mut buf = Utf8CStrSlice::from_ptr(buf, bufsz); + FsPath::from(p) + .read_link(&mut buf) + .log_cxx_with_msg(|w| w.write_fmt(format_args!("readlink {} failed", p))) + .map_or(-1, |_| buf.len() as isize) + } + Err(_) => -1, } - r } #[no_mangle]