Skip to content

Commit 4c0d49d

Browse files
authored
Merge pull request RustPython#3658 from coolreader18/move-crt_fd
Move crt_fd to common
2 parents 74bb4b6 + 77495a2 commit 4c0d49d

File tree

13 files changed

+118
-120
lines changed

13 files changed

+118
-120
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"
Lines changed: 6 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;
@@ -24,7 +23,7 @@ pub type Offset = libc::c_longlong;
2423
#[inline]
2524
fn cvt<T, I: num_traits::PrimInt>(ret: I, f: impl FnOnce(I) -> T) -> io::Result<T> {
2625
if ret < I::zero() {
27-
Err(crate::stdlib::os::errno())
26+
Err(crate::os::errno())
2827
} else {
2928
Ok(f(ret))
3029
}
@@ -73,50 +72,16 @@ impl Fd {
7372
cvt(unsafe { suppress_iph!(ftruncate(self.0, len)) }, drop)
7473
}
7574

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-
10975
#[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};
76+
pub fn to_raw_handle(&self) -> io::Result<std::os::windows::io::RawHandle> {
11277
extern "C" {
11378
fn _get_osfhandle(fd: i32) -> libc::intptr_t;
11479
}
115-
let handle = unsafe { suppress_iph!(_get_osfhandle(self.0)) } as HANDLE;
116-
if handle == INVALID_HANDLE_VALUE {
80+
let handle = unsafe { suppress_iph!(_get_osfhandle(self.0)) };
81+
if handle == -1 {
11782
Err(io::Error::last_os_error())
11883
} else {
119-
Ok(handle)
84+
Ok(handle as _)
12085
}
12186
}
12287
}

common/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
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;
1218
pub mod linked_list;
1319
pub mod lock;
20+
pub mod os;
1421
pub mod rc;
1522
pub mod refcount;
1623
pub mod static_cell;

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+
}

common/src/os.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// TODO: we can move more os-specific bindings/interfaces from stdlib::{os, posix, nt} to here
2+
3+
use std::io;
4+
5+
#[cfg(windows)]
6+
pub fn errno() -> io::Error {
7+
let err = io::Error::last_os_error();
8+
// FIXME: probably not ideal, we need a bigger dichotomy between GetLastError and errno
9+
if err.raw_os_error() == Some(0) {
10+
extern "C" {
11+
fn _get_errno(pValue: *mut i32) -> i32;
12+
}
13+
let mut e = 0;
14+
unsafe { suppress_iph!(_get_errno(&mut e)) };
15+
io::Error::from_raw_os_error(e)
16+
} else {
17+
err
18+
}
19+
}
20+
#[cfg(not(windows))]
21+
pub fn errno() -> io::Error {
22+
io::Error::last_os_error()
23+
}

stdlib/src/socket.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1927,7 +1927,7 @@ mod _socket {
19271927
use winapi::um::winsock2::closesocket as close;
19281928
let ret = unsafe { close(x as _) };
19291929
if ret < 0 {
1930-
let err = crate::vm::stdlib::os::errno();
1930+
let err = crate::common::os::errno();
19311931
if err.raw_os_error() != Some(errcode!(ECONNRESET)) {
19321932
return Err(err.to_pyexception(vm));
19331933
}

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::{

0 commit comments

Comments
 (0)