vm/ospath module

This commit is contained in:
Jeong, YunWon authored and Jeong, YunWon committed 2024-04-19 13:25:19 +09:00
1 parent d57287b89b
commit c9c07a6bbc
10 files changed
+263 -246

No files matched your search

-4
View File
@@ -318,8 +318,6 @@ class TestRmTree(BaseTest, unittest.TestCase):
self.assertTrue(os.path.exists(dir3))
self.assertTrue(os.path.exists(file1))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_rmtree_errors_onerror(self):
# filename is guaranteed not to exist
filename = tempfile.mktemp(dir=self.mkdtemp())
@@ -352,8 +350,6 @@ class TestRmTree(BaseTest, unittest.TestCase):
self.assertIsInstance(errors[1][2][1], NotADirectoryError)
self.assertEqual(errors[1][2][1].filename, filename)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_rmtree_errors_onexc(self):
# filename is guaranteed not to exist
filename = tempfile.mktemp(dir=self.mkdtemp())
-6
View File
@@ -94,8 +94,6 @@ class UnicodeFileTests(unittest.TestCase):
"with bad filename in the exception: %a" %
(fn.__name__, filename, exc_filename))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_failures(self):
# Pass non-existing Unicode filenames all over the place.
for name in self.files:
@@ -113,8 +111,6 @@ class UnicodeFileTests(unittest.TestCase):
else:
_listdir_failure = NotADirectoryError
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_open(self):
for name in self.files:
f = open(name, 'wb')
@@ -127,8 +123,6 @@ class UnicodeFileTests(unittest.TestCase):
# NFD (a variant of Unicode NFD form). Normalize the filename to NFC, NFKC,
# NFKD in Python is useless, because darwin will normalize it later and so
# open(), os.stat(), etc. don't raise any exception.
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')
@unittest.skipIf(
support.is_emscripten or support.is_wasi,
+2 -1
View File
@@ -1,7 +1,8 @@
use crate::vm::{
builtins::PyListRef,
function::ArgSequence,
stdlib::{os::OsPath, posix},
ospath::OsPath,
stdlib::posix,
{PyObjectRef, PyResult, TryFromObject, VirtualMachine},
};
use nix::{errno::Errno, unistd};
+2
View File
@@ -60,6 +60,8 @@ pub mod import;
mod intern;
pub mod iter;
pub mod object;
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
pub mod ospath;
pub mod prelude;
pub mod protocol;
pub mod py_io;
+198
View File
@@ -0,0 +1,198 @@
use crate::{
builtins::PyBaseExceptionRef,
convert::{ToPyException, TryFromObject},
function::FsPath,
object::AsObject,
PyObjectRef, PyResult, VirtualMachine,
};
use std::path::{Path, PathBuf};
// path_ without allow_fd in CPython
#[derive(Clone)]
pub struct OsPath {
pub path: std::ffi::OsString,
pub(super) mode: OutputMode,
}
#[derive(Debug, Copy, Clone)]
pub(super) enum OutputMode {
String,
Bytes,
}
impl OutputMode {
pub(super) fn process_path(self, path: impl Into<PathBuf>, vm: &VirtualMachine) -> PyResult {
fn inner(mode: OutputMode, path: PathBuf, vm: &VirtualMachine) -> PyResult {
let path_as_string = |p: PathBuf| {
p.into_os_string().into_string().map_err(|_| {
vm.new_unicode_decode_error(
"Can't convert OS path to valid UTF-8 string".into(),
)
})
};
match mode {
OutputMode::String => path_as_string(path).map(|s| vm.ctx.new_str(s).into()),
OutputMode::Bytes => {
#[cfg(any(unix, target_os = "wasi"))]
{
use rustpython_common::os::ffi::OsStringExt;
Ok(vm.ctx.new_bytes(path.into_os_string().into_vec()).into())
}
#[cfg(windows)]
{
path_as_string(path).map(|s| vm.ctx.new_bytes(s.into_bytes()).into())
}
}
}
}
inner(self, path.into(), vm)
}
}
impl OsPath {
pub fn new_str(path: impl Into<std::ffi::OsString>) -> Self {
let path = path.into();
Self {
path,
mode: OutputMode::String,
}
}
pub(crate) fn from_fspath(fspath: FsPath, vm: &VirtualMachine) -> PyResult<OsPath> {
let path = fspath.as_os_str(vm)?.to_owned();
let mode = match fspath {
FsPath::Str(_) => OutputMode::String,
FsPath::Bytes(_) => OutputMode::Bytes,
};
Ok(OsPath { path, mode })
}
pub fn as_path(&self) -> &Path {
Path::new(&self.path)
}
pub fn into_bytes(self) -> Vec<u8> {
self.path.into_encoded_bytes()
}
pub fn to_string_lossy(&self) -> std::borrow::Cow<'_, str> {
self.path.to_string_lossy()
}
pub fn into_cstring(self, vm: &VirtualMachine) -> PyResult<std::ffi::CString> {
std::ffi::CString::new(self.into_bytes()).map_err(|err| err.to_pyexception(vm))
}
#[cfg(windows)]
pub fn to_widecstring(&self, vm: &VirtualMachine) -> PyResult<widestring::WideCString> {
widestring::WideCString::from_os_str(&self.path).map_err(|err| err.to_pyexception(vm))
}
pub fn filename(&self, vm: &VirtualMachine) -> PyResult {
self.mode.process_path(self.path.clone(), vm)
}
}
impl AsRef<Path> for OsPath {
fn as_ref(&self) -> &Path {
self.as_path()
}
}
impl TryFromObject for OsPath {
// TODO: path_converter with allow_fd=0 in CPython
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let fspath = FsPath::try_from(obj, true, vm)?;
Self::from_fspath(fspath, vm)
}
}
// path_t with allow_fd in CPython
#[derive(Clone)]
pub(crate) enum OsPathOrFd {
Path(OsPath),
Fd(i32),
}
impl TryFromObject for OsPathOrFd {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let r = match obj.try_index_opt(vm) {
Some(int) => Self::Fd(int?.try_to_primitive(vm)?),
None => Self::Path(obj.try_into_value(vm)?),
};
Ok(r)
}
}
impl From<OsPath> for OsPathOrFd {
fn from(path: OsPath) -> Self {
Self::Path(path)
}
}
impl OsPathOrFd {
pub fn filename(&self, vm: &VirtualMachine) -> PyObjectRef {
match self {
OsPathOrFd::Path(path) => path.filename(vm).unwrap_or_else(|_| vm.ctx.none()),
OsPathOrFd::Fd(fd) => vm.ctx.new_int(*fd).into(),
}
}
}
// TODO: preserve the input `PyObjectRef` of filename and filename2 (Failing check `self.assertIs(err.filename, name, str(func)`)
pub struct IOErrorBuilder<'a> {
error: &'a std::io::Error,
filename: Option<OsPathOrFd>,
filename2: Option<OsPathOrFd>,
}
impl<'a> IOErrorBuilder<'a> {
pub fn new(error: &'a std::io::Error) -> Self {
Self {
error,
filename: None,
filename2: None,
}
}
pub(crate) fn filename(mut self, filename: impl Into<OsPathOrFd>) -> Self {
let filename = filename.into();
self.filename.replace(filename);
self
}
pub(crate) fn filename2(mut self, filename: impl Into<OsPathOrFd>) -> Self {
let filename = filename.into();
self.filename2.replace(filename);
self
}
pub(crate) fn with_filename(
error: &'a std::io::Error,
filename: impl Into<OsPathOrFd>,
vm: &VirtualMachine,
) -> PyBaseExceptionRef {
let zelf = Self {
error,
filename: Some(filename.into()),
filename2: None,
};
zelf.to_pyexception(vm)
}
}
impl<'a> ToPyException for IOErrorBuilder<'a> {
fn to_pyexception(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
let excp = self.error.to_pyexception(vm);
if let Some(filename) = &self.filename {
excp.as_object()
.set_attr("filename", filename.filename(vm), vm)
.unwrap();
}
if let Some(filename2) = &self.filename2 {
excp.as_object()
.set_attr("filename2", filename2.filename(vm), vm)
.unwrap();
}
excp
}
}
+2 -2
View File
@@ -3570,7 +3570,7 @@ mod _io {
// check file descriptor validity
#[cfg(unix)]
if let Ok(crate::stdlib::os::OsPathOrFd::Fd(fd)) = file.clone().try_into_value(vm) {
if let Ok(crate::ospath::OsPathOrFd::Fd(fd)) = file.clone().try_into_value(vm) {
nix::fcntl::fcntl(fd, nix::fcntl::F_GETFD)
.map_err(|_| crate::stdlib::os::errno_err(vm))?;
}
@@ -3901,7 +3901,7 @@ mod fileio {
} else if let Some(i) = name.payload::<crate::builtins::PyInt>() {
i.try_to_primitive(vm)?
} else {
let path = os::OsPath::try_from_object(vm, name.clone())?;
let path = crate::ospath::OsPath::try_from_object(vm, name.clone())?;
if !args.closefd {
return Err(
vm.new_value_error("Cannot use closefd=False with file name".to_owned())
+2 -3
View File
@@ -18,9 +18,8 @@ pub(crate) mod module {
convert::ToPyException,
function::Either,
function::OptionalArg,
stdlib::os::{
errno_err, DirFd, FollowSymlinks, OsPath, SupportFunc, TargetIsDirectory, _os,
},
ospath::OsPath,
stdlib::os::{errno_err, DirFd, FollowSymlinks, SupportFunc, TargetIsDirectory, _os},
PyResult, TryFromObject, VirtualMachine,
};
use libc::intptr_t;
+40 -207
View File
@@ -1,97 +1,11 @@
use crate::{
builtins::{PyBaseExceptionRef, PyModule, PySet},
common::crt_fd::Fd,
convert::{IntoPyException, ToPyException},
function::{ArgumentError, FromArgs, FsPath, FuncArgs},
AsObject, Py, PyObjectRef, PyPayload, PyResult, TryFromObject, VirtualMachine,
convert::ToPyException,
function::{ArgumentError, FromArgs, FuncArgs},
AsObject, Py, PyPayload, PyResult, VirtualMachine,
};
use std::{
ffi, fs, io,
path::{Path, PathBuf},
};
#[derive(Debug, Copy, Clone)]
pub(super) enum OutputMode {
String,
Bytes,
}
impl OutputMode {
pub(super) fn process_path(self, path: impl Into<PathBuf>, vm: &VirtualMachine) -> PyResult {
fn inner(mode: OutputMode, path: PathBuf, vm: &VirtualMachine) -> PyResult {
let path_as_string = |p: PathBuf| {
p.into_os_string().into_string().map_err(|_| {
vm.new_unicode_decode_error(
"Can't convert OS path to valid UTF-8 string".into(),
)
})
};
match mode {
OutputMode::String => path_as_string(path).map(|s| vm.ctx.new_str(s).into()),
OutputMode::Bytes => {
#[cfg(any(unix, target_os = "wasi"))]
{
use rustpython_common::os::ffi::OsStringExt;
Ok(vm.ctx.new_bytes(path.into_os_string().into_vec()).into())
}
#[cfg(windows)]
{
path_as_string(path).map(|s| vm.ctx.new_bytes(s.into_bytes()).into())
}
}
}
}
inner(self, path.into(), vm)
}
}
// path_ without allow_fd in CPython
#[derive(Clone)]
pub struct OsPath {
pub path: ffi::OsString,
pub(super) mode: OutputMode,
}
impl OsPath {
pub fn new_str(path: impl Into<ffi::OsString>) -> Self {
let path = path.into();
Self {
path,
mode: OutputMode::String,
}
}
pub(crate) fn from_fspath(fspath: FsPath, vm: &VirtualMachine) -> PyResult<OsPath> {
let path = fspath.as_os_str(vm)?.to_owned();
let mode = match fspath {
FsPath::Str(_) => OutputMode::String,
FsPath::Bytes(_) => OutputMode::Bytes,
};
Ok(OsPath { path, mode })
}
pub fn as_path(&self) -> &Path {
Path::new(&self.path)
}
pub fn into_bytes(self) -> Vec<u8> {
self.path.into_encoded_bytes()
}
pub fn into_cstring(self, vm: &VirtualMachine) -> PyResult<ffi::CString> {
ffi::CString::new(self.into_bytes()).map_err(|err| err.into_pyexception(vm))
}
#[cfg(windows)]
pub fn to_widecstring(&self, vm: &VirtualMachine) -> PyResult<widestring::WideCString> {
widestring::WideCString::from_os_str(&self.path).map_err(|err| err.into_pyexception(vm))
}
pub fn filename(&self, vm: &VirtualMachine) -> PyResult {
self.mode.process_path(self.path.clone(), vm)
}
}
use std::{ffi, fs, io, path::Path};
pub(super) fn fs_metadata<P: AsRef<Path>>(
path: P,
@@ -104,104 +18,13 @@ pub(super) fn fs_metadata<P: AsRef<Path>>(
}
}
impl AsRef<Path> for OsPath {
fn as_ref(&self) -> &Path {
self.as_path()
}
}
impl TryFromObject for OsPath {
// TODO: path_converter with allow_fd=0 in CPython
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let fspath = FsPath::try_from(obj, true, vm)?;
Self::from_fspath(fspath, vm)
}
}
// path_t with allow_fd in CPython
#[derive(Clone)]
pub(crate) enum OsPathOrFd {
Path(OsPath),
Fd(i32),
}
impl TryFromObject for OsPathOrFd {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let r = match obj.try_index_opt(vm) {
Some(int) => Self::Fd(int?.try_to_primitive(vm)?),
None => Self::Path(obj.try_into_value(vm)?),
};
Ok(r)
}
}
impl From<OsPath> for OsPathOrFd {
fn from(path: OsPath) -> Self {
Self::Path(path)
}
}
impl OsPathOrFd {
pub fn filename(&self, vm: &VirtualMachine) -> PyObjectRef {
match self {
OsPathOrFd::Path(path) => path.filename(vm).unwrap_or_else(|_| vm.ctx.none()),
OsPathOrFd::Fd(fd) => vm.ctx.new_int(*fd).into(),
}
}
}
#[cfg(unix)]
impl IntoPyException for nix::Error {
impl crate::convert::IntoPyException for nix::Error {
fn into_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
io::Error::from(self).into_pyexception(vm)
}
}
// TODO: preserve the input `PyObjectRef` of filename and filename2 (Failing check `self.assertIs(err.filename, name, str(func)`)
pub struct IOErrorBuilder {
error: io::Error,
filename: Option<OsPathOrFd>,
filename2: Option<OsPathOrFd>,
}
impl IOErrorBuilder {
pub fn new(error: io::Error) -> Self {
Self {
error,
filename: None,
filename2: None,
}
}
pub(crate) fn filename(mut self, filename: impl Into<OsPathOrFd>) -> Self {
let filename = filename.into();
self.filename.replace(filename);
self
}
pub(crate) fn filename2(mut self, filename: impl Into<OsPathOrFd>) -> Self {
let filename = filename.into();
self.filename2.replace(filename);
self
}
}
impl IntoPyException for IOErrorBuilder {
fn into_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
let excp = self.error.into_pyexception(vm);
if let Some(filename) = self.filename {
excp.as_object()
.set_attr("filename", filename.filename(vm), vm)
.unwrap();
}
if let Some(filename2) = self.filename2 {
excp.as_object()
.set_attr("filename2", filename2.filename(vm), vm)
.unwrap();
}
excp
}
}
/// Convert the error stored in the `errno` variable into an Exception
#[inline]
pub fn errno_err(vm: &VirtualMachine) -> PyBaseExceptionRef {
@@ -295,10 +118,7 @@ fn bytes_as_osstr<'a>(b: &'a [u8], vm: &VirtualMachine) -> PyResult<&'a ffi::OsS
#[pymodule(sub)]
pub(super) mod _os {
use super::{
errno_err, DirFd, FollowSymlinks, IOErrorBuilder, OsPath, OsPathOrFd, OutputMode,
SupportFunc,
};
use super::{errno_err, DirFd, FollowSymlinks, SupportFunc};
use crate::{
builtins::{
PyBytesRef, PyGenericAlias, PyIntRef, PyStrRef, PyTuple, PyTupleRef, PyTypeRef,
@@ -308,6 +128,7 @@ pub(super) mod _os {
common::suppress_iph,
convert::{IntoPyException, ToPyObject},
function::{ArgBytesLike, Either, FsPath, FuncArgs, OptionalArg},
ospath::{IOErrorBuilder, OsPath, OsPathOrFd, OutputMode},
protocol::PyIterReturn,
recursion::ReprGuard,
types::{IterNext, Iterable, PyStructSequence, Representable, SelfIter},
@@ -407,7 +228,7 @@ pub(super) mod _os {
}
};
fd.map(|fd| fd.0)
.map_err(|e| IOErrorBuilder::new(e).filename(name).into_pyexception(vm))
.map_err(|err| IOErrorBuilder::with_filename(&err, name, vm))
}
#[pyfunction]
@@ -449,7 +270,7 @@ pub(super) mod _os {
} else {
fs::remove_file(&path)
};
res.map_err(|e| IOErrorBuilder::new(e).filename(path).into_pyexception(vm))
res.map_err(|err| IOErrorBuilder::with_filename(&err, path, vm))
}
#[cfg(not(windows))]
@@ -486,8 +307,7 @@ pub(super) mod _os {
#[pyfunction]
fn rmdir(path: OsPath, dir_fd: DirFd<0>, vm: &VirtualMachine) -> PyResult<()> {
let [] = dir_fd.0;
fs::remove_dir(&path)
.map_err(|e| IOErrorBuilder::new(e).filename(path).into_pyexception(vm))
fs::remove_dir(&path).map_err(|err| IOErrorBuilder::with_filename(&err, path, vm))
}
const LISTDIR_FD: bool = cfg!(all(unix, not(target_os = "redox")));
@@ -497,13 +317,16 @@ pub(super) mod _os {
let path = path.unwrap_or_else(|| OsPathOrFd::Path(OsPath::new_str(".")));
let list = match path {
OsPathOrFd::Path(path) => {
let dir_iter = fs::read_dir(&path).map_err(|err| err.into_pyexception(vm))?;
let dir_iter = match fs::read_dir(&path) {
Ok(iter) => iter,
Err(err) => {
return Err(IOErrorBuilder::with_filename(&err, path, vm));
}
};
dir_iter
.map(|entry| match entry {
Ok(entry_path) => path.mode.process_path(entry_path.file_name(), vm),
Err(e) => Err(IOErrorBuilder::new(e)
.filename(path.clone())
.into_pyexception(vm)),
Err(err) => Err(IOErrorBuilder::with_filename(&err, path.clone(), vm)),
})
.collect::<PyResult<_>>()?
}
@@ -593,8 +416,8 @@ pub(super) mod _os {
fn readlink(path: OsPath, dir_fd: DirFd<0>, vm: &VirtualMachine) -> PyResult {
let mode = path.mode;
let [] = dir_fd.0;
let path = fs::read_link(&path)
.map_err(|err| IOErrorBuilder::new(err).filename(path).into_pyexception(vm))?;
let path =
fs::read_link(&path).map_err(|err| IOErrorBuilder::with_filename(&err, path, vm))?;
mode.process_path(path, vm)
}
@@ -861,7 +684,8 @@ pub(super) mod _os {
#[pyfunction]
fn scandir(path: OptionalArg<OsPath>, vm: &VirtualMachine) -> PyResult {
let path = path.unwrap_or_else(|| OsPath::new_str("."));
let entries = fs::read_dir(path.path).map_err(|err| err.into_pyexception(vm))?;
let entries = fs::read_dir(&path.path)
.map_err(|err| IOErrorBuilder::with_filename(&err, path.clone(), vm))?;
Ok(ScandirIterator {
entries: PyRwLock::new(Some(entries)),
mode: path.mode,
@@ -1113,7 +937,7 @@ pub(super) mod _os {
vm: &VirtualMachine,
) -> PyResult {
let stat = stat_inner(file.clone(), dir_fd, follow_symlinks)
.map_err(|e| IOErrorBuilder::new(e).filename(file).into_pyexception(vm))?
.map_err(|err| IOErrorBuilder::with_filename(&err, file, vm))?
.ok_or_else(|| crate::exceptions::cstring_error(vm))?;
Ok(StatResult::from_stat(&stat, vm).to_pyobject(vm))
}
@@ -1144,7 +968,7 @@ pub(super) mod _os {
#[pyfunction]
fn chdir(path: OsPath, vm: &VirtualMachine) -> PyResult<()> {
env::set_current_dir(&path.path)
.map_err(|err| IOErrorBuilder::new(err).filename(path).into_pyexception(vm))
.map_err(|err| IOErrorBuilder::with_filename(&err, path, vm))
}
#[pyfunction]
@@ -1156,7 +980,7 @@ pub(super) mod _os {
#[pyfunction(name = "replace")]
fn rename(src: OsPath, dst: OsPath, vm: &VirtualMachine) -> PyResult<()> {
fs::rename(&src.path, &dst.path).map_err(|err| {
IOErrorBuilder::new(err)
IOErrorBuilder::new(&err)
.filename(src)
.filename2(dst)
.into_pyexception(vm)
@@ -1238,7 +1062,7 @@ pub(super) mod _os {
#[pyfunction]
fn link(src: OsPath, dst: OsPath, vm: &VirtualMachine) -> PyResult<()> {
fs::hard_link(&src.path, &dst.path).map_err(|err| {
IOErrorBuilder::new(err)
IOErrorBuilder::new(&err)
.filename(src)
.filename2(dst)
.into_pyexception(vm)
@@ -1552,14 +1376,23 @@ pub(super) mod _os {
if let Ok(fd) = path.try_to_value(vm) {
return ftruncate(fd, length, vm);
}
#[cold]
fn error(
vm: &VirtualMachine,
error: std::io::Error,
path: OsPath,
) -> crate::builtins::PyBaseExceptionRef {
IOErrorBuilder::with_filename(&error, path, vm)
}
let path = OsPath::try_from_object(vm, path)?;
// TODO: just call libc::truncate() on POSIX
let f = OpenOptions::new()
.write(true)
.open(path)
.map_err(|e| e.into_pyexception(vm))?;
f.set_len(length as u64)
.map_err(|e| e.into_pyexception(vm))?;
let f = match OpenOptions::new().write(true).open(&path) {
Ok(f) => f,
Err(e) => return Err(error(vm, e, path)),
};
f.set_len(length as u64).map_err(|e| error(vm, e, path))?;
drop(f);
Ok(())
}
+15 -22
View File
@@ -24,9 +24,9 @@ pub mod module {
builtins::{PyDictRef, PyInt, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
convert::{IntoPyException, ToPyObject, TryFromObject},
function::{Either, KwArgs, OptionalArg},
ospath::{IOErrorBuilder, OsPath, OsPathOrFd},
stdlib::os::{
errno_err, DirFd, FollowSymlinks, OsPath, OsPathOrFd, SupportFunc, TargetIsDirectory,
_os, fs_metadata, IOErrorBuilder,
errno_err, DirFd, FollowSymlinks, SupportFunc, TargetIsDirectory, _os, fs_metadata,
},
types::{Constructor, Representable},
utils::ToCString,
@@ -279,14 +279,15 @@ pub mod module {
)
})?;
let metadata = fs::metadata(path.path);
let metadata = fs::metadata(path.path.clone());
// if it's only checking for F_OK
if flags == AccessFlags::F_OK {
return Ok(metadata.is_ok());
}
let metadata = metadata.map_err(|err| err.into_pyexception(vm))?;
let metadata =
metadata.map_err(|err| IOErrorBuilder::with_filename(&err, path.clone(), vm))?;
let user_id = metadata.uid();
let group_id = metadata.gid();
@@ -356,13 +357,12 @@ pub mod module {
#[cfg(not(target_os = "redox"))]
#[pyfunction]
fn chroot(path: OsPath, vm: &VirtualMachine) -> PyResult<()> {
use crate::stdlib::os::IOErrorBuilder;
use crate::ospath::IOErrorBuilder;
nix::unistd::chroot(&*path.path).map_err(|err| {
// Use `From<nix::Error> for io::Error` when it is available
IOErrorBuilder::new(io::Error::from_raw_os_error(err as i32))
.filename(path)
.into_pyexception(vm)
let err = io::Error::from_raw_os_error(err as i32);
IOErrorBuilder::with_filename(&err, path, vm)
})
}
@@ -408,9 +408,8 @@ pub mod module {
}
.map_err(|err| {
// Use `From<nix::Error> for io::Error` when it is available
IOErrorBuilder::new(io::Error::from_raw_os_error(err as i32))
.filename(path)
.into_pyexception(vm)
let err = io::Error::from_raw_os_error(err as i32);
IOErrorBuilder::with_filename(&err, path, vm)
})
}
@@ -919,11 +918,7 @@ pub mod module {
permissions.set_mode(mode);
fs::set_permissions(&path, permissions)
};
body().map_err(|err| {
IOErrorBuilder::new(err)
.filename(err_path)
.into_pyexception(vm)
})
body().map_err(|err| IOErrorBuilder::with_filename(&err, err_path, vm))
}
#[cfg(not(target_os = "redox"))]
@@ -1474,9 +1469,8 @@ pub mod module {
}
};
if ret != 0 {
return Err(IOErrorBuilder::new(std::io::Error::from_raw_os_error(ret))
.filename(self.path)
.into_pyexception(vm));
let err = std::io::Error::from_raw_os_error(ret);
return Err(IOErrorBuilder::with_filename(&err, self.path, vm));
}
}
}
@@ -1548,9 +1542,8 @@ pub mod module {
if ret == 0 {
Ok(pid)
} else {
Err(IOErrorBuilder::new(std::io::Error::from_raw_os_error(ret))
.filename(self.path)
.into_pyexception(vm))
let err = std::io::Error::from_raw_os_error(ret);
Err(IOErrorBuilder::with_filename(&err, self.path, vm))
}
}
}
+2 -1
View File
@@ -11,7 +11,8 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
pub(crate) mod module {
use crate::{
builtins::PyStrRef,
stdlib::os::{DirFd, OsPath, SupportFunc, TargetIsDirectory, _os},
ospath::OsPath,
stdlib::os::{DirFd, SupportFunc, TargetIsDirectory, _os},
PyObjectRef, PyResult, VirtualMachine,
};
use std::env;