Skip to content

Commit 696b57b

Browse files
host_env: rustix for unlinkat, fix clippy deny (#8591)
Like the other patches, this greatly simplifies our unlinkat code and is overall nicer because it uses the syscall directly on Linux. As an added benefit, this commit adds WASI support and fixes a clippy deny. The old code caused clippy to complain that the WASI branch bypassed host_env for remove/unlink.
1 parent abf6785 commit 696b57b

5 files changed

Lines changed: 26 additions & 22 deletions

File tree

‎crates/host_env/src/posix.rs‎

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,6 @@ pub fn chroot(path: &Path) -> std::io::Result<()> {
143143
nix::unistd::chroot(path).map_err(std::io::Error::from)
144144
}
145145

146-
#[cfg(not(target_os = "redox"))]
147-
pub fn unlinkat(dir_fd: i32, path: &CStr) -> std::io::Result<()> {
148-
let ret = unsafe { libc::unlinkat(dir_fd, path.as_ptr(), 0) };
149-
if ret < 0 {
150-
Err(std::io::Error::last_os_error())
151-
} else {
152-
Ok(())
153-
}
154-
}
155-
156146
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd"))]
157147
pub fn lchmod(path: &CStr, mode: libc::mode_t) -> std::io::Result<()> {
158148
unsafe extern "C" {

‎crates/host_env/src/posix_unix_like.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,8 @@ pub fn stat_path(
6464
.map(Option::Some)
6565
.map_err(Into::into)
6666
}
67+
68+
pub fn unlinkat(dir_fd: Option<crt_fd::Borrowed<'_>>, path: impl AsRef<Path>) -> io::Result<()> {
69+
let dir_fd = dir_fd.as_ref().map_or(fs::CWD, AsFd::as_fd);
70+
fs::unlinkat(dir_fd, path.as_ref(), AtFlags::empty()).map_err(Into::into)
71+
}

‎crates/vm/src/stdlib/os.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ pub(super) mod _os {
229229
const STAT_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
230230
const UTIME_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
231231
pub(crate) const SYMLINK_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
232-
pub(crate) const UNLINK_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
232+
pub(crate) const UNLINK_DIR_FD: bool = cfg!(not(windows));
233233
const RENAME_DIR_FD: bool = cfg!(any(unix, target_os = "wasi"));
234234
const RMDIR_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
235235
const SCANDIR_FD: bool = cfg!(all(unix, not(target_os = "redox")));

‎crates/vm/src/stdlib/posix.rs‎

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,15 +440,7 @@ pub mod module {
440440
dir_fd: DirFd<'_, { _os::UNLINK_DIR_FD as usize }>,
441441
vm: &VirtualMachine,
442442
) -> PyResult<()> {
443-
#[cfg(not(target_os = "redox"))]
444-
if let Some(fd) = dir_fd.raw_opt() {
445-
let c_path = path.clone().into_cstring(vm)?;
446-
return rustpython_host_env::posix::unlinkat(fd, &c_path)
447-
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm));
448-
}
449-
#[cfg(target_os = "redox")]
450-
let [] = dir_fd.0;
451-
crate::host_env::fs::remove_file(&path)
443+
rustpython_host_env::posix::unlinkat(dir_fd.get_opt(), &path)
452444
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm))
453445
}
454446

‎crates/vm/src/stdlib/posix_compat.rs‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,34 @@ pub(crate) mod module {
99
use crate::{
1010
Py, PyObjectRef, PyResult, VirtualMachine,
1111
builtins::PyStrRef,
12-
convert::IntoPyException,
1312
ospath::OsPath,
1413
stdlib::os::{_os, DirFd, SupportFunc, TargetIsDirectory},
1514
};
16-
use std::fs;
15+
16+
#[cfg(not(target_os = "wasi"))]
17+
use {crate::convert::IntoPyException, std::fs};
18+
19+
#[cfg(target_os = "wasi")]
20+
use crate::exceptions::OSErrorBuilder;
1721

1822
#[pyfunction]
1923
pub(super) fn access(_path: PyStrRef, _mode: u8, vm: &VirtualMachine) -> PyResult<bool> {
2024
os_unimpl("os.access", vm)
2125
}
2226

27+
#[cfg(target_os = "wasi")]
28+
#[pyfunction]
29+
#[pyfunction(name = "unlink")]
30+
fn remove(
31+
path: OsPath,
32+
dir_fd: DirFd<'_, { _os::UNLINK_DIR_FD as usize }>,
33+
vm: &VirtualMachine,
34+
) -> PyResult<()> {
35+
rustpython_host_env::posix::unlinkat(dir_fd.get_opt(), &path)
36+
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm))
37+
}
38+
39+
#[cfg(not(target_os = "wasi"))]
2340
#[pyfunction]
2441
#[pyfunction(name = "unlink")]
2542
fn remove(path: OsPath, dir_fd: DirFd<'_, 0>, vm: &VirtualMachine) -> PyResult<()> {

0 commit comments

Comments
 (0)