mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
more hostenv isolation (#7932)
* Move which crate dependency from vm to host_env
Add host_env::fs::which wrapper and update getpath.rs call site.
* Move readline module from vm to host_env
Move crates/vm/src/readline.rs to crates/host_env/src/readline.rs and
re-export it from rustpython_vm::readline. Move rustyline dependency
from vm to host_env. Drop the host_env feature gates on history I/O
inside the moved module.
* Move gethostname and mac_address dependencies from stdlib to host_env
Add host_env::socket::hostname and host_env::socket::mac_address
wrappers. Update _socket.gethostname and _uuid.get_node_id call sites.
* Re-export libc constants and types through host_env
Move direct libc constant and type references in stdlib (faulthandler,
fcntl, multiprocessing, posixshmem, select, syslog) to use host_env
re-exports. Replace libc::c_int and libc::c_uint in stdlib with
core::ffi equivalents.
* Re-export mmap libc constants through host_env
Move direct libc MADV_*, MAP_*, PROT_*, EOVERFLOW references in
stdlib::mmap to host_env::mmap re-exports. Replace libc::c_int with
core::ffi::c_int.
* Re-export locale and termios libc constants through host_env
Move direct libc LC_*, ABDAY_*, ABMON_*, TIOC*, FIO* and related
constants in stdlib::locale and stdlib::termios to host_env
re-exports. Replace libc::c_char in stdlib::locale and
stdlib::openssl::cert with core::ffi::c_char.
* Replace libc c-types and FILE wrappers in openssl with host_env
Replace libc::c_int, c_long, c_uchar, c_uint, c_ulong, c_void,
c_char in stdlib::openssl with core::ffi equivalents. Replace
libc::ENOENT with host_env::errno::errors::ENOENT. Add
host_env::fileutils::{CFile, fclose} and route the load_dh_params
fclose call and PEM_read_DHparams FILE pointer type through them.
* Fix Windows build: expose EOVERFLOW, SIGSEGV, SIGFPE on Windows
host_mmap::EOVERFLOW and host_faulthandler::{SIGSEGV, SIGFPE}
re-exports were gated to cfg(unix) but stdlib uses them from Windows
and platform-agnostic code paths.
* Re-export remaining libc types and constants through host_env
Move direct libc references in stdlib (resource, posixsubprocess,
grp, socket) to host_env re-exports. Replace libc::c_long,
libc::c_longlong, libc::c_char in stdlib::socket with core::ffi
equivalents. Add resource::{RLIMIT_*, RUSAGE_*, c_long, rlim_t,
rlimit, timeval}, posix::{c_char, pid_t}, grp::gid_t, and
socket::{AF_*, SOCK_STREAM, sa_family_t, socklen_t, sockaddr_*}
re-exports.
* Move socket2 and dns-lookup dependencies from stdlib to host_env
Re-export socket2 as host_env::socket::raw and dns-lookup as
host_env::socket::dns. Update _socket call sites to route through
host_env aliases.
* Move system-configuration dependency from stdlib to host_env
Re-export the macOS system-configuration crate as
host_env::system_configuration and update _scproxy call sites.
* Restrict CAN/ALG sockaddr structs to target_os linux
libc on Android (bionic) does not define sockaddr_can, so importing it
for target_os = "android" fails to compile. Keep AF_ALG/AF_CAN for both
linux and android, and gate sockaddr_alg/sockaddr_can to linux only.
Assisted-by: Claude
This commit is contained in:
1 parent
aeb0f5e00e
commit
fafd9c75df
39 files changed
+858
-541
No files matched your search
Generated
+301
-202
File diff suppressed because it is too large.
Load diff
@@ -27,6 +27,16 @@ rustix = { workspace = true }
|
||||
[target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies]
|
||||
num_cpus = "1.17.0"
|
||||
|
||||
[target.'cfg(not(any(target_os = "ios", target_os = "android", target_os = "windows", target_arch = "wasm32", target_os = "redox")))'.dependencies]
|
||||
mac_address = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
dns-lookup = { workspace = true }
|
||||
gethostname = { workspace = true }
|
||||
rustyline = { workspace = true }
|
||||
socket2 = { workspace = true, features = ["all"] }
|
||||
which = { workspace = true }
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "redox")))'.dependencies]
|
||||
termios = { workspace = true }
|
||||
|
||||
@@ -37,6 +47,9 @@ libloading = "0.9"
|
||||
[target.'cfg(all(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"), not(any(target_env = "musl", target_env = "sgx"))))'.dependencies]
|
||||
libffi = { workspace = true, features = ["system"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
system-configuration = { workspace = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
junction = { workspace = true }
|
||||
schannel = { workspace = true }
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
use alloc::vec::Vec;
|
||||
#[cfg(unix)]
|
||||
use parking_lot::Mutex;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use libc::{SA_NODEFER, c_int};
|
||||
pub use libc::{SIGFPE, SIGSEGV};
|
||||
#[cfg(windows)]
|
||||
use windows_sys::Win32::System::{
|
||||
Diagnostics::Debug::{
|
||||
|
||||
@@ -5,6 +5,32 @@ use std::os::fd::BorrowedFd;
|
||||
|
||||
use crate::os::CheckLibcResult;
|
||||
|
||||
pub use libc::{F_GETFD, F_GETFL, F_SETFD, F_SETFL, FD_CLOEXEC};
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
pub use libc::{F_DUPFD, F_DUPFD_CLOEXEC, F_GETLK, F_SETLK, F_SETLKW};
|
||||
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "redox")))]
|
||||
pub use libc::{F_GETOWN, F_RDLCK, F_SETOWN, F_UNLCK, F_WRLCK, LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN};
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
pub use libc::{F_FULLFSYNC, F_NOCACHE};
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub use libc::{F_DUP2FD, F_DUP2FD_CLOEXEC};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub use libc::{F_OFD_GETLK, F_OFD_SETLK, F_OFD_SETLKW};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
pub use libc::{
|
||||
F_ADD_SEALS, F_GET_SEALS, F_GETLEASE, F_GETPIPE_SZ, F_NOTIFY, F_SEAL_GROW, F_SEAL_SEAL,
|
||||
F_SEAL_SHRINK, F_SEAL_WRITE, F_SETLEASE, F_SETPIPE_SZ,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_vendor = "apple"))]
|
||||
pub use libc::F_GETPATH;
|
||||
|
||||
pub fn normalize_ioctl_request(request: i64) -> libc::c_ulong {
|
||||
(request as u32) as libc::c_ulong
|
||||
}
|
||||
|
||||
@@ -442,10 +442,22 @@ pub mod windows {
|
||||
}
|
||||
}
|
||||
|
||||
/// C `FILE *` handle as returned by [`fopen`] and consumed by [`fclose`].
|
||||
pub type CFile = libc::FILE;
|
||||
|
||||
/// Close a file opened with [`fopen`].
|
||||
///
|
||||
/// # Safety
|
||||
/// `fp` must be a non-null pointer returned by [`fopen`] and must not have been
|
||||
/// closed already.
|
||||
pub unsafe fn fclose(fp: *mut CFile) -> core::ffi::c_int {
|
||||
unsafe { libc::fclose(fp) }
|
||||
}
|
||||
|
||||
// _Py_fopen_obj in cpython (Python/fileutils.c:1757-1835)
|
||||
// Open a file using std::fs::File and convert to FILE*
|
||||
// Automatically handles path encoding and EINTR retries
|
||||
pub fn fopen(path: &std::path::Path, mode: &str) -> std::io::Result<*mut libc::FILE> {
|
||||
pub fn fopen(path: &std::path::Path, mode: &str) -> std::io::Result<*mut CFile> {
|
||||
use alloc::ffi::CString;
|
||||
use std::fs::File;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{
|
||||
fs::{self, File, Metadata, ReadDir},
|
||||
io,
|
||||
path::Path,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
pub fn open(path: impl AsRef<Path>) -> io::Result<File> {
|
||||
@@ -44,10 +44,16 @@ pub fn open_write(path: impl AsRef<Path>) -> io::Result<File> {
|
||||
fs::OpenOptions::new().write(true).open(path)
|
||||
}
|
||||
|
||||
pub fn canonicalize(path: impl AsRef<Path>) -> io::Result<std::path::PathBuf> {
|
||||
pub fn canonicalize(path: impl AsRef<Path>) -> io::Result<PathBuf> {
|
||||
fs::canonicalize(path)
|
||||
}
|
||||
|
||||
/// Resolve `binary_name` to an absolute path by searching `PATH` (and `PATHEXT` on Windows).
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn which<T: AsRef<std::ffi::OsStr>>(binary_name: T) -> Option<PathBuf> {
|
||||
::which::which(binary_name).ok()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn open_write_with_custom_flags(path: impl AsRef<Path>, flags: u32) -> io::Result<File> {
|
||||
use std::os::windows::fs::OpenOptionsExt;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::io;
|
||||
|
||||
pub use libc::gid_t;
|
||||
|
||||
pub struct Group {
|
||||
pub name: String,
|
||||
pub passwd: String,
|
||||
|
||||
@@ -30,6 +30,7 @@ pub mod fileutils;
|
||||
pub mod fs;
|
||||
#[cfg(any(unix, windows))]
|
||||
pub mod locale;
|
||||
pub mod readline;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod windows;
|
||||
@@ -67,6 +68,10 @@ pub mod time;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod cert_store;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod system_configuration {
|
||||
pub use ::system_configuration::*;
|
||||
}
|
||||
#[cfg(any(unix, windows))]
|
||||
pub mod faulthandler;
|
||||
#[cfg(any(unix, windows))]
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::{ffi::CStr, ptr};
|
||||
|
||||
pub use libc::{LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME};
|
||||
|
||||
#[cfg(all(unix, not(any(target_os = "ios", target_os = "redox"))))]
|
||||
pub use libc::LC_MESSAGES;
|
||||
|
||||
#[cfg(all(
|
||||
unix,
|
||||
not(any(target_os = "ios", target_os = "android", target_os = "redox"))
|
||||
))]
|
||||
pub use libc::{
|
||||
ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7, ABMON_1, ABMON_2, ABMON_3,
|
||||
ABMON_4, ABMON_5, ABMON_6, ABMON_7, ABMON_8, ABMON_9, ABMON_10, ABMON_11, ABMON_12, ALT_DIGITS,
|
||||
AM_STR, CODESET, CRNCYSTR, D_FMT, D_T_FMT, DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7,
|
||||
ERA, ERA_D_FMT, ERA_D_T_FMT, ERA_T_FMT, MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7, MON_8,
|
||||
MON_9, MON_10, MON_11, MON_12, NOEXPR, PM_STR, RADIXCHAR, T_FMT, T_FMT_AMPM, THOUSEP, YESEXPR,
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
#[repr(C)]
|
||||
struct RawLconv {
|
||||
|
||||
@@ -59,7 +59,6 @@ pub use libc::MAP_STACK;
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub use libc::{MADV_AUTOSYNC, MADV_CORE, MADV_NOCORE, MADV_NOSYNC, MADV_PROTECT};
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use libc::EOVERFLOW;
|
||||
|
||||
#[cfg(windows)]
|
||||
|
||||
@@ -13,7 +13,7 @@ use alloc::ffi::CString;
|
||||
use std::io;
|
||||
|
||||
#[cfg(unix)]
|
||||
use libc::sem_t;
|
||||
pub use libc::{sem_t, timespec};
|
||||
#[cfg(unix)]
|
||||
use nix::errno::Errno;
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ use std::path::Path;
|
||||
|
||||
use crate::crt_fd;
|
||||
|
||||
pub use libc::{c_char, pid_t};
|
||||
|
||||
pub struct UnameInfo {
|
||||
pub sysname: String,
|
||||
pub nodename: String,
|
||||
|
||||
@@ -106,34 +106,18 @@ pub mod rustyline_readline {
|
||||
}
|
||||
|
||||
pub fn load_history(&mut self, path: &Path) -> OtherResult<()> {
|
||||
#[cfg(not(feature = "host_env"))]
|
||||
{
|
||||
let _ = path;
|
||||
Err(io::Error::other("history requires the `host_env` feature").into())
|
||||
}
|
||||
#[cfg(feature = "host_env")]
|
||||
{
|
||||
self.repl.load_history(path)?;
|
||||
Ok(())
|
||||
}
|
||||
self.repl.load_history(path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn save_history(&mut self, path: &Path) -> OtherResult<()> {
|
||||
#[cfg(not(feature = "host_env"))]
|
||||
if !path.exists()
|
||||
&& let Some(parent) = path.parent()
|
||||
{
|
||||
let _ = path;
|
||||
Err(io::Error::other("history requires the `host_env` feature").into())
|
||||
}
|
||||
#[cfg(feature = "host_env")]
|
||||
{
|
||||
if !path.exists()
|
||||
&& let Some(parent) = path.parent()
|
||||
{
|
||||
crate::host_env::fs::create_dir_all(parent)?;
|
||||
}
|
||||
self.repl.save_history(path)?;
|
||||
Ok(())
|
||||
crate::fs::create_dir_all(parent)?;
|
||||
}
|
||||
self.repl.save_history(path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_history_entry(&mut self, entry: &str) -> OtherResult<()> {
|
||||
@@ -2,6 +2,40 @@ use std::io;
|
||||
|
||||
use crate::os::CheckLibcResult;
|
||||
|
||||
pub use libc::{
|
||||
RLIM_INFINITY, RLIMIT_AS, RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_MEMLOCK,
|
||||
RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_RSS, RLIMIT_STACK, c_long, rlim_t, rlimit, timeval,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub use libc::RLIM_NLIMITS;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
|
||||
pub use libc::{RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_RTPRIO, RLIMIT_SIGPENDING};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use libc::RLIMIT_RTTIME;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos"
|
||||
))]
|
||||
pub use libc::RLIMIT_SBSIZE;
|
||||
|
||||
#[cfg(any(target_os = "freebsd", target_os = "solaris", target_os = "illumos"))]
|
||||
pub use libc::{RLIMIT_NPTS, RLIMIT_SWAP};
|
||||
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
pub use libc::RLIMIT_VMEM;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "freebsd"))]
|
||||
pub use libc::RUSAGE_THREAD;
|
||||
|
||||
#[cfg(not(any(target_os = "windows", target_os = "redox")))]
|
||||
pub use libc::{RUSAGE_CHILDREN, RUSAGE_SELF};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RUsage {
|
||||
pub ru_utime: libc::timeval,
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
use core::mem::MaybeUninit;
|
||||
use std::io;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use libc::{EINTR, FD_SETSIZE, POLLERR, POLLHUP, POLLIN, POLLNVAL, POLLOUT, POLLPRI};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
|
||||
pub use libc::{
|
||||
EPOLL_CLOEXEC, EPOLLERR, EPOLLET, EPOLLEXCLUSIVE, EPOLLHUP, EPOLLIN, EPOLLMSG, EPOLLONESHOT,
|
||||
EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDHUP, EPOLLRDNORM, EPOLLWAKEUP, EPOLLWRBAND,
|
||||
EPOLLWRNORM,
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
pub mod platform {
|
||||
pub use libc::pollfd;
|
||||
|
||||
@@ -3,6 +3,8 @@ use std::io;
|
||||
|
||||
use crate::os::CheckLibcResult;
|
||||
|
||||
pub use libc::mode_t;
|
||||
|
||||
pub fn shm_open(name: &CStr, flags: libc::c_int, mode: libc::c_uint) -> io::Result<libc::c_int> {
|
||||
#[cfg(target_os = "freebsd")]
|
||||
let mode = mode.try_into().unwrap();
|
||||
|
||||
@@ -7,6 +7,43 @@ use std::os::fd::AsRawFd;
|
||||
#[cfg(unix)]
|
||||
use std::{io, os::fd::BorrowedFd};
|
||||
|
||||
/// Returns the system's hostname.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn hostname() -> std::ffi::OsString {
|
||||
gethostname::gethostname()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use ::dns_lookup as dns;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use ::socket2 as raw;
|
||||
|
||||
/// Returns the first non-loopback MAC address as 6 bytes, or `None` when no
|
||||
/// MAC address is available or the lookup fails.
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "android",
|
||||
target_os = "windows",
|
||||
target_arch = "wasm32",
|
||||
target_os = "redox"
|
||||
)))]
|
||||
pub fn mac_address() -> Option<[u8; 6]> {
|
||||
mac_address::get_mac_address()
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|m| m.bytes())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use libc::{AF_UNIX, SOCK_STREAM, sa_family_t, sockaddr_storage, socklen_t};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub use libc::{AF_ALG, AF_CAN};
|
||||
|
||||
// bionic (Android) does not define the CAN/ALG sockaddr structs.
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use libc::{sockaddr_alg, sockaddr_can};
|
||||
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
pub fn sethostname(hostname: &str) -> io::Result<()> {
|
||||
nix::unistd::sethostname(hostname).map_err(io::Error::from)
|
||||
|
||||
@@ -3,6 +3,16 @@ use core::ffi::CStr;
|
||||
use parking_lot::RwLock;
|
||||
use std::{os::raw::c_char, sync::OnceLock};
|
||||
|
||||
pub use libc::{
|
||||
LOG_ALERT, LOG_AUTH, LOG_CONS, LOG_CRIT, LOG_DAEMON, LOG_DEBUG, LOG_EMERG, LOG_ERR, LOG_INFO,
|
||||
LOG_KERN, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6,
|
||||
LOG_LOCAL7, LOG_LPR, LOG_MAIL, LOG_NDELAY, LOG_NEWS, LOG_NOTICE, LOG_NOWAIT, LOG_ODELAY,
|
||||
LOG_PID, LOG_SYSLOG, LOG_USER, LOG_UUCP, LOG_WARNING,
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
pub use libc::{LOG_AUTHPRIV, LOG_CRON, LOG_PERROR};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum GlobalIdent {
|
||||
Explicit(Box<CStr>),
|
||||
|
||||
@@ -1,5 +1,55 @@
|
||||
pub type Termios = ::termios::Termios;
|
||||
|
||||
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
||||
pub use libc::{CSTART, CSTOP, CSWTCH};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub use libc::{FIOASYNC, TIOCGETD, TIOCSETD};
|
||||
|
||||
pub use libc::{FIOCLEX, FIONBIO, TIOCGWINSZ, TIOCSWINSZ};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub use libc::{
|
||||
FIONCLEX, FIONREAD, TIOCEXCL, TIOCM_CAR, TIOCM_CD, TIOCM_CTS, TIOCM_DSR, TIOCM_DTR, TIOCM_LE,
|
||||
TIOCM_RI, TIOCM_RNG, TIOCM_RTS, TIOCM_SR, TIOCM_ST, TIOCMBIC, TIOCMBIS, TIOCMGET, TIOCMSET,
|
||||
TIOCNXCL, TIOCSCTTY,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub use libc::{
|
||||
IBSHIFT, TCFLSH, TCGETA, TCGETS, TCSBRK, TCSETA, TCSETAF, TCSETAW, TCSETS, TCSETSF, TCSETSW,
|
||||
TCXONC, TIOCGSERIAL, TIOCGSOFTCAR, TIOCINQ, TIOCLINUX, TIOCSSOFTCAR, XTABS,
|
||||
};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos"
|
||||
))]
|
||||
pub use libc::{TIOCCONS, TIOCGPGRP, TIOCOUTQ, TIOCSPGRP, TIOCSTI};
|
||||
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"))]
|
||||
pub use libc::{
|
||||
TIOCNOTTY, TIOCPKT, TIOCPKT_DATA, TIOCPKT_DOSTOP, TIOCPKT_FLUSHREAD, TIOCPKT_FLUSHWRITE,
|
||||
TIOCPKT_NOSTOP, TIOCPKT_START, TIOCPKT_STOP,
|
||||
};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
|
||||
@@ -92,14 +92,10 @@ chrono.workspace = true
|
||||
|
||||
# uuid
|
||||
[target.'cfg(not(any(target_os = "ios", target_os = "android", target_os = "windows", target_arch = "wasm32", target_os = "redox")))'.dependencies]
|
||||
mac_address = { workspace = true }
|
||||
uuid = { workspace = true, features = ["v1"] }
|
||||
|
||||
# mmap + socket dependencies
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
gethostname = { workspace = true }
|
||||
socket2 = { workspace = true, features = ["all"] }
|
||||
dns-lookup = { workspace = true }
|
||||
|
||||
# OpenSSL dependencies (optional, for ssl-openssl feature)
|
||||
openssl = { workspace = true, optional = true }
|
||||
@@ -129,9 +125,6 @@ xz-sys = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
widestring = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
system-configuration = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
insta = { workspace = true }
|
||||
rustpython-pylib = { workspace = true, features = [ "freeze-stdlib" ] }
|
||||
|
||||
@@ -373,7 +373,7 @@ mod decl {
|
||||
|
||||
// faulthandler_fatal_error
|
||||
#[cfg(unix)]
|
||||
extern "C" fn faulthandler_fatal_error(signum: libc::c_int) {
|
||||
extern "C" fn faulthandler_fatal_error(signum: core::ffi::c_int) {
|
||||
let save_errno = get_errno();
|
||||
|
||||
if !FATAL_ERROR.enabled.load(Ordering::Relaxed) {
|
||||
@@ -410,7 +410,7 @@ mod decl {
|
||||
|
||||
// faulthandler_fatal_error for Windows
|
||||
#[cfg(windows)]
|
||||
extern "C" fn faulthandler_fatal_error(signum: libc::c_int) {
|
||||
extern "C" fn faulthandler_fatal_error(signum: core::ffi::c_int) {
|
||||
let save_errno = get_errno();
|
||||
|
||||
if !FATAL_ERROR.enabled.load(Ordering::Relaxed) {
|
||||
@@ -479,7 +479,7 @@ mod decl {
|
||||
|
||||
// Disable SIGSEGV handler for access violations to avoid double output
|
||||
if host_faulthandler::is_access_violation(code) {
|
||||
host_faulthandler::disable_fatal_signal(libc::SIGSEGV);
|
||||
host_faulthandler::disable_fatal_signal(host_faulthandler::SIGSEGV);
|
||||
}
|
||||
|
||||
let all_threads = FATAL_ERROR.all_threads.load(Ordering::Relaxed);
|
||||
@@ -495,7 +495,10 @@ mod decl {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !host_faulthandler::enable_fatal_handlers(faulthandler_fatal_error, libc::SA_NODEFER) {
|
||||
if !host_faulthandler::enable_fatal_handlers(
|
||||
faulthandler_fatal_error,
|
||||
host_faulthandler::SA_NODEFER,
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -769,7 +772,7 @@ mod decl {
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
extern "C" fn faulthandler_user_signal(signum: libc::c_int) {
|
||||
extern "C" fn faulthandler_user_signal(signum: core::ffi::c_int) {
|
||||
let save_errno = get_errno();
|
||||
|
||||
let user = match host_faulthandler::get_user_signal(signum as usize) {
|
||||
@@ -900,7 +903,7 @@ mod decl {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
suppress_crash_report();
|
||||
host_faulthandler::raise_signal(libc::SIGFPE);
|
||||
host_faulthandler::raise_signal(host_faulthandler::SIGFPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,38 +25,40 @@ mod fcntl {
|
||||
// I_LINK, I_UNLINK, I_PLINK, I_PUNLINK
|
||||
|
||||
#[pyattr]
|
||||
use libc::{F_GETFD, F_GETFL, F_SETFD, F_SETFL, FD_CLOEXEC};
|
||||
use host_fcntl::{F_GETFD, F_GETFL, F_SETFD, F_SETFL, FD_CLOEXEC};
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
#[pyattr]
|
||||
use libc::{F_DUPFD, F_DUPFD_CLOEXEC, F_GETLK, F_SETLK, F_SETLKW};
|
||||
use host_fcntl::{F_DUPFD, F_DUPFD_CLOEXEC, F_GETLK, F_SETLK, F_SETLKW};
|
||||
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "redox")))]
|
||||
#[pyattr]
|
||||
use libc::{F_GETOWN, F_RDLCK, F_SETOWN, F_UNLCK, F_WRLCK, LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN};
|
||||
use host_fcntl::{
|
||||
F_GETOWN, F_RDLCK, F_SETOWN, F_UNLCK, F_WRLCK, LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN,
|
||||
};
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
#[pyattr]
|
||||
use libc::{F_FULLFSYNC, F_NOCACHE};
|
||||
use host_fcntl::{F_FULLFSYNC, F_NOCACHE};
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[pyattr]
|
||||
use libc::{F_DUP2FD, F_DUP2FD_CLOEXEC};
|
||||
use host_fcntl::{F_DUP2FD, F_DUP2FD_CLOEXEC};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use libc::{F_OFD_GETLK, F_OFD_SETLK, F_OFD_SETLKW};
|
||||
use host_fcntl::{F_OFD_GETLK, F_OFD_SETLK, F_OFD_SETLKW};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use host_fcntl::{
|
||||
F_ADD_SEALS, F_GET_SEALS, F_GETLEASE, F_GETPIPE_SZ, F_NOTIFY, F_SEAL_GROW, F_SEAL_SEAL,
|
||||
F_SEAL_SHRINK, F_SEAL_WRITE, F_SETLEASE, F_SETPIPE_SZ,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_vendor = "apple"))]
|
||||
#[pyattr]
|
||||
use libc::F_GETPATH;
|
||||
use host_fcntl::F_GETPATH;
|
||||
|
||||
#[pyfunction]
|
||||
fn fcntl(
|
||||
|
||||
@@ -43,7 +43,7 @@ mod grp {
|
||||
#[pyfunction]
|
||||
fn getgrgid(gid: PyIntRef, vm: &VirtualMachine) -> PyResult<GroupData> {
|
||||
let gr_gid = gid.as_bigint();
|
||||
let gid = libc::gid_t::try_from(gr_gid).ok();
|
||||
let gid = host_grp::gid_t::try_from(gr_gid).ok();
|
||||
let group = gid
|
||||
.map(host_grp::getgrgid)
|
||||
.transpose()
|
||||
|
||||
@@ -18,7 +18,7 @@ mod _locale {
|
||||
not(any(target_os = "ios", target_os = "android", target_os = "redox"))
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use rustpython_host_env::locale::{
|
||||
ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7, ABMON_1, ABMON_2, ABMON_3,
|
||||
ABMON_4, ABMON_5, ABMON_6, ABMON_7, ABMON_8, ABMON_9, ABMON_10, ABMON_11, ABMON_12,
|
||||
ALT_DIGITS, AM_STR, CODESET, CRNCYSTR, D_FMT, D_T_FMT, DAY_1, DAY_2, DAY_3, DAY_4, DAY_5,
|
||||
@@ -29,17 +29,19 @@ mod _locale {
|
||||
|
||||
#[cfg(all(unix, not(any(target_os = "ios", target_os = "redox"))))]
|
||||
#[pyattr]
|
||||
use libc::LC_MESSAGES;
|
||||
use rustpython_host_env::locale::LC_MESSAGES;
|
||||
|
||||
#[pyattr]
|
||||
use libc::{LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME};
|
||||
use rustpython_host_env::locale::{
|
||||
LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME,
|
||||
};
|
||||
|
||||
#[pyattr(name = "CHAR_MAX")]
|
||||
fn char_max(vm: &VirtualMachine) -> PyIntRef {
|
||||
vm.ctx.new_int(libc::c_char::MAX)
|
||||
vm.ctx.new_int(core::ffi::c_char::MAX)
|
||||
}
|
||||
|
||||
fn copy_grouping(group: &[libc::c_char], vm: &VirtualMachine) -> PyListRef {
|
||||
fn copy_grouping(group: &[core::ffi::c_char], vm: &VirtualMachine) -> PyListRef {
|
||||
let mut group_vec: Vec<PyObjectRef> = Vec::new();
|
||||
for &value in group {
|
||||
let val = vm.ctx.new_int(value);
|
||||
|
||||
@@ -333,7 +333,7 @@ mod _multiprocessing {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn send(socket: usize, buf: ArgBytesLike, vm: &VirtualMachine) -> PyResult<libc::c_int> {
|
||||
fn send(socket: usize, buf: ArgBytesLike, vm: &VirtualMachine) -> PyResult<core::ffi::c_int> {
|
||||
buf.with_ref(|b| {
|
||||
host_multiprocessing::send_socket(socket as host_multiprocessing::RawSocket, b)
|
||||
})
|
||||
@@ -355,7 +355,7 @@ mod _multiprocessing {
|
||||
};
|
||||
use core::sync::atomic::{AtomicI32, AtomicU64, Ordering};
|
||||
#[cfg(target_vendor = "apple")]
|
||||
use libc::sem_t;
|
||||
use rustpython_host_env::multiprocessing::sem_t;
|
||||
use rustpython_host_env::multiprocessing::{
|
||||
self as host_multiprocessing, SemError, TryAcquireStatus, WaitStatus,
|
||||
};
|
||||
@@ -373,7 +373,7 @@ mod _multiprocessing {
|
||||
#[cfg(target_vendor = "apple")]
|
||||
fn sem_timedwait_polled(
|
||||
sem: *mut sem_t,
|
||||
deadline: &libc::timespec,
|
||||
deadline: &host_multiprocessing::timespec,
|
||||
vm: &VirtualMachine,
|
||||
) -> Result<(), SemWaitError> {
|
||||
let mut delay: u64 = 0;
|
||||
|
||||
+139
-129
@@ -154,63 +154,63 @@ mod _ssl {
|
||||
// SSL Alert Descriptions (RFC 5246 and extensions)
|
||||
// Hybrid approach: use openssl_sys constants where available, hardcode others
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_CLOSE_NOTIFY: libc::c_int = 0;
|
||||
const ALERT_DESCRIPTION_CLOSE_NOTIFY: core::ffi::c_int = 0;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_UNEXPECTED_MESSAGE: libc::c_int = 10;
|
||||
const ALERT_DESCRIPTION_UNEXPECTED_MESSAGE: core::ffi::c_int = 10;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_BAD_RECORD_MAC: libc::c_int = 20;
|
||||
const ALERT_DESCRIPTION_BAD_RECORD_MAC: core::ffi::c_int = 20;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_RECORD_OVERFLOW: libc::c_int = 22;
|
||||
const ALERT_DESCRIPTION_RECORD_OVERFLOW: core::ffi::c_int = 22;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_DECOMPRESSION_FAILURE: libc::c_int = 30;
|
||||
const ALERT_DESCRIPTION_DECOMPRESSION_FAILURE: core::ffi::c_int = 30;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_HANDSHAKE_FAILURE: libc::c_int = 40;
|
||||
const ALERT_DESCRIPTION_HANDSHAKE_FAILURE: core::ffi::c_int = 40;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_BAD_CERTIFICATE: libc::c_int = 42;
|
||||
const ALERT_DESCRIPTION_BAD_CERTIFICATE: core::ffi::c_int = 42;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE: libc::c_int = 43;
|
||||
const ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE: core::ffi::c_int = 43;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_REVOKED: libc::c_int = 44;
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_REVOKED: core::ffi::c_int = 44;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_EXPIRED: libc::c_int = 45;
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_EXPIRED: core::ffi::c_int = 45;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN: libc::c_int = 46;
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN: core::ffi::c_int = 46;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_ILLEGAL_PARAMETER: libc::c_int = SSL_AD_ILLEGAL_PARAMETER;
|
||||
const ALERT_DESCRIPTION_ILLEGAL_PARAMETER: core::ffi::c_int = SSL_AD_ILLEGAL_PARAMETER;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_UNKNOWN_CA: libc::c_int = 48;
|
||||
const ALERT_DESCRIPTION_UNKNOWN_CA: core::ffi::c_int = 48;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_ACCESS_DENIED: libc::c_int = 49;
|
||||
const ALERT_DESCRIPTION_ACCESS_DENIED: core::ffi::c_int = 49;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_DECODE_ERROR: libc::c_int = SSL_AD_DECODE_ERROR;
|
||||
const ALERT_DESCRIPTION_DECODE_ERROR: core::ffi::c_int = SSL_AD_DECODE_ERROR;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_DECRYPT_ERROR: libc::c_int = 51;
|
||||
const ALERT_DESCRIPTION_DECRYPT_ERROR: core::ffi::c_int = 51;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_PROTOCOL_VERSION: libc::c_int = 70;
|
||||
const ALERT_DESCRIPTION_PROTOCOL_VERSION: core::ffi::c_int = 70;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_INSUFFICIENT_SECURITY: libc::c_int = 71;
|
||||
const ALERT_DESCRIPTION_INSUFFICIENT_SECURITY: core::ffi::c_int = 71;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_INTERNAL_ERROR: libc::c_int = 80;
|
||||
const ALERT_DESCRIPTION_INTERNAL_ERROR: core::ffi::c_int = 80;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_USER_CANCELLED: libc::c_int = 90;
|
||||
const ALERT_DESCRIPTION_USER_CANCELLED: core::ffi::c_int = 90;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_NO_RENEGOTIATION: libc::c_int = 100;
|
||||
const ALERT_DESCRIPTION_NO_RENEGOTIATION: core::ffi::c_int = 100;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION: libc::c_int = 110;
|
||||
const ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION: core::ffi::c_int = 110;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE: libc::c_int = 111;
|
||||
const ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE: core::ffi::c_int = 111;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_UNRECOGNIZED_NAME: libc::c_int = SSL_AD_UNRECOGNIZED_NAME;
|
||||
const ALERT_DESCRIPTION_UNRECOGNIZED_NAME: core::ffi::c_int = SSL_AD_UNRECOGNIZED_NAME;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE: libc::c_int = 113;
|
||||
const ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE: core::ffi::c_int = 113;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE: libc::c_int = 114;
|
||||
const ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE: core::ffi::c_int = 114;
|
||||
#[pyattr]
|
||||
const ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY: libc::c_int = 115;
|
||||
const ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY: core::ffi::c_int = 115;
|
||||
|
||||
// CRL verification constants
|
||||
#[pyattr]
|
||||
const VERIFY_CRL_CHECK_CHAIN: libc::c_ulong =
|
||||
const VERIFY_CRL_CHECK_CHAIN: core::ffi::c_ulong =
|
||||
sys::X509_V_FLAG_CRL_CHECK | sys::X509_V_FLAG_CRL_CHECK_ALL;
|
||||
|
||||
// taken from CPython, should probably be kept up to date with their version if it ever changes
|
||||
@@ -248,7 +248,8 @@ mod _ssl {
|
||||
#[pyattr]
|
||||
const PROTO_MAXIMUM_SUPPORTED: i32 = ProtoVersion::MaxSupported as i32;
|
||||
#[pyattr]
|
||||
const OP_ALL: libc::c_ulong = (sys::SSL_OP_ALL & !sys::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) as _;
|
||||
const OP_ALL: core::ffi::c_ulong =
|
||||
(sys::SSL_OP_ALL & !sys::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) as _;
|
||||
#[pyattr]
|
||||
const HAS_TLS_UNIQUE: bool = true;
|
||||
#[pyattr]
|
||||
@@ -298,7 +299,7 @@ mod _ssl {
|
||||
|
||||
// SSL_VERIFY constants for post-handshake authentication
|
||||
#[cfg(ossl111)]
|
||||
const SSL_VERIFY_POST_HANDSHAKE: libc::c_int = 0x20;
|
||||
const SSL_VERIFY_POST_HANDSHAKE: core::ffi::c_int = 0x20;
|
||||
|
||||
// the openssl version from the API headers
|
||||
|
||||
@@ -393,7 +394,7 @@ mod _ssl {
|
||||
unsafe { ptr2obj(sys::OBJ_nid2obj(nid.as_raw())) }
|
||||
}
|
||||
|
||||
type PyNid = (libc::c_int, String, String, Option<String>);
|
||||
type PyNid = (core::ffi::c_int, String, String, Option<String>);
|
||||
fn obj2py(obj: &Asn1ObjectRef, vm: &VirtualMachine) -> PyResult<PyNid> {
|
||||
let nid = obj.nid();
|
||||
let short_name = nid
|
||||
@@ -428,7 +429,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn nid2obj(nid: libc::c_int, vm: &VirtualMachine) -> PyResult<PyNid> {
|
||||
fn nid2obj(nid: core::ffi::c_int, vm: &VirtualMachine) -> PyResult<PyNid> {
|
||||
_nid2obj(Nid::from_raw(nid))
|
||||
.as_deref()
|
||||
.ok_or_else(|| vm.new_value_error(format!("unknown NID {nid}")))
|
||||
@@ -508,7 +509,7 @@ mod _ssl {
|
||||
#[pyfunction(name = "RAND_add")]
|
||||
fn rand_add(string: ArgStrOrBytesLike, entropy: f64) {
|
||||
let f = |b: &[u8]| {
|
||||
for buf in b.chunks(libc::c_int::MAX as usize) {
|
||||
for buf in b.chunks(core::ffi::c_int::MAX as usize) {
|
||||
unsafe { sys::RAND_add(buf.as_ptr() as *const _, buf.len() as _, entropy) }
|
||||
}
|
||||
};
|
||||
@@ -573,9 +574,9 @@ mod _ssl {
|
||||
}
|
||||
|
||||
// Get or create an ex_data index for SNI callback data
|
||||
fn get_sni_ex_data_index() -> libc::c_int {
|
||||
fn get_sni_ex_data_index() -> core::ffi::c_int {
|
||||
use rustpython_common::lock::LazyLock;
|
||||
static SNI_EX_DATA_IDX: LazyLock<libc::c_int> = LazyLock::new(|| unsafe {
|
||||
static SNI_EX_DATA_IDX: LazyLock<core::ffi::c_int> = LazyLock::new(|| unsafe {
|
||||
sys::SSL_get_ex_new_index(
|
||||
0,
|
||||
core::ptr::null_mut(),
|
||||
@@ -591,12 +592,12 @@ mod _ssl {
|
||||
// NOTE: We don't free the data here because it's managed manually in do_handshake
|
||||
// to avoid use-after-free when the SSL object is dropped after timeout
|
||||
unsafe extern "C" fn sni_callback_data_free(
|
||||
_parent: *mut libc::c_void,
|
||||
_ptr: *mut libc::c_void,
|
||||
_parent: *mut core::ffi::c_void,
|
||||
_ptr: *mut core::ffi::c_void,
|
||||
_ad: *mut sys::CRYPTO_EX_DATA,
|
||||
_idx: libc::c_int,
|
||||
_argl: libc::c_long,
|
||||
_argp: *mut libc::c_void,
|
||||
_idx: core::ffi::c_int,
|
||||
_argl: core::ffi::c_long,
|
||||
_argp: *mut core::ffi::c_void,
|
||||
) {
|
||||
// Intentionally empty - data is freed in cleanup_sni_ex_data()
|
||||
}
|
||||
@@ -617,9 +618,9 @@ mod _ssl {
|
||||
}
|
||||
|
||||
// Get or create an ex_data index for msg_callback data
|
||||
fn get_msg_callback_ex_data_index() -> libc::c_int {
|
||||
fn get_msg_callback_ex_data_index() -> core::ffi::c_int {
|
||||
use rustpython_common::lock::LazyLock;
|
||||
static MSG_CB_EX_DATA_IDX: LazyLock<libc::c_int> = LazyLock::new(|| unsafe {
|
||||
static MSG_CB_EX_DATA_IDX: LazyLock<core::ffi::c_int> = LazyLock::new(|| unsafe {
|
||||
sys::SSL_get_ex_new_index(
|
||||
0,
|
||||
core::ptr::null_mut(),
|
||||
@@ -633,12 +634,12 @@ mod _ssl {
|
||||
|
||||
// Free function for msg_callback data - called by OpenSSL when SSL is freed
|
||||
unsafe extern "C" fn msg_callback_data_free(
|
||||
_parent: *mut libc::c_void,
|
||||
ptr: *mut libc::c_void,
|
||||
_parent: *mut core::ffi::c_void,
|
||||
ptr: *mut core::ffi::c_void,
|
||||
_ad: *mut sys::CRYPTO_EX_DATA,
|
||||
_idx: libc::c_int,
|
||||
_argl: libc::c_long,
|
||||
_argp: *mut libc::c_void,
|
||||
_idx: core::ffi::c_int,
|
||||
_argl: core::ffi::c_long,
|
||||
_argp: *mut core::ffi::c_void,
|
||||
) {
|
||||
if !ptr.is_null() {
|
||||
unsafe {
|
||||
@@ -652,13 +653,13 @@ mod _ssl {
|
||||
// SNI callback function called by OpenSSL
|
||||
unsafe extern "C" fn _servername_callback(
|
||||
ssl_ptr: *mut sys::SSL,
|
||||
al: *mut libc::c_int,
|
||||
arg: *mut libc::c_void,
|
||||
) -> libc::c_int {
|
||||
const SSL_TLSEXT_ERR_OK: libc::c_int = 0;
|
||||
const SSL_TLSEXT_ERR_ALERT_FATAL: libc::c_int = 2;
|
||||
const SSL_AD_INTERNAL_ERROR: libc::c_int = 80;
|
||||
const TLSEXT_NAMETYPE_host_name: libc::c_int = 0;
|
||||
al: *mut core::ffi::c_int,
|
||||
arg: *mut core::ffi::c_void,
|
||||
) -> core::ffi::c_int {
|
||||
const SSL_TLSEXT_ERR_OK: core::ffi::c_int = 0;
|
||||
const SSL_TLSEXT_ERR_ALERT_FATAL: core::ffi::c_int = 2;
|
||||
const SSL_AD_INTERNAL_ERROR: core::ffi::c_int = 80;
|
||||
const TLSEXT_NAMETYPE_host_name: core::ffi::c_int = 0;
|
||||
|
||||
if arg.is_null() {
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
@@ -766,13 +767,13 @@ mod _ssl {
|
||||
// Called during SSL operations to report protocol messages.
|
||||
// debughelpers.c:_PySSL_msg_callback
|
||||
unsafe extern "C" fn _msg_callback(
|
||||
write_p: libc::c_int,
|
||||
mut version: libc::c_int,
|
||||
content_type: libc::c_int,
|
||||
buf: *const libc::c_void,
|
||||
write_p: core::ffi::c_int,
|
||||
mut version: core::ffi::c_int,
|
||||
content_type: core::ffi::c_int,
|
||||
buf: *const core::ffi::c_void,
|
||||
len: usize,
|
||||
ssl_ptr: *mut sys::SSL,
|
||||
_arg: *mut libc::c_void,
|
||||
_arg: *mut core::ffi::c_void,
|
||||
) {
|
||||
if ssl_ptr.is_null() {
|
||||
return;
|
||||
@@ -1122,7 +1123,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[pygetset]
|
||||
fn options(&self) -> libc::c_ulong {
|
||||
fn options(&self) -> core::ffi::c_ulong {
|
||||
self.ctx.read().options().bits() as _
|
||||
}
|
||||
#[pygetset(setter)]
|
||||
@@ -1130,10 +1131,10 @@ mod _ssl {
|
||||
if new_opts < 0 {
|
||||
return Err(vm.new_value_error("invalid options value"));
|
||||
}
|
||||
let new_opts = new_opts as libc::c_ulong;
|
||||
let new_opts = new_opts as core::ffi::c_ulong;
|
||||
let mut ctx = self.builder();
|
||||
// Get current options
|
||||
let current = ctx.options().bits() as libc::c_ulong;
|
||||
let current = ctx.options().bits() as core::ffi::c_ulong;
|
||||
|
||||
// Calculate options to clear and set
|
||||
let clear = current & !new_opts;
|
||||
@@ -1190,7 +1191,7 @@ mod _ssl {
|
||||
Ok(())
|
||||
}
|
||||
#[pygetset]
|
||||
fn verify_flags(&self) -> libc::c_ulong {
|
||||
fn verify_flags(&self) -> core::ffi::c_ulong {
|
||||
unsafe {
|
||||
let ctx_ptr = self.ctx().as_ptr();
|
||||
let param = sys::SSL_CTX_get0_param(ctx_ptr);
|
||||
@@ -1198,7 +1199,11 @@ mod _ssl {
|
||||
}
|
||||
}
|
||||
#[pygetset(setter)]
|
||||
fn set_verify_flags(&self, new_flags: libc::c_ulong, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn set_verify_flags(
|
||||
&self,
|
||||
new_flags: core::ffi::c_ulong,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
unsafe {
|
||||
let ctx_ptr = self.ctx().as_ptr();
|
||||
let param = sys::SSL_CTX_get0_param(ctx_ptr);
|
||||
@@ -1359,10 +1364,10 @@ mod _ssl {
|
||||
{
|
||||
let mut ctx = self.builder();
|
||||
let server = protos.with_ref(|pbuf| {
|
||||
if pbuf.len() > libc::c_uint::MAX as usize {
|
||||
if pbuf.len() > core::ffi::c_uint::MAX as usize {
|
||||
return Err(vm.new_overflow_error(format!(
|
||||
"protocols longer than {} bytes",
|
||||
libc::c_uint::MAX
|
||||
core::ffi::c_uint::MAX
|
||||
)));
|
||||
}
|
||||
ctx.set_alpn_protos(pbuf)
|
||||
@@ -1523,7 +1528,7 @@ mod _ssl {
|
||||
return Err(vm
|
||||
.new_os_subtype_error(
|
||||
vm.ctx.exceptions.file_not_found_error.to_owned(),
|
||||
Some(libc::ENOENT),
|
||||
Some(rustpython_host_env::errno::errors::ENOENT),
|
||||
format!("No such file or directory: '{}'", path.display()),
|
||||
)
|
||||
.upcast());
|
||||
@@ -1534,7 +1539,7 @@ mod _ssl {
|
||||
return Err(vm
|
||||
.new_os_subtype_error(
|
||||
vm.ctx.exceptions.file_not_found_error.to_owned(),
|
||||
Some(libc::ENOENT),
|
||||
Some(rustpython_host_env::errno::errors::ENOENT),
|
||||
format!("No such file or directory: '{}'", path.display()),
|
||||
)
|
||||
.upcast());
|
||||
@@ -1667,7 +1672,7 @@ mod _ssl {
|
||||
std::io::ErrorKind::NotFound => vm
|
||||
.new_os_subtype_error(
|
||||
vm.ctx.exceptions.file_not_found_error.to_owned(),
|
||||
Some(libc::ENOENT),
|
||||
Some(rustpython_host_env::errno::errors::ENOENT),
|
||||
e.to_string(),
|
||||
)
|
||||
.upcast(),
|
||||
@@ -1684,7 +1689,7 @@ mod _ssl {
|
||||
)
|
||||
};
|
||||
unsafe {
|
||||
libc::fclose(fp);
|
||||
rustpython_host_env::fileutils::fclose(fp);
|
||||
}
|
||||
|
||||
if dh.is_null() {
|
||||
@@ -1842,7 +1847,7 @@ mod _ssl {
|
||||
return Err(vm
|
||||
.new_os_subtype_error(
|
||||
vm.ctx.exceptions.file_not_found_error.to_owned(),
|
||||
Some(libc::ENOENT),
|
||||
Some(rustpython_host_env::errno::errors::ENOENT),
|
||||
format!("No such file or directory: '{}'", cert_path.display()),
|
||||
)
|
||||
.upcast());
|
||||
@@ -1853,7 +1858,7 @@ mod _ssl {
|
||||
return Err(vm
|
||||
.new_os_subtype_error(
|
||||
vm.ctx.exceptions.file_not_found_error.to_owned(),
|
||||
Some(libc::ENOENT),
|
||||
Some(rustpython_host_env::errno::errors::ENOENT),
|
||||
format!("No such file or directory: '{}'", kp.display()),
|
||||
)
|
||||
.upcast());
|
||||
@@ -2013,7 +2018,7 @@ mod _ssl {
|
||||
let ret = SSL_set_session_id_context(
|
||||
ssl.as_ptr(),
|
||||
SID_CTX.as_ptr(),
|
||||
SID_CTX.len() as libc::c_uint,
|
||||
SID_CTX.len() as core::ffi::c_uint,
|
||||
);
|
||||
if ret == 0 {
|
||||
return Err(convert_openssl_error(vm, ErrorStack::get()));
|
||||
@@ -2061,7 +2066,7 @@ mod _ssl {
|
||||
// Server socket: add SSL_VERIFY_POST_HANDSHAKE flag
|
||||
// Only in combination with SSL_VERIFY_PEER
|
||||
let mode = sys::SSL_get_verify_mode(ssl.as_ptr());
|
||||
if (mode & sys::SSL_VERIFY_PEER as libc::c_int) != 0 {
|
||||
if (mode & sys::SSL_VERIFY_PEER as core::ffi::c_int) != 0 {
|
||||
sys::SSL_set_verify(
|
||||
ssl.as_ptr(),
|
||||
mode | SSL_VERIFY_POST_HANDSHAKE,
|
||||
@@ -2553,7 +2558,7 @@ mod _ssl {
|
||||
unsafe {
|
||||
let ssl_ctx = sys::SSL_get_SSL_CTX(stream.ssl().as_ptr());
|
||||
let verify_mode = sys::SSL_CTX_get_verify_mode(ssl_ctx);
|
||||
if (verify_mode & sys::SSL_VERIFY_PEER as libc::c_int) == 0 {
|
||||
if (verify_mode & sys::SSL_VERIFY_PEER as core::ffi::c_int) == 0 {
|
||||
// Return empty dict when SSL_VERIFY_PEER is not set
|
||||
Ok(Some(vm.ctx.new_dict().into()))
|
||||
} else {
|
||||
@@ -2723,8 +2728,8 @@ mod _ssl {
|
||||
// Use thread-local SSL pointer during handshake to avoid deadlock
|
||||
let ssl_ptr = get_ssl_ptr_for_context_change(&self.connection);
|
||||
unsafe {
|
||||
let mut out: *const libc::c_uchar = core::ptr::null();
|
||||
let mut outlen: libc::c_uint = 0;
|
||||
let mut out: *const core::ffi::c_uchar = core::ptr::null();
|
||||
let mut outlen: core::ffi::c_uint = 0;
|
||||
|
||||
sys::SSL_get0_alpn_selected(ssl_ptr, &mut out, &mut outlen);
|
||||
|
||||
@@ -3308,8 +3313,8 @@ mod _ssl {
|
||||
return Ok(PyComparisonValue::NotImplemented);
|
||||
}
|
||||
let mut eq = unsafe {
|
||||
let mut self_len: libc::c_uint = 0;
|
||||
let mut other_len: libc::c_uint = 0;
|
||||
let mut self_len: core::ffi::c_uint = 0;
|
||||
let mut other_len: core::ffi::c_uint = 0;
|
||||
let self_id = sys::SSL_SESSION_get_id(zelf.session, &mut self_len);
|
||||
let other_id = sys::SSL_SESSION_get_id(other.session, &mut other_len);
|
||||
|
||||
@@ -3359,7 +3364,7 @@ mod _ssl {
|
||||
|
||||
unsafe extern "C" {
|
||||
// X509_check_ca returns 1 for CA certificates, 0 otherwise
|
||||
fn X509_check_ca(x: *const sys::X509) -> libc::c_int;
|
||||
fn X509_check_ca(x: *const sys::X509) -> core::ffi::c_int;
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
@@ -3373,13 +3378,13 @@ mod _ssl {
|
||||
|
||||
#[cfg(ossl111)]
|
||||
unsafe extern "C" {
|
||||
fn SSL_verify_client_post_handshake(ssl: *const sys::SSL) -> libc::c_int;
|
||||
fn SSL_set_post_handshake_auth(ssl: *mut sys::SSL, val: libc::c_int);
|
||||
fn SSL_verify_client_post_handshake(ssl: *const sys::SSL) -> core::ffi::c_int;
|
||||
fn SSL_set_post_handshake_auth(ssl: *mut sys::SSL, val: core::ffi::c_int);
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
unsafe extern "C" {
|
||||
fn SSL_CTX_get_security_level(ctx: *const sys::SSL_CTX) -> libc::c_int;
|
||||
fn SSL_CTX_get_security_level(ctx: *const sys::SSL_CTX) -> core::ffi::c_int;
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
@@ -3390,13 +3395,13 @@ mod _ssl {
|
||||
#[allow(non_camel_case_types)]
|
||||
type SSL_CTX_msg_callback = Option<
|
||||
unsafe extern "C" fn(
|
||||
write_p: libc::c_int,
|
||||
version: libc::c_int,
|
||||
content_type: libc::c_int,
|
||||
buf: *const libc::c_void,
|
||||
write_p: core::ffi::c_int,
|
||||
version: core::ffi::c_int,
|
||||
content_type: core::ffi::c_int,
|
||||
buf: *const core::ffi::c_void,
|
||||
len: usize,
|
||||
ssl: *mut sys::SSL,
|
||||
arg: *mut libc::c_void,
|
||||
arg: *mut core::ffi::c_void,
|
||||
),
|
||||
>;
|
||||
|
||||
@@ -3406,40 +3411,42 @@ mod _ssl {
|
||||
|
||||
#[cfg(ossl110)]
|
||||
unsafe extern "C" {
|
||||
fn SSL_SESSION_has_ticket(session: *const sys::SSL_SESSION) -> libc::c_int;
|
||||
fn SSL_SESSION_get_ticket_lifetime_hint(session: *const sys::SSL_SESSION) -> libc::c_ulong;
|
||||
fn SSL_SESSION_has_ticket(session: *const sys::SSL_SESSION) -> core::ffi::c_int;
|
||||
fn SSL_SESSION_get_ticket_lifetime_hint(
|
||||
session: *const sys::SSL_SESSION,
|
||||
) -> core::ffi::c_ulong;
|
||||
}
|
||||
|
||||
// X509 object types
|
||||
const X509_LU_X509: libc::c_int = 1;
|
||||
const X509_LU_CRL: libc::c_int = 2;
|
||||
const X509_LU_X509: core::ffi::c_int = 1;
|
||||
const X509_LU_CRL: core::ffi::c_int = 2;
|
||||
|
||||
unsafe extern "C" {
|
||||
fn X509_OBJECT_get_type(obj: *const sys::X509_OBJECT) -> libc::c_int;
|
||||
fn X509_OBJECT_get_type(obj: *const sys::X509_OBJECT) -> core::ffi::c_int;
|
||||
fn SSL_set_session_id_context(
|
||||
ssl: *mut sys::SSL,
|
||||
sid_ctx: *const libc::c_uchar,
|
||||
sid_ctx_len: libc::c_uint,
|
||||
) -> libc::c_int;
|
||||
sid_ctx: *const core::ffi::c_uchar,
|
||||
sid_ctx_len: core::ffi::c_uint,
|
||||
) -> core::ffi::c_int;
|
||||
fn SSL_get1_session(ssl: *const sys::SSL) -> *mut sys::SSL_SESSION;
|
||||
}
|
||||
|
||||
// SSL session statistics constants (used with SSL_CTX_ctrl)
|
||||
const SSL_CTRL_SESS_NUMBER: libc::c_int = 20;
|
||||
const SSL_CTRL_SESS_CONNECT: libc::c_int = 21;
|
||||
const SSL_CTRL_SESS_CONNECT_GOOD: libc::c_int = 22;
|
||||
const SSL_CTRL_SESS_CONNECT_RENEGOTIATE: libc::c_int = 23;
|
||||
const SSL_CTRL_SESS_ACCEPT: libc::c_int = 24;
|
||||
const SSL_CTRL_SESS_ACCEPT_GOOD: libc::c_int = 25;
|
||||
const SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: libc::c_int = 26;
|
||||
const SSL_CTRL_SESS_HIT: libc::c_int = 27;
|
||||
const SSL_CTRL_SESS_MISSES: libc::c_int = 29;
|
||||
const SSL_CTRL_SESS_TIMEOUTS: libc::c_int = 30;
|
||||
const SSL_CTRL_SESS_CACHE_FULL: libc::c_int = 31;
|
||||
const SSL_CTRL_SESS_NUMBER: core::ffi::c_int = 20;
|
||||
const SSL_CTRL_SESS_CONNECT: core::ffi::c_int = 21;
|
||||
const SSL_CTRL_SESS_CONNECT_GOOD: core::ffi::c_int = 22;
|
||||
const SSL_CTRL_SESS_CONNECT_RENEGOTIATE: core::ffi::c_int = 23;
|
||||
const SSL_CTRL_SESS_ACCEPT: core::ffi::c_int = 24;
|
||||
const SSL_CTRL_SESS_ACCEPT_GOOD: core::ffi::c_int = 25;
|
||||
const SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: core::ffi::c_int = 26;
|
||||
const SSL_CTRL_SESS_HIT: core::ffi::c_int = 27;
|
||||
const SSL_CTRL_SESS_MISSES: core::ffi::c_int = 29;
|
||||
const SSL_CTRL_SESS_TIMEOUTS: core::ffi::c_int = 30;
|
||||
const SSL_CTRL_SESS_CACHE_FULL: core::ffi::c_int = 31;
|
||||
|
||||
// SSL session statistics functions (implemented as macros in OpenSSL)
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_number(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_number(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3451,7 +3458,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_connect(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_connect(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3463,7 +3470,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_connect_good(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_connect_good(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3475,7 +3482,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_connect_renegotiate(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_connect_renegotiate(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3487,7 +3494,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_accept(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_accept(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3499,7 +3506,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_accept_good(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_accept_good(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3511,7 +3518,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_accept_renegotiate(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_accept_renegotiate(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3523,12 +3530,12 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_hits(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_hits(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe { sys::SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_SESS_HIT, 0, core::ptr::null_mut()) }
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_misses(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_misses(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3540,7 +3547,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_timeouts(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_timeouts(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3552,7 +3559,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn SSL_CTX_sess_cache_full(ctx: *const sys::SSL_CTX) -> libc::c_long {
|
||||
unsafe fn SSL_CTX_sess_cache_full(ctx: *const sys::SSL_CTX) -> core::ffi::c_long {
|
||||
unsafe {
|
||||
sys::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
@@ -3566,17 +3573,17 @@ mod _ssl {
|
||||
// DH parameters functions
|
||||
unsafe extern "C" {
|
||||
fn PEM_read_DHparams(
|
||||
fp: *mut libc::FILE,
|
||||
fp: *mut rustpython_host_env::fileutils::CFile,
|
||||
x: *mut *mut sys::DH,
|
||||
cb: *mut libc::c_void,
|
||||
u: *mut libc::c_void,
|
||||
cb: *mut core::ffi::c_void,
|
||||
u: *mut core::ffi::c_void,
|
||||
) -> *mut sys::DH;
|
||||
}
|
||||
|
||||
// OpenSSL BIO helper functions
|
||||
// These are typically macros in OpenSSL, implemented via BIO_ctrl
|
||||
const BIO_CTRL_PENDING: libc::c_int = 10;
|
||||
const BIO_CTRL_SET_EOF: libc::c_int = 2;
|
||||
const BIO_CTRL_PENDING: core::ffi::c_int = 10;
|
||||
const BIO_CTRL_SET_EOF: core::ffi::c_int = 2;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn BIO_ctrl_pending(bio: *mut sys::BIO) -> usize {
|
||||
@@ -3584,14 +3591,17 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn BIO_set_mem_eof_return(bio: *mut sys::BIO, eof: libc::c_int) -> libc::c_int {
|
||||
unsafe fn BIO_set_mem_eof_return(
|
||||
bio: *mut sys::BIO,
|
||||
eof: core::ffi::c_int,
|
||||
) -> core::ffi::c_int {
|
||||
unsafe {
|
||||
sys::BIO_ctrl(
|
||||
bio,
|
||||
BIO_CTRL_SET_EOF,
|
||||
eof as libc::c_long,
|
||||
eof as core::ffi::c_long,
|
||||
core::ptr::null_mut(),
|
||||
) as libc::c_int
|
||||
) as core::ffi::c_int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3721,7 +3731,7 @@ mod _ssl {
|
||||
#[pygetset]
|
||||
fn id(&self, vm: &VirtualMachine) -> PyBytesRef {
|
||||
unsafe {
|
||||
let mut len: libc::c_uint = 0;
|
||||
let mut len: core::ffi::c_uint = 0;
|
||||
let id_ptr = sys::SSL_SESSION_get_id(self.session, &mut len);
|
||||
let id_slice = core::slice::from_raw_parts(id_ptr, len as usize);
|
||||
vm.ctx.new_bytes(id_slice.to_vec())
|
||||
@@ -3976,7 +3986,7 @@ mod _ssl {
|
||||
let mut buf = vec![0u8; 256];
|
||||
let result = sys::SSL_CIPHER_description(
|
||||
cipher,
|
||||
buf.as_mut_ptr() as *mut libc::c_char,
|
||||
buf.as_mut_ptr() as *mut core::ffi::c_char,
|
||||
buf.len() as i32,
|
||||
);
|
||||
if result.is_null() {
|
||||
@@ -4142,7 +4152,7 @@ mod windows {
|
||||
mod bio {
|
||||
//! based off rust-openssl's private `bio` module
|
||||
|
||||
use libc::c_int;
|
||||
use core::ffi::c_int;
|
||||
use openssl::error::ErrorStack;
|
||||
use openssl_sys as sys;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
@@ -39,7 +39,7 @@ pub(crate) mod ssl_cert {
|
||||
let buflen = buflen as usize;
|
||||
let mut buf = Vec::<u8>::with_capacity(buflen + 1);
|
||||
let ret = sys::OBJ_obj2txt(
|
||||
buf.as_mut_ptr() as *mut libc::c_char,
|
||||
buf.as_mut_ptr() as *mut core::ffi::c_char,
|
||||
buf.capacity() as _,
|
||||
ptr,
|
||||
no_name,
|
||||
|
||||
@@ -16,15 +16,15 @@ mod _posixshmem {
|
||||
#[pyarg(any)]
|
||||
name: PyUtf8StrRef,
|
||||
#[pyarg(any)]
|
||||
flags: libc::c_int,
|
||||
flags: core::ffi::c_int,
|
||||
#[pyarg(any, default = 0o600)]
|
||||
mode: libc::mode_t,
|
||||
mode: shm::mode_t,
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn shm_open(args: ShmOpenArgs, vm: &VirtualMachine) -> PyResult<libc::c_int> {
|
||||
fn shm_open(args: ShmOpenArgs, vm: &VirtualMachine) -> PyResult<core::ffi::c_int> {
|
||||
let name = CString::new(args.name.as_str()).map_err(|e| e.into_pyexception(vm))?;
|
||||
let mode: libc::c_uint = args.mode as _;
|
||||
let mode: core::ffi::c_uint = args.mode as _;
|
||||
shm::shm_open(name.as_c_str(), args.flags, mode).map_err(|e| e.into_pyexception(vm))
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ mod _posixsubprocess {
|
||||
use crate::vm::{PyResult, VirtualMachine, convert::IntoPyException};
|
||||
|
||||
#[pyfunction]
|
||||
fn fork_exec(args: ForkExecArgs<'_>, vm: &VirtualMachine) -> PyResult<libc::pid_t> {
|
||||
fn fork_exec(args: ForkExecArgs<'_>, vm: &VirtualMachine) -> PyResult<host_posix::pid_t> {
|
||||
// Check for interpreter shutdown when preexec_fn is used
|
||||
if args.preexec_fn.is_some()
|
||||
&& vm
|
||||
@@ -85,7 +85,7 @@ impl AsRef<CStr> for CStrPathLike {
|
||||
|
||||
#[derive(Default)]
|
||||
struct CharPtrVec<'a> {
|
||||
vec: Vec<*const libc::c_char>,
|
||||
vec: Vec<*const host_posix::c_char>,
|
||||
marker: PhantomData<Vec<&'a CStr>>,
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ impl<'a> Deref for CharPtrVec<'a> {
|
||||
type Target = CharPtrSlice<'a>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe {
|
||||
&*(self.vec.as_slice() as *const [*const libc::c_char] as *const CharPtrSlice<'a>)
|
||||
&*(self.vec.as_slice() as *const [*const host_posix::c_char] as *const CharPtrSlice<'a>)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,11 +115,11 @@ impl<'a> Deref for CharPtrVec<'a> {
|
||||
#[repr(transparent)]
|
||||
struct CharPtrSlice<'a> {
|
||||
marker: PhantomData<[&'a CStr]>,
|
||||
slice: [*const libc::c_char],
|
||||
slice: [*const host_posix::c_char],
|
||||
}
|
||||
|
||||
impl CharPtrSlice<'_> {
|
||||
const fn as_ptr(&self) -> *const *const libc::c_char {
|
||||
const fn as_ptr(&self) -> *const *const host_posix::c_char {
|
||||
self.slice.as_ptr()
|
||||
}
|
||||
}
|
||||
@@ -254,7 +254,7 @@ gen_args! {
|
||||
errpipe_write: Fd,
|
||||
restore_signals: bool,
|
||||
call_setsid: bool,
|
||||
pgid_to_set: libc::pid_t,
|
||||
pgid_to_set: host_posix::pid_t,
|
||||
gid: Option<RawGid>,
|
||||
groups_list: Option<PyListRef>,
|
||||
uid: Option<RawUid>,
|
||||
|
||||
@@ -16,7 +16,7 @@ mod resource {
|
||||
#[cfg_attr(target_os = "android", expect(deprecated))]
|
||||
const RLIM_NLIMITS: i32 = cfg_select! {
|
||||
target_os = "android" => {
|
||||
libc::RLIM_NLIMITS
|
||||
host_resource::RLIM_NLIMITS
|
||||
}
|
||||
_ => {
|
||||
// This constant isn't abi-stable across os versions, so we just
|
||||
@@ -28,18 +28,18 @@ mod resource {
|
||||
|
||||
// TODO: RLIMIT_OFILE,
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use host_resource::{
|
||||
RLIM_INFINITY, RLIMIT_AS, RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE,
|
||||
RLIMIT_MEMLOCK, RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_RSS, RLIMIT_STACK,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
|
||||
#[pyattr]
|
||||
use libc::{RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_RTPRIO, RLIMIT_SIGPENDING};
|
||||
use host_resource::{RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_RTPRIO, RLIMIT_SIGPENDING};
|
||||
// TODO: I think this is supposed to be defined for all linux_like?
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pyattr]
|
||||
use libc::RLIMIT_RTTIME;
|
||||
use host_resource::RLIMIT_RTTIME;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
@@ -48,41 +48,41 @@ mod resource {
|
||||
target_os = "illumos"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::RLIMIT_SBSIZE;
|
||||
use host_resource::RLIMIT_SBSIZE;
|
||||
|
||||
#[cfg(any(target_os = "freebsd", target_os = "solaris", target_os = "illumos"))]
|
||||
#[pyattr]
|
||||
use libc::{RLIMIT_NPTS, RLIMIT_SWAP};
|
||||
use host_resource::{RLIMIT_NPTS, RLIMIT_SWAP};
|
||||
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
#[pyattr]
|
||||
use libc::RLIMIT_VMEM;
|
||||
use host_resource::RLIMIT_VMEM;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "freebsd"))]
|
||||
#[pyattr]
|
||||
use libc::RUSAGE_THREAD;
|
||||
use host_resource::RUSAGE_THREAD;
|
||||
#[cfg(not(any(target_os = "windows", target_os = "redox")))]
|
||||
#[pyattr]
|
||||
use libc::{RUSAGE_CHILDREN, RUSAGE_SELF};
|
||||
use host_resource::{RUSAGE_CHILDREN, RUSAGE_SELF};
|
||||
|
||||
#[pystruct_sequence_data]
|
||||
struct RUsageData {
|
||||
ru_utime: f64,
|
||||
ru_stime: f64,
|
||||
ru_maxrss: libc::c_long,
|
||||
ru_ixrss: libc::c_long,
|
||||
ru_idrss: libc::c_long,
|
||||
ru_isrss: libc::c_long,
|
||||
ru_minflt: libc::c_long,
|
||||
ru_majflt: libc::c_long,
|
||||
ru_nswap: libc::c_long,
|
||||
ru_inblock: libc::c_long,
|
||||
ru_oublock: libc::c_long,
|
||||
ru_msgsnd: libc::c_long,
|
||||
ru_msgrcv: libc::c_long,
|
||||
ru_nsignals: libc::c_long,
|
||||
ru_nvcsw: libc::c_long,
|
||||
ru_nivcsw: libc::c_long,
|
||||
ru_maxrss: host_resource::c_long,
|
||||
ru_ixrss: host_resource::c_long,
|
||||
ru_idrss: host_resource::c_long,
|
||||
ru_isrss: host_resource::c_long,
|
||||
ru_minflt: host_resource::c_long,
|
||||
ru_majflt: host_resource::c_long,
|
||||
ru_nswap: host_resource::c_long,
|
||||
ru_inblock: host_resource::c_long,
|
||||
ru_oublock: host_resource::c_long,
|
||||
ru_msgsnd: host_resource::c_long,
|
||||
ru_msgrcv: host_resource::c_long,
|
||||
ru_nsignals: host_resource::c_long,
|
||||
ru_nvcsw: host_resource::c_long,
|
||||
ru_nivcsw: host_resource::c_long,
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
@@ -94,7 +94,8 @@ mod resource {
|
||||
|
||||
impl From<host_resource::RUsage> for RUsageData {
|
||||
fn from(rusage: host_resource::RUsage) -> Self {
|
||||
let tv = |tv: libc::timeval| tv.tv_sec as f64 + (tv.tv_usec as f64 / 1_000_000.0);
|
||||
let tv =
|
||||
|tv: host_resource::timeval| tv.tv_sec as f64 + (tv.tv_usec as f64 / 1_000_000.0);
|
||||
Self {
|
||||
ru_utime: tv(rusage.ru_utime),
|
||||
ru_stime: tv(rusage.ru_stime),
|
||||
@@ -128,13 +129,13 @@ mod resource {
|
||||
})
|
||||
}
|
||||
|
||||
struct Limits(libc::rlimit);
|
||||
struct Limits(host_resource::rlimit);
|
||||
|
||||
impl<'a> TryFromBorrowedObject<'a> for Limits {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
|
||||
let seq: Vec<libc::rlim_t> = obj.try_to_value(vm)?;
|
||||
let seq: Vec<host_resource::rlim_t> = obj.try_to_value(vm)?;
|
||||
match *seq {
|
||||
[cur, max] => Ok(Self(libc::rlimit {
|
||||
[cur, max] => Ok(Self(host_resource::rlimit {
|
||||
rlim_cur: cur & RLIM_INFINITY,
|
||||
rlim_max: max & RLIM_INFINITY,
|
||||
})),
|
||||
@@ -149,14 +150,14 @@ mod resource {
|
||||
}
|
||||
}
|
||||
|
||||
fn py2rlim(obj: PyIntRef, vm: &VirtualMachine) -> PyResult<libc::rlim_t> {
|
||||
fn py2rlim(obj: PyIntRef, vm: &VirtualMachine) -> PyResult<host_resource::rlim_t> {
|
||||
let value = obj.try_to_primitive::<isize>(vm)?;
|
||||
|
||||
if value.is_negative() {
|
||||
return Err(vm.new_value_error("Cannot convert negative int"));
|
||||
}
|
||||
|
||||
libc::rlim_t::try_from(value)
|
||||
host_resource::rlim_t::try_from(value)
|
||||
.map_err(|_| vm.new_overflow_error("Python int too large to convert to C rlim_t"))
|
||||
}
|
||||
|
||||
@@ -164,7 +165,7 @@ mod resource {
|
||||
fn getrlimit(resource: PyIntRef, vm: &VirtualMachine) -> PyResult<Limits> {
|
||||
let resource = py2rlim(resource, vm)?;
|
||||
|
||||
if resource >= RLIM_NLIMITS as libc::rlim_t {
|
||||
if resource >= RLIM_NLIMITS as host_resource::rlim_t {
|
||||
return Err(vm.new_value_error("invalid resource specified"));
|
||||
}
|
||||
|
||||
@@ -176,7 +177,7 @@ mod resource {
|
||||
fn setrlimit(resource: PyIntRef, limits: Limits, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let resource = py2rlim(resource, vm)?;
|
||||
|
||||
if resource >= RLIM_NLIMITS as libc::rlim_t {
|
||||
if resource >= RLIM_NLIMITS as host_resource::rlim_t {
|
||||
return Err(vm.new_value_error("invalid resource specified"));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ mod _scproxy {
|
||||
builtins::{PyDict, PyDictRef, PyStr},
|
||||
convert::ToPyObject,
|
||||
};
|
||||
use system_configuration::core_foundation::{
|
||||
use rustpython_host_env::system_configuration::core_foundation::{
|
||||
array::CFArray,
|
||||
base::{CFType, FromVoid, TCFType},
|
||||
dictionary::CFDictionary,
|
||||
number::CFNumber,
|
||||
string::{CFString, CFStringRef},
|
||||
};
|
||||
use system_configuration::sys::{
|
||||
use rustpython_host_env::system_configuration::sys::{
|
||||
dynamic_store_copy_specific::SCDynamicStoreCopyProxies, schema_definitions::*,
|
||||
};
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ mod decl {
|
||||
|
||||
#[cfg(unix)]
|
||||
#[pyattr]
|
||||
use libc::{POLLERR, POLLHUP, POLLIN, POLLNVAL, POLLOUT, POLLPRI};
|
||||
use host_select::{POLLERR, POLLHUP, POLLIN, POLLNVAL, POLLOUT, POLLPRI};
|
||||
|
||||
#[cfg(unix)]
|
||||
pub(super) mod poll {
|
||||
@@ -261,7 +261,8 @@ mod decl {
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_EVENTS: i16 = libc::POLLIN | libc::POLLPRI | libc::POLLOUT;
|
||||
const DEFAULT_EVENTS: i16 =
|
||||
host_select::POLLIN | host_select::POLLPRI | host_select::POLLOUT;
|
||||
|
||||
#[pyclass]
|
||||
impl PyPoll {
|
||||
@@ -315,7 +316,7 @@ mod decl {
|
||||
loop {
|
||||
match vm.allow_threads(|| host_select::poll_fds(&mut fds, poll_timeout)) {
|
||||
Ok(_) => break,
|
||||
Err(err) if err.raw_os_error() == Some(libc::EINTR) => {
|
||||
Err(err) if err.raw_os_error() == Some(host_select::EINTR) => {
|
||||
vm.check_signals()?
|
||||
}
|
||||
Err(err) => return Err(err.into_pyexception(vm)),
|
||||
@@ -346,14 +347,14 @@ mod decl {
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use host_select::{
|
||||
EPOLL_CLOEXEC, EPOLLERR, EPOLLEXCLUSIVE, EPOLLHUP, EPOLLIN, EPOLLMSG, EPOLLONESHOT,
|
||||
EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDHUP, EPOLLRDNORM, EPOLLWAKEUP, EPOLLWRBAND,
|
||||
EPOLLWRNORM,
|
||||
};
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
|
||||
#[pyattr]
|
||||
const EPOLLET: u32 = libc::EPOLLET as u32;
|
||||
const EPOLLET: u32 = host_select::EPOLLET as u32;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
|
||||
pub(super) mod epoll {
|
||||
@@ -392,7 +393,7 @@ mod decl {
|
||||
if let ..=-2 | 0 = args.sizehint {
|
||||
return Err(vm.new_value_error("negative sizehint"));
|
||||
}
|
||||
if !matches!(args.flags, 0 | libc::EPOLL_CLOEXEC) {
|
||||
if !matches!(args.flags, 0 | host_select::EPOLL_CLOEXEC) {
|
||||
return Err(vm.new_os_error("invalid flags"));
|
||||
}
|
||||
Self::new().map_err(|e| e.into_pyexception(vm))
|
||||
@@ -497,7 +498,7 @@ mod decl {
|
||||
"maxevents must be greater than 0, got {maxevents}"
|
||||
)));
|
||||
}
|
||||
-1 => libc::FD_SETSIZE - 1,
|
||||
-1 => host_select::FD_SETSIZE - 1,
|
||||
_ => maxevents as usize,
|
||||
};
|
||||
|
||||
|
||||
+44
-46
@@ -45,8 +45,8 @@ mod _socket {
|
||||
time::Duration,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use host_socket::raw::Socket;
|
||||
use num_traits::ToPrimitive;
|
||||
use socket2::Socket;
|
||||
use std::{
|
||||
ffi,
|
||||
io::{self, Read, Write},
|
||||
@@ -885,9 +885,9 @@ mod _socket {
|
||||
|
||||
fn get_raw_sock(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<RawSocket> {
|
||||
#[cfg(unix)]
|
||||
type CastFrom = libc::c_long;
|
||||
type CastFrom = core::ffi::c_long;
|
||||
#[cfg(windows)]
|
||||
type CastFrom = libc::c_longlong;
|
||||
type CastFrom = core::ffi::c_longlong;
|
||||
|
||||
// should really just be to_index() but test_socket tests the error messages explicitly
|
||||
if obj.fast_isinstance(vm.ctx.types.float_type) {
|
||||
@@ -1109,7 +1109,7 @@ mod _socket {
|
||||
addr: PyObjectRef,
|
||||
caller: &str,
|
||||
vm: &VirtualMachine,
|
||||
) -> Result<socket2::SockAddr, IoOrPyException> {
|
||||
) -> Result<host_socket::raw::SockAddr, IoOrPyException> {
|
||||
let family = self.family.load();
|
||||
match family {
|
||||
#[cfg(unix)]
|
||||
@@ -1122,7 +1122,7 @@ mod _socket {
|
||||
ArgStrOrBytesLike::Buf(_) => ffi::OsStr::from_bytes(bytes).into(),
|
||||
ArgStrOrBytesLike::Str(s) => vm.fsencode(s)?,
|
||||
};
|
||||
socket2::SockAddr::unix(path)
|
||||
host_socket::raw::SockAddr::unix(path)
|
||||
.map_err(|_| vm.new_os_error("AF_UNIX path too long").into())
|
||||
}
|
||||
c::AF_INET => {
|
||||
@@ -1214,19 +1214,18 @@ mod _socket {
|
||||
};
|
||||
|
||||
// Create sockaddr_can
|
||||
let mut storage: libc::sockaddr_storage = unsafe { core::mem::zeroed() };
|
||||
let can_addr =
|
||||
&mut storage as *mut libc::sockaddr_storage as *mut libc::sockaddr_can;
|
||||
let mut storage: c::sockaddr_storage = unsafe { core::mem::zeroed() };
|
||||
let can_addr = &mut storage as *mut c::sockaddr_storage as *mut c::sockaddr_can;
|
||||
unsafe {
|
||||
(*can_addr).can_family = libc::AF_CAN as libc::sa_family_t;
|
||||
(*can_addr).can_family = c::AF_CAN as c::sa_family_t;
|
||||
(*can_addr).can_ifindex = ifindex;
|
||||
}
|
||||
let storage: socket2::SockAddrStorage =
|
||||
let storage: host_socket::raw::SockAddrStorage =
|
||||
unsafe { core::mem::transmute(storage) };
|
||||
Ok(unsafe {
|
||||
socket2::SockAddr::new(
|
||||
host_socket::raw::SockAddr::new(
|
||||
storage,
|
||||
core::mem::size_of::<libc::sockaddr_can>() as libc::socklen_t,
|
||||
core::mem::size_of::<c::sockaddr_can>() as c::socklen_t,
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -1273,11 +1272,10 @@ mod _socket {
|
||||
}
|
||||
|
||||
// Create sockaddr_alg
|
||||
let mut storage: libc::sockaddr_storage = unsafe { core::mem::zeroed() };
|
||||
let alg_addr =
|
||||
&mut storage as *mut libc::sockaddr_storage as *mut libc::sockaddr_alg;
|
||||
let mut storage: c::sockaddr_storage = unsafe { core::mem::zeroed() };
|
||||
let alg_addr = &mut storage as *mut c::sockaddr_storage as *mut c::sockaddr_alg;
|
||||
unsafe {
|
||||
(*alg_addr).salg_family = libc::AF_ALG as libc::sa_family_t;
|
||||
(*alg_addr).salg_family = c::AF_ALG as c::sa_family_t;
|
||||
// Copy type string
|
||||
for (i, b) in type_str.bytes().enumerate() {
|
||||
(*alg_addr).salg_type[i] = b;
|
||||
@@ -1287,12 +1285,12 @@ mod _socket {
|
||||
(*alg_addr).salg_name[i] = b;
|
||||
}
|
||||
}
|
||||
let storage: socket2::SockAddrStorage =
|
||||
let storage: host_socket::raw::SockAddrStorage =
|
||||
unsafe { core::mem::transmute(storage) };
|
||||
Ok(unsafe {
|
||||
socket2::SockAddr::new(
|
||||
host_socket::raw::SockAddr::new(
|
||||
storage,
|
||||
core::mem::size_of::<libc::sockaddr_alg>() as libc::socklen_t,
|
||||
core::mem::size_of::<c::sockaddr_alg>() as c::socklen_t,
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -1773,7 +1771,7 @@ mod _socket {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<usize> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
let mut msg = socket2::MsgHdr::new();
|
||||
let mut msg = host_socket::raw::MsgHdr::new();
|
||||
|
||||
let sockaddr;
|
||||
if let Some(addr) = addr.flatten() {
|
||||
@@ -1896,9 +1894,9 @@ mod _socket {
|
||||
|
||||
// Build address tuple
|
||||
let address = if let Some(address) = msg.address {
|
||||
let storage: socket2::SockAddrStorage =
|
||||
let storage: host_socket::raw::SockAddrStorage =
|
||||
unsafe { core::mem::transmute(address.storage) };
|
||||
let addr = unsafe { socket2::SockAddr::new(storage, address.len as _) };
|
||||
let addr = unsafe { host_socket::raw::SockAddr::new(storage, address.len as _) };
|
||||
get_addr_tuple(&addr, vm)
|
||||
} else {
|
||||
vm.ctx.none()
|
||||
@@ -2260,7 +2258,7 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_addr_tuple(addr: &socket2::SockAddr, vm: &VirtualMachine) -> PyObjectRef {
|
||||
fn get_addr_tuple(addr: &host_socket::raw::SockAddr, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if let Some(addr) = addr.as_socket() {
|
||||
return get_ip_addr_tuple(&addr, vm);
|
||||
}
|
||||
@@ -2280,9 +2278,9 @@ mod _socket {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let family = addr.family();
|
||||
if family == libc::AF_CAN as libc::sa_family_t {
|
||||
if family == c::AF_CAN as c::sa_family_t {
|
||||
// AF_CAN address: (interface_name,) or (interface_name, can_id)
|
||||
let can_addr = unsafe { &*(addr.as_ptr() as *const libc::sockaddr_can) };
|
||||
let can_addr = unsafe { &*(addr.as_ptr() as *const c::sockaddr_can) };
|
||||
let ifindex = can_addr.can_ifindex;
|
||||
let ifname = if ifindex == 0 {
|
||||
String::new()
|
||||
@@ -2291,9 +2289,9 @@ mod _socket {
|
||||
};
|
||||
return vm.ctx.new_tuple(vec![vm.ctx.new_str(ifname).into()]).into();
|
||||
}
|
||||
if family == libc::AF_ALG as libc::sa_family_t {
|
||||
if family == c::AF_ALG as c::sa_family_t {
|
||||
// AF_ALG address: (type, name)
|
||||
let alg_addr = unsafe { &*(addr.as_ptr() as *const libc::sockaddr_alg) };
|
||||
let alg_addr = unsafe { &*(addr.as_ptr() as *const c::sockaddr_alg) };
|
||||
let type_bytes = &alg_addr.salg_type;
|
||||
let name_bytes = &alg_addr.salg_name;
|
||||
let type_nul = memchr::memchr(b'\0', type_bytes).unwrap_or(type_bytes.len());
|
||||
@@ -2319,7 +2317,7 @@ mod _socket {
|
||||
audit.call((vm.ctx.new_str("socket.gethostname"),), vm)?;
|
||||
}
|
||||
|
||||
gethostname::gethostname()
|
||||
rustpython_host_env::socket::hostname()
|
||||
.into_string()
|
||||
.map(|hostname| vm.ctx.new_str(hostname))
|
||||
.map_err(|err| vm.new_os_error(err.into_string().unwrap()))
|
||||
@@ -2348,7 +2346,7 @@ mod _socket {
|
||||
Ok(vm.ctx.new_str(Ipv4Addr::from(*packed_ip).to_string()))
|
||||
}
|
||||
|
||||
fn cstr_opt_as_ptr(x: &OptionalArg<ffi::CString>) -> *const libc::c_char {
|
||||
fn cstr_opt_as_ptr(x: &OptionalArg<ffi::CString>) -> *const core::ffi::c_char {
|
||||
x.as_ref().map_or_else(core::ptr::null, |s| s.as_ptr())
|
||||
}
|
||||
|
||||
@@ -2593,7 +2591,7 @@ mod _socket {
|
||||
opts: GAIOptions,
|
||||
vm: &VirtualMachine,
|
||||
) -> Result<Vec<PyObjectRef>, IoOrPyException> {
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
let hints = host_socket::dns::AddrInfoHints {
|
||||
socktype: opts.ty,
|
||||
protocol: opts.proto,
|
||||
address: opts.family,
|
||||
@@ -2646,7 +2644,7 @@ mod _socket {
|
||||
};
|
||||
let port = port_encoded.as_deref();
|
||||
|
||||
let addrs = dns_lookup::getaddrinfo(host, port, Some(hints))
|
||||
let addrs = host_socket::dns::getaddrinfo(host, port, Some(hints))
|
||||
.map_err(|err| convert_socket_error(vm, err, SocketError::GaiError))?;
|
||||
|
||||
let list = addrs
|
||||
@@ -2672,7 +2670,7 @@ mod _socket {
|
||||
vm: &VirtualMachine,
|
||||
) -> Result<(String, PyListRef, PyListRef), IoOrPyException> {
|
||||
let addr = get_addr(vm, addr, c::AF_UNSPEC)?;
|
||||
let (hostname, _) = dns_lookup::getnameinfo(&addr, 0)
|
||||
let (hostname, _) = host_socket::dns::getnameinfo(&addr, 0)
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::HError))?;
|
||||
Ok((
|
||||
hostname,
|
||||
@@ -2697,7 +2695,7 @@ mod _socket {
|
||||
vm: &VirtualMachine,
|
||||
) -> Result<(String, PyListRef, PyListRef), IoOrPyException> {
|
||||
let addr = get_addr(vm, name, c::AF_INET)?;
|
||||
let (hostname, _) = dns_lookup::getnameinfo(&addr, 0)
|
||||
let (hostname, _) = host_socket::dns::getnameinfo(&addr, 0)
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::HError))?;
|
||||
Ok((
|
||||
hostname,
|
||||
@@ -2772,7 +2770,7 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
let (addr, flowinfo, scopeid) = Address::from_tuple_ipv6(&address, vm)?;
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
let hints = host_socket::dns::AddrInfoHints {
|
||||
address: c::AF_UNSPEC,
|
||||
socktype: c::SOCK_DGRAM,
|
||||
flags: c::AI_NUMERICHOST,
|
||||
@@ -2780,7 +2778,7 @@ mod _socket {
|
||||
};
|
||||
let service = addr.port.to_string();
|
||||
let host_str = addr.host.as_str();
|
||||
let mut res = dns_lookup::getaddrinfo(Some(host_str), Some(&service), Some(hints))
|
||||
let mut res = host_socket::dns::getaddrinfo(Some(host_str), Some(&service), Some(hints))
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::GaiError))?
|
||||
.filter_map(Result::ok);
|
||||
let mut ainfo = res.next().unwrap();
|
||||
@@ -2800,7 +2798,7 @@ mod _socket {
|
||||
addr.set_scope_id(scopeid);
|
||||
}
|
||||
}
|
||||
dns_lookup::getnameinfo(&ainfo.sockaddr, flags)
|
||||
host_socket::dns::getnameinfo(&ainfo.sockaddr, flags)
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::GaiError))
|
||||
}
|
||||
|
||||
@@ -2811,8 +2809,8 @@ mod _socket {
|
||||
socket_kind: OptionalArg<i32>,
|
||||
proto: OptionalArg<i32>,
|
||||
) -> Result<(PySocket, PySocket), IoOrPyException> {
|
||||
let family = family.unwrap_or(libc::AF_UNIX);
|
||||
let socket_kind = socket_kind.unwrap_or(libc::SOCK_STREAM);
|
||||
let family = family.unwrap_or(c::AF_UNIX);
|
||||
let socket_kind = socket_kind.unwrap_or(c::SOCK_STREAM);
|
||||
let proto = proto.unwrap_or(0);
|
||||
let (a, b) = Socket::pair(family.into(), socket_kind.into(), Some(proto.into()))?;
|
||||
let py_a = PySocket::default();
|
||||
@@ -2839,7 +2837,7 @@ mod _socket {
|
||||
{
|
||||
let name = name.to_cstring(vm)?;
|
||||
// in case 'if_nametoindex' does not set errno
|
||||
rustpython_host_env::os::set_errno(libc::ENODEV);
|
||||
rustpython_host_env::os::set_errno(c::ENODEV);
|
||||
let ret = unsafe { c::if_nametoindex(name.as_ptr() as _) };
|
||||
if ret == 0 {
|
||||
Err(vm.new_last_errno_error())
|
||||
@@ -2860,7 +2858,7 @@ mod _socket {
|
||||
{
|
||||
let mut buf = [0; c::IF_NAMESIZE + 1];
|
||||
// in case 'if_indextoname' does not set errno
|
||||
rustpython_host_env::os::set_errno(libc::ENXIO);
|
||||
rustpython_host_env::os::set_errno(c::ENXIO);
|
||||
let ret = unsafe { c::if_indextoname(index, buf.as_mut_ptr()) };
|
||||
if ret.is_null() {
|
||||
Err(vm.new_last_errno_error())
|
||||
@@ -2912,13 +2910,13 @@ mod _socket {
|
||||
) -> Result<SocketAddr, IoOrPyException> {
|
||||
let name = pyname.as_str();
|
||||
if name.is_empty() {
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
let hints = host_socket::dns::AddrInfoHints {
|
||||
address: af,
|
||||
socktype: c::SOCK_DGRAM,
|
||||
flags: c::AI_PASSIVE,
|
||||
protocol: 0,
|
||||
};
|
||||
let mut res = dns_lookup::getaddrinfo(None, Some("0"), Some(hints))
|
||||
let mut res = host_socket::dns::getaddrinfo(None, Some("0"), Some(hints))
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::GaiError))?;
|
||||
let ainfo = res.next().unwrap()?;
|
||||
if res.next().is_some() {
|
||||
@@ -2951,7 +2949,7 @@ mod _socket {
|
||||
{
|
||||
return Ok(SocketAddr::V6(net::SocketAddrV6::new(addr, 0, 0, 0)));
|
||||
}
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
let hints = host_socket::dns::AddrInfoHints {
|
||||
address: af,
|
||||
..Default::default()
|
||||
};
|
||||
@@ -2961,7 +2959,7 @@ mod _socket {
|
||||
.encode_text(pyname.into_wtf8(), "idna", None, vm)?;
|
||||
let name = core::str::from_utf8(name.as_bytes())
|
||||
.map_err(|_| vm.new_runtime_error("idna output is not utf8"))?;
|
||||
let mut res = dns_lookup::getaddrinfo(Some(name), None, Some(hints))
|
||||
let mut res = host_socket::dns::getaddrinfo(Some(name), None, Some(hints))
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::GaiError))?;
|
||||
Ok(res.next().unwrap().map(|ainfo| ainfo.sockaddr)?)
|
||||
}
|
||||
@@ -3027,10 +3025,10 @@ mod _socket {
|
||||
|
||||
fn convert_socket_error(
|
||||
vm: &VirtualMachine,
|
||||
err: dns_lookup::LookupError,
|
||||
err: host_socket::dns::LookupError,
|
||||
err_kind: SocketError,
|
||||
) -> IoOrPyException {
|
||||
if let dns_lookup::LookupErrorKind::System = err.kind() {
|
||||
if let host_socket::dns::LookupErrorKind::System = err.kind() {
|
||||
return io::Error::from(err).into();
|
||||
}
|
||||
let strerr = {
|
||||
|
||||
@@ -13,7 +13,7 @@ mod syslog {
|
||||
use rustpython_host_env::syslog as host_syslog;
|
||||
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use host_syslog::{
|
||||
LOG_ALERT, LOG_AUTH, LOG_CONS, LOG_CRIT, LOG_DAEMON, LOG_DEBUG, LOG_EMERG, LOG_ERR,
|
||||
LOG_INFO, LOG_KERN, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5,
|
||||
LOG_LOCAL6, LOG_LOCAL7, LOG_LPR, LOG_MAIL, LOG_NDELAY, LOG_NEWS, LOG_NOTICE, LOG_NOWAIT,
|
||||
@@ -22,7 +22,7 @@ mod syslog {
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[pyattr]
|
||||
use libc::{LOG_AUTHPRIV, LOG_CRON, LOG_PERROR};
|
||||
use host_syslog::{LOG_AUTHPRIV, LOG_CRON, LOG_PERROR};
|
||||
|
||||
fn get_argv(vm: &VirtualMachine) -> Option<PyStrRef> {
|
||||
if let Some(argv) = vm.state.config.settings.argv.first()
|
||||
|
||||
@@ -99,6 +99,41 @@ mod termios {
|
||||
))]
|
||||
#[pyattr]
|
||||
use host_termios::{CBAUD, CIBAUD, IUCLC, OLCUC, XCASE};
|
||||
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
||||
#[pyattr]
|
||||
use host_termios::{CSTART, CSTOP, CSWTCH};
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use host_termios::{FIOASYNC, TIOCGETD, TIOCSETD};
|
||||
#[pyattr]
|
||||
use host_termios::{FIOCLEX, FIONBIO, TIOCGWINSZ, TIOCSWINSZ};
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use host_termios::{
|
||||
FIONCLEX, FIONREAD, TIOCEXCL, TIOCM_CAR, TIOCM_CD, TIOCM_CTS, TIOCM_DSR, TIOCM_DTR,
|
||||
TIOCM_LE, TIOCM_RI, TIOCM_RNG, TIOCM_RTS, TIOCM_SR, TIOCM_ST, TIOCMBIC, TIOCMBIS, TIOCMGET,
|
||||
TIOCMSET, TIOCNXCL, TIOCSCTTY,
|
||||
};
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use host_termios::{
|
||||
IBSHIFT, TCFLSH, TCGETA, TCGETS, TCSBRK, TCSETA, TCSETAF, TCSETAW, TCSETS, TCSETSF,
|
||||
TCSETSW, TCXONC, TIOCGSERIAL, TIOCGSOFTCAR, TIOCINQ, TIOCLINUX, TIOCSSOFTCAR, XTABS,
|
||||
};
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
@@ -109,47 +144,6 @@ mod termios {
|
||||
))]
|
||||
#[pyattr]
|
||||
use host_termios::{TAB0, TABDLY};
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use host_termios::{VSWTC, VSWTC as VSWTCH};
|
||||
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
||||
#[pyattr]
|
||||
use host_termios::{VSWTCH, VSWTCH as VSWTC};
|
||||
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
||||
#[pyattr]
|
||||
use libc::{CSTART, CSTOP, CSWTCH};
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{FIOASYNC, TIOCGETD, TIOCSETD};
|
||||
#[pyattr]
|
||||
use libc::{FIOCLEX, FIONBIO, TIOCGWINSZ, TIOCSWINSZ};
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
FIONCLEX, FIONREAD, TIOCEXCL, TIOCM_CAR, TIOCM_CD, TIOCM_CTS, TIOCM_DSR, TIOCM_DTR,
|
||||
TIOCM_LE, TIOCM_RI, TIOCM_RNG, TIOCM_RTS, TIOCM_SR, TIOCM_ST, TIOCMBIC, TIOCMBIS, TIOCMGET,
|
||||
TIOCMSET, TIOCNXCL, TIOCSCTTY,
|
||||
};
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
IBSHIFT, TCFLSH, TCGETA, TCGETS, TCSBRK, TCSETA, TCSETAF, TCSETAW, TCSETS, TCSETSF,
|
||||
TCSETSW, TCXONC, TIOCGSERIAL, TIOCGSOFTCAR, TIOCINQ, TIOCLINUX, TIOCSSOFTCAR, XTABS,
|
||||
};
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
@@ -158,13 +152,19 @@ mod termios {
|
||||
target_os = "macos"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{TIOCCONS, TIOCGPGRP, TIOCOUTQ, TIOCSPGRP, TIOCSTI};
|
||||
use host_termios::{TIOCCONS, TIOCGPGRP, TIOCOUTQ, TIOCSPGRP, TIOCSTI};
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use host_termios::{
|
||||
TIOCNOTTY, TIOCPKT, TIOCPKT_DATA, TIOCPKT_DOSTOP, TIOCPKT_FLUSHREAD, TIOCPKT_FLUSHWRITE,
|
||||
TIOCPKT_NOSTOP, TIOCPKT_START, TIOCPKT_STOP,
|
||||
};
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use host_termios::{VSWTC, VSWTC as VSWTCH};
|
||||
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
||||
#[pyattr]
|
||||
use host_termios::{VSWTCH, VSWTCH as VSWTC};
|
||||
|
||||
#[pyfunction]
|
||||
fn tcgetattr(fd: PyObjectRef, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
|
||||
|
||||
@@ -3,16 +3,13 @@ pub(crate) use _uuid::module_def;
|
||||
#[pymodule]
|
||||
mod _uuid {
|
||||
use crate::{builtins::PyNone, vm::VirtualMachine};
|
||||
use mac_address::get_mac_address;
|
||||
use std::sync::OnceLock;
|
||||
use uuid::{ContextV1, Uuid, timestamp::Timestamp};
|
||||
|
||||
fn get_node_id() -> [u8; 6] {
|
||||
match get_mac_address() {
|
||||
Ok(Some(_ma)) => get_mac_address().unwrap().unwrap().bytes(),
|
||||
// os_random is expensive, but this is only ever called once
|
||||
_ => rustpython_common::rand::os_random::<6>(),
|
||||
}
|
||||
// os_random is expensive, but this is only ever called once
|
||||
rustpython_host_env::socket::mac_address()
|
||||
.unwrap_or_else(rustpython_common::rand::os_random::<6>)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
@@ -91,8 +91,6 @@ writeable = { workspace = true }
|
||||
exitcode = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
rustyline = { workspace = true }
|
||||
which = { workspace = true }
|
||||
widestring = { workspace = true }
|
||||
|
||||
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
|
||||
|
||||
@@ -359,7 +359,7 @@ fn get_executable_path() -> Option<PathBuf> {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let exec_arg = env::args_os().next()?;
|
||||
which::which(exec_arg).ok()
|
||||
crate::host_env::fs::which(exec_arg)
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ pub mod py_io;
|
||||
pub mod py_serde;
|
||||
|
||||
pub mod gc_state;
|
||||
pub mod readline;
|
||||
pub use rustpython_host_env::readline;
|
||||
pub mod recursion;
|
||||
pub mod scope;
|
||||
pub mod sequence;
|
||||
|
||||
Reference in new issue
Block a user