From 8e1a91509cfafbeba9ed5f3589c57a1ed8aabdbb Mon Sep 17 00:00:00 2001
From: topjohnwu <topjohnwu@gmail.com>
Date: Tue, 19 Sep 2023 00:06:21 -0700
Subject: [PATCH] Remove readlink_unsafe

---
 native/src/base/files.rs | 19 +++++--------------
 native/src/base/xwrap.rs | 15 ++++++++++-----
 2 files changed, 15 insertions(+), 19 deletions(-)

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]