mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #2515 from deantvv/os-enhancement
Implement dir_fd in os.open
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -749,6 +749,16 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "filepath"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dd50318458226958db06f173610f54f01d26f0a9ccfa3d38bd60f70bc9939ff"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.2.0"
|
||||
@@ -1986,6 +1996,7 @@ dependencies = [
|
||||
"digest",
|
||||
"dns-lookup",
|
||||
"exitcode",
|
||||
"filepath",
|
||||
"flame",
|
||||
"flamer",
|
||||
"flate2",
|
||||
|
||||
@@ -149,5 +149,8 @@ features = [
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "macos", windows))'.dependencies]
|
||||
filepath = "0.1.1"
|
||||
|
||||
[build-dependencies]
|
||||
itertools = "0.9"
|
||||
|
||||
@@ -7,6 +7,8 @@ use std::time::{Duration, SystemTime};
|
||||
use std::{env, fs};
|
||||
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", windows))]
|
||||
use filepath::FilePath;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use super::errno::errors;
|
||||
@@ -161,11 +163,25 @@ fn make_path<'a>(
|
||||
vm: &VirtualMachine,
|
||||
path: &'a PyPathLike,
|
||||
dir_fd: &DirFd,
|
||||
) -> PyResult<&'a ffi::OsStr> {
|
||||
if dir_fd.0.is_some() {
|
||||
Err(vm.new_os_error("dir_fd not supported yet".to_owned()))
|
||||
} else {
|
||||
Ok(path.path.as_os_str())
|
||||
) -> PyResult<std::borrow::Cow<'a, ffi::OsStr>> {
|
||||
let path = &path.path;
|
||||
if dir_fd.0.is_none() || path.is_absolute() {
|
||||
return Ok(path.as_os_str().into());
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(target_os = "linux", target_os = "macos", windows))] {
|
||||
let dir_path = match rust_file(dir_fd.0.unwrap().into()).path() {
|
||||
Ok(dir_path) => dir_path,
|
||||
Err(_) => {
|
||||
return Err(vm.new_os_error(format!("Cannot determine path of dir_fd: {:?}", dir_fd.0)));
|
||||
}
|
||||
};
|
||||
let p: PathBuf = vec![dir_path, path.to_path_buf()].iter().collect();
|
||||
Ok(p.into_os_string().into())
|
||||
} else {
|
||||
return Err(vm.new_os_error("dir_fd not supported on wasi yet".to_owned()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +365,7 @@ mod _os {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<i64> {
|
||||
let fname = make_path(vm, &name, &dir_fd)?;
|
||||
if osstr_contains_nul(fname) {
|
||||
if osstr_contains_nul(&fname) {
|
||||
return Err(vm.new_value_error("embedded null character".to_owned()));
|
||||
}
|
||||
|
||||
@@ -504,14 +520,14 @@ mod _os {
|
||||
fn remove(path: PyPathLike, dir_fd: DirFd, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let path = make_path(vm, &path, &dir_fd)?;
|
||||
let is_junction = cfg!(windows)
|
||||
&& fs::symlink_metadata(path).map_or(false, |meta| {
|
||||
&& fs::symlink_metadata(&path).map_or(false, |meta| {
|
||||
let ty = meta.file_type();
|
||||
ty.is_dir() && ty.is_symlink()
|
||||
});
|
||||
let res = if is_junction {
|
||||
fs::remove_dir(path)
|
||||
fs::remove_dir(&path)
|
||||
} else {
|
||||
fs::remove_file(path)
|
||||
fs::remove_file(&path)
|
||||
};
|
||||
res.map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
@@ -1221,7 +1237,7 @@ mod _os {
|
||||
pub(super) fn support_funcs(vm: &VirtualMachine) -> Vec<SupportFunc> {
|
||||
let mut supports = super::platform::support_funcs(vm);
|
||||
supports.extend(vec![
|
||||
SupportFunc::new(vm, "open", open, None, Some(false), None),
|
||||
SupportFunc::new(vm, "open", open, None, Some(true), None),
|
||||
SupportFunc::new(
|
||||
vm,
|
||||
"access",
|
||||
@@ -1800,10 +1816,10 @@ mod posix {
|
||||
let path = make_path(vm, &path, &dir_fd)?;
|
||||
let body = move || {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let meta = fs_metadata(path, follow_symlinks.0)?;
|
||||
let meta = fs_metadata(&path, follow_symlinks.0)?;
|
||||
let mut permissions = meta.permissions();
|
||||
permissions.set_mode(mode);
|
||||
fs::set_permissions(path, permissions)
|
||||
fs::set_permissions(&path, permissions)
|
||||
};
|
||||
body().map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
@@ -2675,14 +2691,14 @@ mod nt {
|
||||
const S_IWRITE: u32 = 128;
|
||||
let path = make_path(vm, &path, &dir_fd)?;
|
||||
let metadata = if follow_symlinks.0 {
|
||||
fs::metadata(path)
|
||||
fs::metadata(&path)
|
||||
} else {
|
||||
fs::symlink_metadata(path)
|
||||
fs::symlink_metadata(&path)
|
||||
};
|
||||
let meta = metadata.map_err(|err| err.into_pyexception(vm))?;
|
||||
let mut permissions = meta.permissions();
|
||||
permissions.set_readonly(mode & S_IWRITE != 0);
|
||||
fs::set_permissions(path, permissions).map_err(|err| err.into_pyexception(vm))
|
||||
fs::set_permissions(&path, permissions).map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
|
||||
// cwait is available on MSVC only (according to CPython)
|
||||
|
||||
Reference in New Issue
Block a user