mirror of
https://gitee.com/openharmony/third_party_rust_nix
synced 2024-12-11 17:37:18 +00:00
Remove PATH_MAX
restriction from with_nix_path
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
This commit is contained in:
parent
15af9b6d81
commit
378a66dd18
@ -64,6 +64,9 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
Because of this change, you now need `use std::iter::Extend` to call `extend`
|
||||
on a `SigSet`.
|
||||
(#[1553](https://github.com/nix-rust/nix/pull/1553))
|
||||
- Removed the the `PATH_MAX` restriction from APIs accepting paths. Paths
|
||||
will now be allocated on the heap if they are too long. In addition, large
|
||||
instruction count improvements (~30x) were made to path handling.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
47
src/lib.rs
47
src/lib.rs
@ -156,19 +156,11 @@ feature! {
|
||||
#[allow(missing_docs)]
|
||||
pub mod unistd;
|
||||
|
||||
/*
|
||||
*
|
||||
* ===== Result / Error =====
|
||||
*
|
||||
*/
|
||||
|
||||
use libc::PATH_MAX;
|
||||
|
||||
use std::{ptr, result, slice};
|
||||
use std::ffi::{CStr, OsStr};
|
||||
use std::ffi::{CStr, CString, OsStr};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{ptr, result, slice};
|
||||
|
||||
use errno::Errno;
|
||||
|
||||
@ -242,12 +234,9 @@ impl NixPath for CStr {
|
||||
}
|
||||
|
||||
fn with_nix_path<T, F>(&self, f: F) -> Result<T>
|
||||
where F: FnOnce(&CStr) -> T {
|
||||
// Equivalence with the [u8] impl.
|
||||
if self.len() >= PATH_MAX as usize {
|
||||
return Err(Errno::ENAMETOOLONG)
|
||||
}
|
||||
|
||||
where
|
||||
F: FnOnce(&CStr) -> T,
|
||||
{
|
||||
Ok(f(self))
|
||||
}
|
||||
}
|
||||
@ -265,11 +254,19 @@ impl NixPath for [u8] {
|
||||
where
|
||||
F: FnOnce(&CStr) -> T,
|
||||
{
|
||||
if self.len() >= PATH_MAX as usize {
|
||||
return Err(Errno::ENAMETOOLONG);
|
||||
// The real PATH_MAX is typically 4096, but it's statistically unlikely to have a path
|
||||
// longer than ~300 bytes. See the the PR description to get stats for your own machine.
|
||||
// https://github.com/nix-rust/nix/pull/1656
|
||||
//
|
||||
// By being smaller than a memory page, we also avoid the compiler inserting a probe frame:
|
||||
// https://docs.rs/compiler_builtins/latest/compiler_builtins/probestack/index.html
|
||||
const MAX_STACK_ALLOCATION: usize = 1024;
|
||||
|
||||
if self.len() >= MAX_STACK_ALLOCATION {
|
||||
return with_nix_path_allocating(self, f);
|
||||
}
|
||||
|
||||
let mut buf = MaybeUninit::<[u8; PATH_MAX as usize]>::uninit();
|
||||
let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit();
|
||||
let buf_ptr = buf.as_mut_ptr() as *mut u8;
|
||||
|
||||
unsafe {
|
||||
@ -284,6 +281,18 @@ impl NixPath for [u8] {
|
||||
}
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn with_nix_path_allocating<T, F>(from: &[u8], f: F) -> Result<T>
|
||||
where
|
||||
F: FnOnce(&CStr) -> T,
|
||||
{
|
||||
match CString::new(from) {
|
||||
Ok(s) => Ok(f(&s)),
|
||||
Err(_) => Err(Errno::EINVAL),
|
||||
}
|
||||
}
|
||||
|
||||
impl NixPath for Path {
|
||||
fn is_empty(&self) -> bool {
|
||||
NixPath::is_empty(self.as_os_str())
|
||||
|
Loading…
Reference in New Issue
Block a user