Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions crates/host_env/src/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use std::os::fd::FromRawFd;
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, OwnedFd};
use std::path::Path;

use crate::crt_fd;

pub struct UnameInfo {
pub sysname: String,
pub nodename: String,
Expand Down Expand Up @@ -174,24 +176,32 @@ pub fn fcopyfile(in_fd: i32, out_fd: i32, flags: u32) -> std::io::Result<()> {
}
}

#[cfg(not(windows))]
pub fn make_dir(path: &CStr, mode: u32) -> std::io::Result<()> {
let ret = unsafe { libc::mkdir(path.as_ptr(), mode as _) };
if ret < 0 {
Err(std::io::Error::last_os_error())
#[cfg(not(unix))]
pub fn make_dir(
dir_fd: Option<crt_fd::Borrowed<'_>>,
path: &Path,
_mode: u32,
) -> std::io::Result<()> {
// TODO: On Windows, Python has an override if the mode is 0o700
if dir_fd.is_none() {
std::fs::create_dir(path)
} else {
Ok(())
core::hint::cold_path();
Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"mkdirat is not available on this platform",
))
}
}

#[cfg(all(not(windows), not(target_os = "redox")))]
pub fn make_dir_at(dir_fd: i32, path: &CStr, mode: u32) -> std::io::Result<()> {
let ret = unsafe { libc::mkdirat(dir_fd, path.as_ptr(), mode as _) };
if ret < 0 {
Err(std::io::Error::last_os_error())
} else {
Ok(())
}
#[cfg(unix)]
pub fn make_dir(
dir_fd: Option<crt_fd::Borrowed<'_>>,
path: &Path,
mode: u32,
) -> std::io::Result<()> {
let dir_fd = dir_fd.as_ref().map_or(rustix::fs::CWD, AsFd::as_fd);
rustix::fs::mkdirat(dir_fd, path, mode.into()).map_err(Into::into)
}

#[cfg(unix)]
Expand Down
20 changes: 10 additions & 10 deletions crates/host_env/src/posix_wasi.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use alloc::ffi::CString;
use core::{ffi::CStr, time::Duration};
use std::{ffi::OsStr, io};
use rustix::fd::AsFd;
use std::{ffi::OsStr, io, path::Path};

use crate::os::CheckLibcResult;
use crate::{crt_fd, os::CheckLibcResult};

pub fn make_dir(path: &CStr, mode: u32) -> io::Result<()> {
unsafe { libc::mkdir(path.as_ptr(), mode as _) }.check_libc_neg()?;
Ok(())
}

pub fn make_dir_at(dir_fd: i32, path: &CStr, mode: u32) -> io::Result<()> {
unsafe { libc::mkdirat(dir_fd, path.as_ptr(), mode as _) }.check_libc_neg()?;
Ok(())
pub fn make_dir(
dir_fd: Option<crt_fd::Borrowed<'_>>,
path: &Path,
mode: u32,
) -> std::io::Result<()> {
let dir_fd = dir_fd.as_ref().map_or(rustix::fs::CWD, AsFd::as_fd);
rustix::fs::mkdirat(dir_fd, path, mode.into()).map_err(Into::into)
}

pub fn remove_dir_at(dir_fd: i32, path: &CStr) -> io::Result<()> {
Expand Down
33 changes: 11 additions & 22 deletions crates/vm/src/stdlib/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct TargetIsDirectory {
}

cfg_select! {
all(any(unix, target_os = "wasi"), not(target_os = "redox")) => {
any(unix, target_os = "wasi") => {
use libc::AT_FDCWD;
}
_ => {
Expand Down Expand Up @@ -181,10 +181,14 @@ pub(super) mod _os {
use rustpython_host_env::nt as host_nt;
#[cfg(all(any(unix, target_os = "wasi"), not(target_os = "redox")))]
use rustpython_host_env::posix as host_posix;
use std::{fs, io, path::PathBuf, time::SystemTime};
use std::{
fs, io,
path::{Path, PathBuf},
time::SystemTime,
};

const OPEN_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
pub(crate) const MKDIR_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
pub(crate) const MKDIR_DIR_FD: bool = cfg!(any(unix, target_os = "wasi"));
const STAT_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
const UTIME_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
pub(crate) const SYMLINK_DIR_FD: bool = cfg!(not(any(windows, target_os = "redox")));
Expand Down Expand Up @@ -338,32 +342,17 @@ pub(super) mod _os {
}
}

#[cfg(not(windows))]
#[pyfunction]
fn mkdir(
path: OsPath,
mode: OptionalArg<i32>,
dir_fd: DirFd<'_, { MKDIR_DIR_FD as usize }>,
vm: &VirtualMachine,
) -> PyResult<()> {
let mode = mode.unwrap_or(0o777);
let c_path = path.clone().into_cstring(vm)?;
#[cfg(not(target_os = "redox"))]
if let Some(fd) = dir_fd.raw_opt() {
return if let Err(err) =
crate::host_env::posix::make_dir_at(fd, c_path.as_c_str(), mode as u32)
{
Err(OSErrorBuilder::with_filename(&err, path, vm))
} else {
Ok(())
};
}
#[cfg(target_os = "redox")]
let [] = dir_fd.0;
if let Err(err) = crate::host_env::posix::make_dir(c_path.as_c_str(), mode as u32) {
return Err(OSErrorBuilder::with_filename(&err, path, vm));
}
Ok(())
let mode = mode.unwrap_or(0o777) as u32;
let dir_fd = dir_fd.get_opt();
crate::host_env::posix::make_dir(dir_fd, Path::new(&path.path), mode)
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm))
}

#[pyfunction]
Expand Down
Loading