Introduce cstr_buf helper functions

This commit is contained in:
topjohnwu
2025-02-17 11:32:21 -08:00
parent fc2ef21660
commit 363410e1c0
10 changed files with 70 additions and 36 deletions

View File

@@ -22,6 +22,8 @@ use crate::slice_from_ptr_mut;
// Utf8CStrBufRef: reference to a fixed sized buffer
// Utf8CStrBufArr<N>: fixed sized buffer allocated on the stack
//
// For easier usage, please use the helper functions in cstr_buf.
//
// In most cases, these are the types being used
//
// &Utf8CStr: whenever a printable null terminated string is needed
@@ -33,6 +35,37 @@ use crate::slice_from_ptr_mut;
// All types dereferences to &Utf8CStr.
// Utf8CString, Utf8CStrBufRef, and Utf8CStrBufArr<N> implements Utf8CStrBuf.
// Public helper functions
pub mod cstr_buf {
use super::{Utf8CStrBufArr, Utf8CStrBufRef, Utf8CString};
#[inline(always)]
pub fn with_capacity(capacity: usize) -> Utf8CString {
Utf8CString::with_capacity(capacity)
}
#[inline(always)]
pub fn default() -> Utf8CStrBufArr<4096> {
Utf8CStrBufArr::default()
}
#[inline(always)]
pub fn new<const N: usize>() -> Utf8CStrBufArr<N> {
Utf8CStrBufArr::new()
}
#[inline(always)]
pub fn wrap(buf: &mut [u8]) -> Utf8CStrBufRef {
Utf8CStrBufRef::from(buf)
}
#[inline(always)]
pub unsafe fn wrap_ptr<'a>(buf: *mut u8, len: usize) -> Utf8CStrBufRef<'a> {
Utf8CStrBufRef::from_ptr(buf, len)
}
}
// Trait definitions
pub trait Utf8CStrBuf:
@@ -492,13 +525,13 @@ impl FsPathBuf<0> {
impl Default for FsPathBuf<4096> {
fn default() -> Self {
FsPathBuf(Utf8CStrBufOwned::Fixed(Utf8CStrBufArr::default()))
FsPathBuf(Utf8CStrBufOwned::Fixed(cstr_buf::default()))
}
}
impl<const N: usize> FsPathBuf<N> {
pub fn new() -> Self {
FsPathBuf(Utf8CStrBufOwned::Fixed(Utf8CStrBufArr::<N>::new()))
FsPathBuf(Utf8CStrBufOwned::Fixed(cstr_buf::new::<N>()))
}
pub fn clear(&mut self) {

View File

@@ -9,12 +9,12 @@ use libc::{c_char, mode_t};
use crate::files::map_file_at;
pub(crate) use crate::xwrap::*;
use crate::{
clone_attr, cstr, fclone_attr, fd_path, map_fd, map_file, slice_from_ptr, CxxResultExt,
Directory, FsPath, Utf8CStr, Utf8CStrBufRef,
clone_attr, cstr, cstr_buf, fclone_attr, fd_path, map_fd, map_file, slice_from_ptr,
CxxResultExt, Directory, FsPath, Utf8CStr,
};
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
let mut buf = Utf8CStrBufRef::from(buf);
let mut buf = cstr_buf::wrap(buf);
fd_path(fd, &mut buf)
.log_cxx_with_msg(|w| w.write_str("fd_path failed"))
.map_or(-1_isize, |_| buf.len() as isize)
@@ -24,7 +24,7 @@ pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
match Utf8CStr::from_ptr(path) {
Ok(p) => {
let mut buf = Utf8CStrBufRef::from_ptr(buf, bufsz);
let mut buf = cstr_buf::wrap_ptr(buf, bufsz);
FsPath::from(p)
.realpath(&mut buf)
.map_or(-1, |_| buf.len() as isize)

View File

@@ -1,6 +1,7 @@
use crate::cxx_extern::readlinkat_for_cxx;
use crate::{
cstr, errno, error, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrBuf, Utf8CStrBufArr,
cstr, cstr_buf, errno, error, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrBuf,
Utf8CStrBufArr,
};
use bytemuck::{bytes_of, bytes_of_mut, Pod};
use libc::{
@@ -284,13 +285,13 @@ impl DirEntry<'_> {
}
pub fn get_attr(&self) -> io::Result<FileAttr> {
let mut path = Utf8CStrBufArr::default();
let mut path = cstr_buf::default();
self.path(&mut path)?;
FsPath::from(&path).get_attr()
}
pub fn set_attr(&self, attr: &FileAttr) -> io::Result<()> {
let mut path = Utf8CStrBufArr::default();
let mut path = cstr_buf::default();
self.path(&mut path)?;
FsPath::from(&path).set_attr(attr)
}
@@ -431,7 +432,7 @@ impl Directory {
std::io::copy(&mut src, &mut dest)?;
fd_set_attr(dest.as_raw_fd(), &attr)?;
} else if e.is_symlink() {
let mut path = Utf8CStrBufArr::default();
let mut path = cstr_buf::default();
e.read_link(&mut path)?;
unsafe {
libc::symlinkat(path.as_ptr(), dir.as_raw_fd(), e.d_name.as_ptr())
@@ -645,7 +646,7 @@ impl FsPath {
if self.is_empty() {
return Ok(());
}
let mut arr = Utf8CStrBufArr::default();
let mut arr = cstr_buf::default();
arr.push_str(self);
let mut off = 1;
unsafe {
@@ -748,7 +749,7 @@ impl FsPath {
let mut dest = path.create(O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0o777)?;
std::io::copy(&mut src, &mut dest)?;
} else if attr.is_symlink() {
let mut buf = Utf8CStrBufArr::default();
let mut buf = cstr_buf::default();
self.read_link(&mut buf)?;
unsafe {
libc::symlink(buf.as_ptr(), path.as_ptr()).as_os_err()?;

View File

@@ -7,7 +7,7 @@ use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::FromPrimitive;
use crate::ffi::LogLevelCxx;
use crate::{Utf8CStr, Utf8CStrBufArr};
use crate::{cstr_buf, Utf8CStr};
// Ugly hack to avoid using enum
#[allow(non_snake_case, non_upper_case_globals)]
@@ -96,7 +96,7 @@ pub fn log_from_cxx(level: LogLevelCxx, msg: &Utf8CStr) {
pub fn log_with_formatter<F: FnOnce(Formatter) -> fmt::Result>(level: LogLevel, f: F) {
log_with_writer(level, |write| {
let mut buf = Utf8CStrBufArr::default();
let mut buf = cstr_buf::default();
f(&mut buf).ok();
write(level, &buf);
});