Fix mkdirs

This commit is contained in:
topjohnwu 2024-04-10 22:36:47 -07:00
parent c50ee722a1
commit 2a3d34c812
2 changed files with 13 additions and 13 deletions

View File

@ -34,13 +34,6 @@ use crate::slice_from_ptr_mut;
// Utf8CString, Utf8CStrBufRef, and Utf8CStrBufArr<N> implements Utf8CStrWrite. // Utf8CString, Utf8CStrBufRef, and Utf8CStrBufArr<N> implements Utf8CStrWrite.
// Utf8CStrBufRef and Utf8CStrBufArr<N> implements Utf8CStrBuf. // Utf8CStrBufRef and Utf8CStrBufArr<N> implements Utf8CStrBuf.
pub fn copy_cstr<T: AsRef<CStr> + ?Sized>(dest: &mut [u8], src: &T) -> usize {
let src = src.as_ref().to_bytes_with_nul();
let len = min(src.len(), dest.len());
dest[..len].copy_from_slice(&src[..len]);
len - 1
}
fn utf8_cstr_buf_append(buf: &mut dyn Utf8CStrBuf, s: &[u8]) -> usize { fn utf8_cstr_buf_append(buf: &mut dyn Utf8CStrBuf, s: &[u8]) -> usize {
let mut used = buf.len(); let mut used = buf.len();
if used >= buf.capacity() - 1 { if used >= buf.capacity() - 1 {
@ -49,7 +42,9 @@ fn utf8_cstr_buf_append(buf: &mut dyn Utf8CStrBuf, s: &[u8]) -> usize {
} }
let dest = unsafe { &mut buf.mut_buf()[used..] }; let dest = unsafe { &mut buf.mut_buf()[used..] };
let len = min(s.len(), dest.len() - 1); let len = min(s.len(), dest.len() - 1);
dest[..len].copy_from_slice(&s[..len]); if len > 0 {
dest[..len].copy_from_slice(&s[..len]);
}
dest[len] = b'\0'; dest[len] = b'\0';
used += len; used += len;
unsafe { buf.set_len(used) }; unsafe { buf.set_len(used) };

View File

@ -5,7 +5,9 @@ use std::fs::File;
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write}; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write};
use std::ops::Deref; use std::ops::Deref;
use std::os::fd::{AsFd, BorrowedFd, IntoRawFd}; use std::os::fd::{AsFd, BorrowedFd, IntoRawFd};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd}; use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::path::Path;
use std::{io, mem, ptr, slice}; use std::{io, mem, ptr, slice};
use bytemuck::{bytes_of_mut, Pod}; use bytemuck::{bytes_of_mut, Pod};
@ -17,8 +19,8 @@ use num_traits::AsPrimitive;
use crate::cxx_extern::readlinkat_for_cxx; use crate::cxx_extern::readlinkat_for_cxx;
use crate::{ use crate::{
copy_cstr, cstr, errno, error, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrBuf, cstr, errno, error, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrBuf, Utf8CStrBufArr,
Utf8CStrBufArr, Utf8CStrWrite,
}; };
pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> io::Result<OwnedFd> { pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> io::Result<OwnedFd> {
@ -631,11 +633,14 @@ impl FsPath {
} }
pub fn mkdirs(&self, mode: mode_t) -> io::Result<()> { pub fn mkdirs(&self, mode: mode_t) -> io::Result<()> {
let mut buf = [0_u8; 4096]; if self.is_empty() {
let len = copy_cstr(&mut buf, self); return Ok(());
let buf = &mut buf[..len]; }
let mut arr = Utf8CStrBufArr::default();
arr.push_str(self);
let mut off = 1; let mut off = 1;
unsafe { unsafe {
let buf = arr.as_bytes_mut();
while let Some(p) = buf[off..].iter().position(|c| *c == b'/') { while let Some(p) = buf[off..].iter().position(|c| *c == b'/') {
buf[off + p] = b'\0'; buf[off + p] = b'\0';
if libc::mkdir(buf.as_ptr().cast(), mode) < 0 && *errno() != EEXIST { if libc::mkdir(buf.as_ptr().cast(), mode) < 0 && *errno() != EEXIST {