Skip to content

Commit b382d3c

Browse files
committed
Move crt_fd to common
1 parent abdb04f commit b382d3c

File tree

11 files changed

+113
-101
lines changed

11 files changed

+113
-101
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ radium = "0.7"
2424
libc = "0.2.101"
2525
ascii = "1.0"
2626
unic-ucd-category = "0.9"
27+
28+
[target.'cfg(windows)'.dependencies]
29+
widestring = "0.5.1"

vm/src/crt_fd.rs renamed to common/src/crt_fd.rs

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! A module implementing an io type backed by the C runtime's file descriptors, i.e. what's
22
//! returned from libc::open, even on windows.
33
4-
use crate::suppress_iph;
5-
use std::{cmp, ffi, fs, io, mem};
4+
use std::{cmp, ffi, io};
65

76
#[cfg(windows)]
87
use libc::commit as fsync;
@@ -21,10 +20,31 @@ pub type Offset = libc::off_t;
2120
#[cfg(windows)]
2221
pub type Offset = libc::c_longlong;
2322

23+
// copied from stdlib::os
24+
#[cfg(windows)]
25+
fn errno() -> io::Error {
26+
let err = io::Error::last_os_error();
27+
// FIXME: probably not ideal, we need a bigger dichotomy between GetLastError and errno
28+
if err.raw_os_error() == Some(0) {
29+
extern "C" {
30+
fn _get_errno(pValue: *mut i32) -> i32;
31+
}
32+
let mut e = 0;
33+
unsafe { suppress_iph!(_get_errno(&mut e)) };
34+
io::Error::from_raw_os_error(e)
35+
} else {
36+
err
37+
}
38+
}
39+
#[cfg(not(windows))]
40+
fn errno() -> io::Error {
41+
io::Error::last_os_error()
42+
}
43+
2444
#[inline]
2545
fn cvt<T, I: num_traits::PrimInt>(ret: I, f: impl FnOnce(I) -> T) -> io::Result<T> {
2646
if ret < I::zero() {
27-
Err(crate::stdlib::os::errno())
47+
Err(errno())
2848
} else {
2949
Ok(f(ret))
3050
}
@@ -73,50 +93,16 @@ impl Fd {
7393
cvt(unsafe { suppress_iph!(ftruncate(self.0, len)) }, drop)
7494
}
7595

76-
/// NOTE: it's not recommended to use ManuallyDrop::into_inner() to drop the file - it won't
77-
/// work on all platforms, and will swallow any errors you might want to handle.
78-
#[allow(unused)] // only used on windows atm
79-
pub(crate) fn as_rust_file(&self) -> io::Result<mem::ManuallyDrop<fs::File>> {
80-
#[cfg(windows)]
81-
let file = {
82-
use std::os::windows::io::FromRawHandle;
83-
let handle = self.to_raw_handle()?;
84-
unsafe { fs::File::from_raw_handle(handle) }
85-
};
86-
#[cfg(unix)]
87-
let file = {
88-
let fd = self.0;
89-
use std::os::unix::io::FromRawFd;
90-
if fd < 0 {
91-
return Err(io::Error::from_raw_os_error(libc::EBADF));
92-
}
93-
unsafe { fs::File::from_raw_fd(fd) }
94-
};
95-
#[cfg(target_os = "wasi")]
96-
let file = {
97-
let fd = self.0;
98-
if fd < 0 {
99-
return Err(io::Error::from_raw_os_error(libc::EBADF));
100-
}
101-
// SAFETY: as of now, File is a wrapper around WasiFd, which is a wrapper around
102-
// wasi::Fd (u32). This isn't likely to change, and if it does change to a different
103-
// sized integer, mem::transmute will fail.
104-
unsafe { mem::transmute::<u32, fs::File>(fd as u32) }
105-
};
106-
Ok(mem::ManuallyDrop::new(file))
107-
}
108-
10996
#[cfg(windows)]
110-
pub(crate) fn to_raw_handle(&self) -> io::Result<std::os::windows::io::RawHandle> {
111-
use winapi::um::{handleapi::INVALID_HANDLE_VALUE, winnt::HANDLE};
97+
pub fn to_raw_handle(&self) -> io::Result<std::os::windows::io::RawHandle> {
11298
extern "C" {
11399
fn _get_osfhandle(fd: i32) -> libc::intptr_t;
114100
}
115-
let handle = unsafe { suppress_iph!(_get_osfhandle(self.0)) } as HANDLE;
116-
if handle == INVALID_HANDLE_VALUE {
101+
let handle = unsafe { suppress_iph!(_get_osfhandle(self.0)) };
102+
if handle == -1 {
117103
Err(io::Error::last_os_error())
118104
} else {
119-
Ok(handle)
105+
Ok(handle as _)
120106
}
121107
}
122108
}

common/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
//! A crate to hold types and functions common to all rustpython components.
22
3+
#[macro_use]
4+
mod macros;
5+
pub use macros::*;
6+
37
pub mod atomic;
48
pub mod borrow;
59
pub mod boxvec;
610
pub mod bytes;
711
pub mod char;
812
pub mod cmp;
13+
#[cfg(any(unix, windows, target_os = "wasi"))]
14+
pub mod crt_fd;
915
pub mod encodings;
1016
pub mod float_ops;
1117
pub mod hash;

common/src/macros.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/// Suppress the MSVC invalid parameter handler, which by default crashes the process. Does nothing
2+
/// on non-MSVC targets.
3+
#[macro_export]
4+
macro_rules! suppress_iph {
5+
($e:expr) => {
6+
$crate::__suppress_iph_impl!($e)
7+
};
8+
}
9+
10+
#[macro_export]
11+
#[doc(hidden)]
12+
#[cfg(all(windows, target_env = "msvc"))]
13+
macro_rules! __suppress_iph_impl {
14+
($e:expr) => {{
15+
let old = $crate::__macro_private::_set_thread_local_invalid_parameter_handler(
16+
$crate::__macro_private::silent_iph_handler,
17+
);
18+
let ret = $e;
19+
$crate::__macro_private::_set_thread_local_invalid_parameter_handler(old);
20+
ret
21+
}};
22+
}
23+
24+
#[cfg(not(all(windows, target_env = "msvc")))]
25+
#[macro_export]
26+
#[doc(hidden)]
27+
macro_rules! __suppress_iph_impl {
28+
($e:expr) => {
29+
$e
30+
};
31+
}
32+
33+
#[doc(hidden)]
34+
pub mod __macro_private {
35+
#[cfg(target_env = "msvc")]
36+
type InvalidParamHandler = extern "C" fn(
37+
*const libc::wchar_t,
38+
*const libc::wchar_t,
39+
*const libc::wchar_t,
40+
libc::c_uint,
41+
libc::uintptr_t,
42+
);
43+
#[cfg(target_env = "msvc")]
44+
extern "C" {
45+
pub fn _set_thread_local_invalid_parameter_handler(
46+
pNew: InvalidParamHandler,
47+
) -> InvalidParamHandler;
48+
}
49+
50+
#[cfg(target_env = "msvc")]
51+
pub extern "C" fn silent_iph_handler(
52+
_: *const libc::wchar_t,
53+
_: *const libc::wchar_t,
54+
_: *const libc::wchar_t,
55+
_: libc::c_uint,
56+
_: libc::uintptr_t,
57+
) {
58+
}
59+
}

vm/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ pub mod class;
4747
mod codecs;
4848
pub mod convert;
4949
mod coroutine;
50-
#[cfg(any(unix, windows, target_os = "wasi"))]
51-
mod crt_fd;
5250
mod dictdatatype;
5351
#[cfg(feature = "rustpython-compiler")]
5452
pub mod eval;

vm/src/stdlib/io.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
cfg_if::cfg_if! {
55
if #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] {
6-
use crate::crt_fd::Offset;
6+
use crate::common::crt_fd::Offset;
77
} else {
88
type Offset = i64;
99
}
@@ -3695,8 +3695,8 @@ mod fileio {
36953695
use super::{Offset, _io::*};
36963696
use crate::{
36973697
builtins::{PyStr, PyStrRef},
3698+
common::crt_fd::Fd,
36983699
convert::ToPyException,
3699-
crt_fd::Fd,
37003700
function::{ArgBytesLike, ArgMemoryBuffer, OptionalArg, OptionalOption},
37013701
stdlib::os,
37023702
types::{DefaultConstructor, Initializer},

vm/src/stdlib/msvcrt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ pub use msvcrt::*;
44
mod msvcrt {
55
use crate::{
66
builtins::{PyBytes, PyStrRef},
7+
common::suppress_iph,
78
stdlib::os::errno_err,
8-
suppress_iph, PyRef, PyResult, VirtualMachine,
9+
PyRef, PyResult, VirtualMachine,
910
};
1011
use itertools::Itertools;
1112
use winapi::{

vm/src/stdlib/nt.rs

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef {
1212
pub(crate) mod module {
1313
use crate::{
1414
builtins::{PyStrRef, PyTupleRef},
15+
common::{crt_fd::Fd, suppress_iph},
1516
convert::ToPyException,
16-
crt_fd::Fd,
1717
function::Either,
1818
function::OptionalArg,
1919
stdlib::os::{
2020
errno_err, DirFd, FollowSymlinks, PyPathLike, SupportFunc, TargetIsDirectory, _os,
2121
errno,
2222
},
23-
suppress_iph, PyResult, TryFromObject, VirtualMachine,
23+
PyResult, TryFromObject, VirtualMachine,
2424
};
2525
use std::{env, fs, io};
2626

@@ -191,33 +191,6 @@ pub(crate) mod module {
191191
Ok(_os::PyTerminalSize { columns, lines })
192192
}
193193

194-
#[cfg(target_env = "msvc")]
195-
type InvalidParamHandler = extern "C" fn(
196-
*const libc::wchar_t,
197-
*const libc::wchar_t,
198-
*const libc::wchar_t,
199-
libc::c_uint,
200-
libc::uintptr_t,
201-
);
202-
#[cfg(target_env = "msvc")]
203-
extern "C" {
204-
#[doc(hidden)]
205-
pub fn _set_thread_local_invalid_parameter_handler(
206-
pNew: InvalidParamHandler,
207-
) -> InvalidParamHandler;
208-
}
209-
210-
#[cfg(target_env = "msvc")]
211-
#[doc(hidden)]
212-
pub extern "C" fn silent_iph_handler(
213-
_: *const libc::wchar_t,
214-
_: *const libc::wchar_t,
215-
_: *const libc::wchar_t,
216-
_: libc::c_uint,
217-
_: libc::uintptr_t,
218-
) {
219-
}
220-
221194
#[cfg(target_env = "msvc")]
222195
extern "C" {
223196
fn _wexecv(cmdname: *const u16, argv: *const *const u16) -> intptr_t;
@@ -409,19 +382,6 @@ pub(crate) mod module {
409382
}
410383
}
411384

412-
#[cfg(all(windows, target_env = "msvc"))]
413-
#[macro_export]
414-
macro_rules! suppress_iph {
415-
($e:expr) => {{
416-
let old = $crate::stdlib::nt::module::_set_thread_local_invalid_parameter_handler(
417-
$crate::stdlib::nt::module::silent_iph_handler,
418-
);
419-
let ret = $e;
420-
$crate::stdlib::nt::module::_set_thread_local_invalid_parameter_handler(old);
421-
ret
422-
}};
423-
}
424-
425385
pub fn init_winsock() {
426386
static WSA_INIT: parking_lot::Once = parking_lot::Once::new();
427387
WSA_INIT.call_once(|| unsafe {

vm/src/stdlib/os.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
builtins::{PyBaseExceptionRef, PyBytes, PyBytesRef, PyInt, PySet, PyStr, PyStrRef},
3+
common::crt_fd::Fd,
34
convert::{ToPyException, ToPyObject},
4-
crt_fd::Fd,
55
function::{ArgumentError, FromArgs, FuncArgs},
66
protocol::PyBuffer,
77
AsObject, PyObject, PyObjectRef, PyPayload, PyResult, TryFromBorrowedObject, TryFromObject,
@@ -408,13 +408,13 @@ pub(super) mod _os {
408408
builtins::{
409409
PyBytesRef, PyGenericAlias, PyIntRef, PyStrRef, PyTuple, PyTupleRef, PyTypeRef,
410410
},
411+
common::crt_fd::{Fd, Offset},
412+
common::suppress_iph,
411413
convert::{ToPyException, ToPyObject},
412-
crt_fd::{Fd, Offset},
413414
function::Either,
414415
function::{ArgBytesLike, FuncArgs, OptionalArg},
415416
protocol::PyIterReturn,
416417
recursion::ReprGuard,
417-
suppress_iph,
418418
types::{IterNext, IterNextIterable, PyStructSequence},
419419
vm::VirtualMachine,
420420
AsObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
@@ -1123,7 +1123,13 @@ pub(super) mod _os {
11231123
let [] = dir_fd.0;
11241124
let meta = match file {
11251125
PathOrFd::Path(path) => super::fs_metadata(&path, follow_symlinks.0)?,
1126-
PathOrFd::Fd(fno) => Fd(fno).as_rust_file()?.metadata()?,
1126+
PathOrFd::Fd(fno) => {
1127+
use std::os::windows::io::FromRawHandle;
1128+
let handle = Fd(fno).to_raw_handle()?;
1129+
let file =
1130+
std::mem::ManuallyDrop::new(unsafe { std::fs::File::from_raw_handle(handle) });
1131+
file.metadata()?
1132+
}
11271133
};
11281134
meta_to_stat(&meta).map(Some)
11291135
}
@@ -1825,11 +1831,3 @@ use super::posix as platform;
18251831
use super::nt as platform;
18261832

18271833
pub(crate) use platform::module::MODULE_NAME;
1828-
1829-
#[cfg(not(all(windows, target_env = "msvc")))]
1830-
#[macro_export]
1831-
macro_rules! suppress_iph {
1832-
($e:expr) => {
1833-
$e
1834-
};
1835-
}

vm/src/stdlib/posix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1897,7 +1897,7 @@ pub mod module {
18971897
struct SendFileArgs {
18981898
out_fd: i32,
18991899
in_fd: i32,
1900-
offset: crate::crt_fd::Offset,
1900+
offset: crate::common::crt_fd::Offset,
19011901
count: i64,
19021902
#[cfg(target_os = "macos")]
19031903
#[pyarg(any, optional)]

0 commit comments

Comments
 (0)