mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
host_env: export O_* flags, wasm errno, and posix names (#8788)
* host_env: export O_* flags and wasm errno Re-export open(2) flags from os. wasm32-unknown-unknown uses Darwin/BSD numbers, matching the guest errno table. Expand errno_wasm to that table plus strerror. Assisted-by: Claude * stdlib: take O_* open flags from host_env os, posix, and nt re-export the host_env names instead of libc. Assisted-by: Claude * host_env: export remaining posix integer names Publish wait, RTLD, SCHED, SEEK, PRIO, CLD, AT, lockf, and statvfs flags so posix and os stop taking them from libc. Assisted-by: Claude * stdlib: take remaining posix names from host_env posix and os re-export wait, RTLD, SCHED, SEEK, PRIO, and statvfs flags from host_env. Assisted-by: Claude * host_env: define AT_EACCESS on Android bionic's libc crate does not export AT_EACCESS. Use the Linux fcntl value there. The eval-breaker unit test now waits for STOP_BIT to be clear instead of requiring the whole process-wide breaker word empty. Assisted-by: Claude * vm: gate stop_bit_set to tests Clippy builds the lib without tests, so the helper and its re-export were unused. Assisted-by: Claude
This commit is contained in:
1 parent
2b8c095e11
commit
01bd5ca370
15 files changed
+509
-87
No files matched your search
@@ -1,10 +1,86 @@
|
||||
//! Errno numbers for `wasm32-unknown-unknown`.
|
||||
//!
|
||||
//! There is no libc errno table. The values are the Linux ABI the stdlib
|
||||
//! and `OSError` subclasses match against.
|
||||
//! There is no libc errno table. The values are the Darwin/BSD numbers the
|
||||
//! guest `O_*` flags and `OSError` subclasses match against.
|
||||
|
||||
#[must_use]
|
||||
pub fn strerror_string(errno: i32) -> Option<String> {
|
||||
errors::strerror(errno).map(str::to_owned)
|
||||
}
|
||||
|
||||
pub mod errors {
|
||||
pub const EAGAIN: i32 = 11;
|
||||
pub const ECONNABORTED: i32 = 103;
|
||||
pub const ECONNRESET: i32 = 104;
|
||||
pub const EPERM: i32 = 1;
|
||||
pub const ENOENT: i32 = 2;
|
||||
pub const ESRCH: i32 = 3;
|
||||
pub const EINTR: i32 = 4;
|
||||
pub const EIO: i32 = 5;
|
||||
pub const EBADF: i32 = 9;
|
||||
pub const ECHILD: i32 = 10;
|
||||
pub const EAGAIN: i32 = 35;
|
||||
pub const EWOULDBLOCK: i32 = 35;
|
||||
pub const EINPROGRESS: i32 = 36;
|
||||
pub const EALREADY: i32 = 37;
|
||||
pub const EPIPE: i32 = 32;
|
||||
pub const ENOTDIR: i32 = 20;
|
||||
pub const EISDIR: i32 = 21;
|
||||
pub const EINVAL: i32 = 22;
|
||||
pub const EMFILE: i32 = 24;
|
||||
pub const ESPIPE: i32 = 29;
|
||||
pub const EROFS: i32 = 30;
|
||||
pub const EACCES: i32 = 13;
|
||||
pub const EEXIST: i32 = 17;
|
||||
pub const ENOTSUP: i32 = 45;
|
||||
pub const EAFNOSUPPORT: i32 = 47;
|
||||
pub const ECONNABORTED: i32 = 53;
|
||||
pub const ECONNRESET: i32 = 54;
|
||||
pub const ESHUTDOWN: i32 = 58;
|
||||
pub const ETIMEDOUT: i32 = 60;
|
||||
pub const ECONNREFUSED: i32 = 61;
|
||||
|
||||
pub fn strerror(errno: i32) -> Option<&'static str> {
|
||||
Some(match errno {
|
||||
EPERM => "Operation not permitted",
|
||||
ENOENT => "No such file or directory",
|
||||
ESRCH => "No such process",
|
||||
EIO => "Input/output error",
|
||||
EINTR => "Interrupted system call",
|
||||
ECHILD => "No child processes",
|
||||
EACCES => "Permission denied",
|
||||
EEXIST => "File exists",
|
||||
ENOTDIR => "Not a directory",
|
||||
EISDIR => "Is a directory",
|
||||
EPIPE => "Broken pipe",
|
||||
EAGAIN => "Resource temporarily unavailable",
|
||||
EINPROGRESS => "Operation now in progress",
|
||||
EALREADY => "Operation already in progress",
|
||||
ENOTSUP => "Operation not supported",
|
||||
EAFNOSUPPORT => "Address family not supported by protocol",
|
||||
ECONNABORTED => "Software caused connection abort",
|
||||
ECONNRESET => "Connection reset by peer",
|
||||
ETIMEDOUT => "Operation timed out",
|
||||
ECONNREFUSED => "Connection refused",
|
||||
EBADF => "Bad file descriptor",
|
||||
EINVAL => "Invalid argument",
|
||||
EMFILE => "Too many open files",
|
||||
ESPIPE => "Illegal seek",
|
||||
EROFS => "Read-only file system",
|
||||
ESHUTDOWN => "Can't send after socket shutdown",
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::errors;
|
||||
|
||||
#[test]
|
||||
fn eagain_is_darwin() {
|
||||
assert_eq!(errors::EAGAIN, 35);
|
||||
assert_eq!(errors::EWOULDBLOCK, 35);
|
||||
assert_eq!(
|
||||
errors::strerror(errors::EAGAIN),
|
||||
Some("Resource temporarily unavailable")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,17 @@ use crate::os::CheckLibcResult;
|
||||
|
||||
pub use libc::{F_GETFD, F_GETFL, F_SETFD, F_SETFL, FD_CLOEXEC};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub use libc::{F_LOCK, F_TEST, F_TLOCK, F_ULOCK};
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
pub use libc::{F_DUPFD, F_DUPFD_CLOEXEC, F_GETLK, F_SETLK, F_SETLKW};
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ pub fn fopen(path: &std::path::Path, mode: &str) -> std::io::Result<*mut CFile>
|
||||
|
||||
// Convert File handle to CRT file descriptor
|
||||
let handle = file.into_raw_handle();
|
||||
let fd = unsafe { libc::open_osfhandle(handle as isize, libc::O_RDONLY) };
|
||||
let fd = unsafe { libc::open_osfhandle(handle as isize, crate::os::O_RDONLY) };
|
||||
if fd == -1 {
|
||||
return Err(std::io::Error::last_os_error());
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ pub fn parse_fileio_mode(mode_str: &str) -> Result<ParsedFileMode, FileModeError
|
||||
}
|
||||
rwa = true;
|
||||
mode.insert(FileMode::WRITABLE | FileMode::CREATED);
|
||||
flags |= libc::O_EXCL | libc::O_CREAT;
|
||||
flags |= os::O_EXCL | os::O_CREAT;
|
||||
}
|
||||
b'r' => {
|
||||
if rwa {
|
||||
@@ -97,7 +97,7 @@ pub fn parse_fileio_mode(mode_str: &str) -> Result<ParsedFileMode, FileModeError
|
||||
}
|
||||
rwa = true;
|
||||
mode.insert(FileMode::WRITABLE);
|
||||
flags |= libc::O_CREAT | libc::O_TRUNC;
|
||||
flags |= os::O_CREAT | os::O_TRUNC;
|
||||
}
|
||||
b'a' => {
|
||||
if rwa {
|
||||
@@ -105,7 +105,7 @@ pub fn parse_fileio_mode(mode_str: &str) -> Result<ParsedFileMode, FileModeError
|
||||
}
|
||||
rwa = true;
|
||||
mode.insert(FileMode::WRITABLE | FileMode::APPENDING);
|
||||
flags |= libc::O_APPEND | libc::O_CREAT;
|
||||
flags |= os::O_APPEND | os::O_CREAT;
|
||||
}
|
||||
b'+' => {
|
||||
if plus {
|
||||
@@ -124,20 +124,20 @@ pub fn parse_fileio_mode(mode_str: &str) -> Result<ParsedFileMode, FileModeError
|
||||
}
|
||||
|
||||
if mode.contains(FileMode::READABLE | FileMode::WRITABLE) {
|
||||
flags |= libc::O_RDWR;
|
||||
flags |= os::O_RDWR;
|
||||
} else if mode.contains(FileMode::READABLE) {
|
||||
flags |= libc::O_RDONLY;
|
||||
flags |= os::O_RDONLY;
|
||||
} else {
|
||||
flags |= libc::O_WRONLY;
|
||||
flags |= os::O_WRONLY;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
flags |= libc::O_BINARY | libc::O_NOINHERIT;
|
||||
flags |= os::O_BINARY | os::O_NOINHERIT;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
flags |= libc::O_CLOEXEC;
|
||||
flags |= os::O_CLOEXEC;
|
||||
}
|
||||
|
||||
Ok(ParsedFileMode { mode, flags })
|
||||
|
||||
@@ -2,19 +2,8 @@ use core::ffi::CStr;
|
||||
use std::io;
|
||||
|
||||
use crate::crt_fd;
|
||||
|
||||
const EBADF: i32 = 9;
|
||||
const EAGAIN: i32 = 11;
|
||||
const EINTR: i32 = 4;
|
||||
const EISDIR: i32 = 21;
|
||||
|
||||
const O_RDONLY: i32 = 0;
|
||||
const O_WRONLY: i32 = 1;
|
||||
const O_RDWR: i32 = 2;
|
||||
const O_APPEND: i32 = 0x0008;
|
||||
const O_CREAT: i32 = 0x0200;
|
||||
const O_TRUNC: i32 = 0x0400;
|
||||
const O_EXCL: i32 = 0x0800;
|
||||
use crate::errno::errors::{EAGAIN, EBADF, EINTR, EISDIR};
|
||||
use crate::os::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
||||
@@ -46,7 +46,7 @@ unsafe extern "C" {
|
||||
}
|
||||
|
||||
pub fn setmode_binary(fd: crt_fd::Borrowed<'_>) {
|
||||
unsafe { suppress_iph!(_setmode(fd, libc::O_BINARY)) };
|
||||
unsafe { suppress_iph!(_setmode(fd, crate::os::O_BINARY)) };
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -136,8 +136,14 @@ impl SemHandle {
|
||||
unlink: bool,
|
||||
) -> Result<(Self, Option<String>), SemError> {
|
||||
let cname = semaphore_name(name)?;
|
||||
let raw =
|
||||
unsafe { libc::sem_open(cname.as_ptr(), libc::O_CREAT | libc::O_EXCL, 0o600, value) };
|
||||
let raw = unsafe {
|
||||
libc::sem_open(
|
||||
cname.as_ptr(),
|
||||
crate::os::O_CREAT | crate::os::O_EXCL,
|
||||
0o600,
|
||||
value,
|
||||
)
|
||||
};
|
||||
if raw == libc::SEM_FAILED {
|
||||
return Err(SemError::from_errno(Errno::last()));
|
||||
}
|
||||
|
||||
@@ -1369,7 +1369,7 @@ pub fn pipe() -> io::Result<(i32, i32)> {
|
||||
|
||||
let write_fd = match crate::msvcrt::open_osfhandle(
|
||||
write_handle.as_raw_handle() as isize,
|
||||
libc::O_WRONLY | O_NOINHERIT,
|
||||
crate::os::O_WRONLY | O_NOINHERIT,
|
||||
) {
|
||||
Ok(fd) => {
|
||||
let _ = write_handle.into_raw_handle();
|
||||
@@ -2370,9 +2370,9 @@ pub fn open_console_path_fd(path: &widestring::WideCStr, writable: bool) -> io::
|
||||
}
|
||||
|
||||
let osf_flags = if writable {
|
||||
libc::O_WRONLY | libc::O_BINARY | 0x80
|
||||
crate::os::O_WRONLY | crate::os::O_BINARY | 0x80
|
||||
} else {
|
||||
libc::O_RDONLY | libc::O_BINARY | 0x80
|
||||
crate::os::O_RDONLY | crate::os::O_BINARY | 0x80
|
||||
};
|
||||
match crate::msvcrt::open_osfhandle(handle as isize, osf_flags) {
|
||||
Ok(fd) => Ok(fd),
|
||||
|
||||
@@ -40,6 +40,124 @@ pub use libc::AT_FDCWD;
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
pub const AT_FDCWD: i32 = -100;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use libc::{AT_REMOVEDIR, AT_SYMLINK_FOLLOW, AT_SYMLINK_NOFOLLOW};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_vendor = "apple"
|
||||
))]
|
||||
pub use libc::AT_EACCESS;
|
||||
|
||||
/// bionic does not export `AT_EACCESS`; the value is the Linux `fcntl.h` one.
|
||||
#[cfg(target_os = "android")]
|
||||
pub const AT_EACCESS: i32 = 0x200;
|
||||
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
pub use libc::{ST_NOSUID, ST_RDONLY};
|
||||
|
||||
/// `open(2)` flags. libc on hosts that bind them; Darwin/BSD numbers on
|
||||
/// `wasm32-unknown-unknown`, matching the guest errno table.
|
||||
#[cfg(any(unix, windows, target_os = "wasi"))]
|
||||
pub use libc::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use libc::{O_ACCMODE, O_CLOEXEC, O_DIRECTORY, O_NOFOLLOW, O_NONBLOCK};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub use libc::{O_ASYNC, O_NDELAY, O_NOCTTY};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
pub use libc::O_DSYNC;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
pub use libc::O_SYNC;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub use libc::O_FSYNC;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub use libc::{O_DIRECT, O_LARGEFILE, O_NOATIME, O_PATH, O_RSYNC, O_TMPFILE};
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub use libc::{O_DIRECT, O_PATH};
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub use libc::O_PATH;
|
||||
|
||||
#[cfg(target_os = "netbsd")]
|
||||
pub use libc::{O_DIRECT, O_RSYNC};
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
pub use libc::O_DIRECT;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub use libc::{O_EVTONLY, O_EXEC, O_EXLOCK, O_NOFOLLOW_ANY, O_SEARCH, O_SHLOCK, O_SYMLINK};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub use libc::{O_EXLOCK, O_SHLOCK};
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub use libc::O_SYMLINK;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use libc::{O_BINARY, O_NOINHERIT, O_RANDOM, O_SEQUENTIAL, O_TEMPORARY, O_TEXT};
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
|
||||
mod wasm_oflag {
|
||||
pub const O_RDONLY: i32 = 0x0000;
|
||||
pub const O_WRONLY: i32 = 0x0001;
|
||||
pub const O_RDWR: i32 = 0x0002;
|
||||
pub const O_ACCMODE: i32 = 0x0003;
|
||||
pub const O_NONBLOCK: i32 = 0x0004;
|
||||
pub const O_APPEND: i32 = 0x0008;
|
||||
pub const O_SYNC: i32 = 0x0080;
|
||||
pub const O_NOFOLLOW: i32 = 0x0100;
|
||||
pub const O_CREAT: i32 = 0x0200;
|
||||
pub const O_TRUNC: i32 = 0x0400;
|
||||
pub const O_EXCL: i32 = 0x0800;
|
||||
pub const O_DIRECTORY: i32 = 0x0010_0000;
|
||||
pub const O_CLOEXEC: i32 = 0x0100_0000;
|
||||
pub const O_NDELAY: i32 = O_NONBLOCK;
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
|
||||
pub use wasm_oflag::*;
|
||||
|
||||
/// BSD `chflags` bits the `libc` crate does not bind. Published by `_stat`
|
||||
/// on every platform.
|
||||
pub const UF_SETTABLE: u32 = 0x0000ffff;
|
||||
@@ -837,3 +955,16 @@ pub fn winerror_to_errno(winerror: i32) -> i32 {
|
||||
_ => EINVAL,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn o_rdonly_is_zero() {
|
||||
assert_eq!(super::O_RDONLY, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn o_wronly_is_one() {
|
||||
assert_eq!(super::O_WRONLY, 1);
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,145 @@ pub const EX_PROTOCOL: i32 = 76;
|
||||
pub const EX_NOPERM: i32 = 77;
|
||||
pub const EX_CONFIG: i32 = 78;
|
||||
|
||||
/// Remaining `posix` integer names the VM still took from `libc`.
|
||||
#[cfg(any(target_os = "android", target_os = "redox", unix))]
|
||||
pub use libc::{PRIO_PGRP, PRIO_PROCESS, PRIO_USER};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use libc::{
|
||||
COPYFILE_ACL, COPYFILE_DATA, COPYFILE_STAT, COPYFILE_XATTR, PRIO_DARWIN_BG, PRIO_DARWIN_NONUI,
|
||||
PRIO_DARWIN_PROCESS, PRIO_DARWIN_THREAD, TMP_MAX,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use libc::PIDFD_NONBLOCK;
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub use libc::{
|
||||
CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID,
|
||||
CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SIGHAND, CLONE_SYSVSEM, CLONE_THREAD, CLONE_VM,
|
||||
MFD_HUGE_SHIFT, P_PIDFD, SCHED_BATCH, SCHED_DEADLINE, SCHED_IDLE, SCHED_NORMAL,
|
||||
SCHED_RESET_ON_FORK, SPLICE_F_MORE, SPLICE_F_MOVE, SPLICE_F_NONBLOCK,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "netbsd"))]
|
||||
pub use libc::{XATTR_CREATE, XATTR_REPLACE};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
pub use libc::{
|
||||
MFD_ALLOW_SEALING, MFD_CLOEXEC, MFD_HUGE_MASK, MFD_HUGETLB, POSIX_FADV_DONTNEED,
|
||||
POSIX_FADV_NOREUSE, POSIX_FADV_NORMAL, POSIX_FADV_RANDOM, POSIX_FADV_SEQUENTIAL,
|
||||
POSIX_FADV_WILLNEED,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox", unix))]
|
||||
pub use libc::{RTLD_LAZY, RTLD_NOW, WNOHANG};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "macos", target_os = "redox", unix))]
|
||||
pub use libc::RTLD_GLOBAL;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
pub use libc::{
|
||||
EFD_CLOEXEC, EFD_NONBLOCK, EFD_SEMAPHORE, TFD_CLOEXEC, TFD_NONBLOCK, TFD_TIMER_ABSTIME,
|
||||
TFD_TIMER_CANCEL_ON_SET,
|
||||
};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
pub use libc::{GRND_NONBLOCK, GRND_RANDOM};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
pub use libc::SCHED_OTHER;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos"
|
||||
))]
|
||||
pub use libc::{RTLD_NODELETE, SEEK_DATA, SEEK_HOLE};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox",
|
||||
unix
|
||||
))]
|
||||
pub use libc::RTLD_LOCAL;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox",
|
||||
unix
|
||||
))]
|
||||
pub use libc::WUNTRACED;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
pub use libc::{
|
||||
CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, P_ALL, P_PGID,
|
||||
P_PID, SCHED_FIFO, SCHED_RR,
|
||||
};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub use libc::{RTLD_NOLOAD, WEXITED, WNOWAIT, WSTOPPED};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox",
|
||||
unix
|
||||
))]
|
||||
pub use libc::WCONTINUED;
|
||||
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu"))]
|
||||
pub use libc::RTLD_DEEPBIND;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use libc::{UTIME_NOW, UTIME_OMIT};
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub use libc::{SF_MNOWAIT, SF_NOCACHE, SF_NODISKIO, SF_SYNC};
|
||||
|
||||
pub struct UnameInfo {
|
||||
pub sysname: String,
|
||||
pub nodename: String,
|
||||
|
||||
@@ -182,6 +182,11 @@ mod mt {
|
||||
EVAL_BREAKER.fetch_and(!STOP_BIT, Ordering::Release);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn stop_bit_set() -> bool {
|
||||
EVAL_BREAKER.load(Ordering::Relaxed) & STOP_BIT != 0
|
||||
}
|
||||
|
||||
/// Record that finalization has begun. See `FINALIZING_BIT`.
|
||||
pub(crate) fn set_finalizing_bit() {
|
||||
EVAL_BREAKER.fetch_or(FINALIZING_BIT, Ordering::Release);
|
||||
@@ -198,6 +203,8 @@ mod mt {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "threading"))]
|
||||
pub(crate) use mt::stop_bit_set;
|
||||
#[cfg(feature = "threading")]
|
||||
pub(crate) use mt::{
|
||||
clear_qsbr_bit, clear_stop_bit, qsbr_bit_set, schedule_gc, set_finalizing_bit, set_qsbr_bit,
|
||||
|
||||
@@ -25,7 +25,9 @@ pub(crate) mod module {
|
||||
use std::os::windows::io::AsRawHandle;
|
||||
|
||||
#[pyattr]
|
||||
use libc::{O_BINARY, O_NOINHERIT, O_RANDOM, O_SEQUENTIAL, O_TEMPORARY, O_TEXT};
|
||||
use rustpython_host_env::os::{
|
||||
O_BINARY, O_NOINHERIT, O_RANDOM, O_SEQUENTIAL, O_TEMPORARY, O_TEXT,
|
||||
};
|
||||
|
||||
#[pyattr]
|
||||
use host_msvcrt::{
|
||||
|
||||
@@ -242,7 +242,7 @@ pub(super) mod _os {
|
||||
const SCANDIR_FD: bool = cfg!(all(unix, not(target_os = "redox")));
|
||||
|
||||
#[pyattr]
|
||||
use libc::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
|
||||
use crate::host_env::os::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
|
||||
|
||||
#[pyattr]
|
||||
pub(crate) use crate::host_env::os::{F_OK, R_OK, W_OK, X_OK};
|
||||
@@ -250,11 +250,7 @@ pub(super) mod _os {
|
||||
// ST_RDONLY and ST_NOSUID flags for statvfs
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
#[pyattr]
|
||||
const ST_RDONLY: libc::c_ulong = libc::ST_RDONLY;
|
||||
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
#[pyattr]
|
||||
const ST_NOSUID: libc::c_ulong = libc::ST_NOSUID;
|
||||
use crate::host_env::os::{ST_NOSUID, ST_RDONLY};
|
||||
|
||||
#[pyfunction]
|
||||
fn close(fd: crt_fd::Owned) -> io::Result<()> {
|
||||
@@ -299,14 +295,14 @@ pub(super) mod _os {
|
||||
let fd = {
|
||||
let [] = dir_fd.0;
|
||||
let name = name.to_wide_cstring(vm)?;
|
||||
let flags = flags | libc::O_NOINHERIT;
|
||||
let flags = flags | crate::host_env::os::O_NOINHERIT;
|
||||
crt_fd::wopen(&name, flags, mode)
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
let fd = {
|
||||
let name = name.clone().into_cstring(vm)?;
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
let flags = flags | libc::O_CLOEXEC;
|
||||
let flags = flags | crate::host_env::os::O_CLOEXEC;
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
if let Some(dir_fd) = dir_fd.get_opt() {
|
||||
crt_fd::openat(dir_fd, &name, flags, mode)
|
||||
|
||||
@@ -48,48 +48,59 @@ pub mod module {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pyattr]
|
||||
use libc::PIDFD_NONBLOCK;
|
||||
use rustpython_host_env::posix::PIDFD_NONBLOCK;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
COPYFILE_DATA as _COPYFILE_DATA, O_EVTONLY, O_NOFOLLOW_ANY, PRIO_DARWIN_BG,
|
||||
PRIO_DARWIN_NONUI, PRIO_DARWIN_PROCESS, PRIO_DARWIN_THREAD,
|
||||
use rustpython_host_env::posix::{
|
||||
COPYFILE_DATA as _COPYFILE_DATA, PRIO_DARWIN_BG, PRIO_DARWIN_NONUI, PRIO_DARWIN_PROCESS,
|
||||
PRIO_DARWIN_THREAD,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::os::{O_EVTONLY, O_NOFOLLOW_ANY};
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[pyattr]
|
||||
use libc::{SF_MNOWAIT, SF_NOCACHE, SF_NODISKIO, SF_SYNC};
|
||||
use rustpython_host_env::posix::{SF_MNOWAIT, SF_NOCACHE, SF_NODISKIO, SF_SYNC};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use rustpython_host_env::posix::{
|
||||
CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS,
|
||||
CLONE_NEWPID, CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SIGHAND, CLONE_SYSVSEM, CLONE_THREAD,
|
||||
CLONE_VM, MFD_HUGE_SHIFT, O_NOATIME, O_TMPFILE, P_PIDFD, SCHED_BATCH, SCHED_DEADLINE,
|
||||
SCHED_IDLE, SCHED_NORMAL, SCHED_RESET_ON_FORK, SPLICE_F_MORE, SPLICE_F_MOVE,
|
||||
SPLICE_F_NONBLOCK,
|
||||
CLONE_VM, MFD_HUGE_SHIFT, P_PIDFD, SCHED_BATCH, SCHED_DEADLINE, SCHED_IDLE, SCHED_NORMAL,
|
||||
SCHED_RESET_ON_FORK, SPLICE_F_MORE, SPLICE_F_MOVE, SPLICE_F_NONBLOCK,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::os::{O_NOATIME, O_TMPFILE};
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "redox"))]
|
||||
#[pyattr]
|
||||
use libc::O_SYMLINK;
|
||||
use rustpython_host_env::os::O_SYMLINK;
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "redox", unix))]
|
||||
#[pyattr]
|
||||
use libc::{O_NOFOLLOW, PRIO_PGRP, PRIO_PROCESS, PRIO_USER};
|
||||
use rustpython_host_env::posix::{PRIO_PGRP, PRIO_PROCESS, PRIO_USER};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "redox", unix))]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::os::O_NOFOLLOW;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "netbsd"))]
|
||||
#[pyattr]
|
||||
use libc::{XATTR_CREATE, XATTR_REPLACE};
|
||||
use rustpython_host_env::posix::{XATTR_CREATE, XATTR_REPLACE};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux", target_os = "netbsd"))]
|
||||
#[pyattr]
|
||||
use libc::O_RSYNC;
|
||||
use rustpython_host_env::os::O_RSYNC;
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use rustpython_host_env::posix::{
|
||||
MFD_ALLOW_SEALING, MFD_CLOEXEC, MFD_HUGE_MASK, MFD_HUGETLB, POSIX_FADV_DONTNEED,
|
||||
POSIX_FADV_NOREUSE, POSIX_FADV_NORMAL, POSIX_FADV_RANDOM, POSIX_FADV_SEQUENTIAL,
|
||||
POSIX_FADV_WILLNEED,
|
||||
@@ -97,11 +108,11 @@ pub mod module {
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox", unix))]
|
||||
#[pyattr]
|
||||
use libc::{RTLD_LAZY, RTLD_NOW, WNOHANG};
|
||||
use rustpython_host_env::posix::{RTLD_LAZY, RTLD_NOW, WNOHANG};
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "macos", target_os = "redox", unix))]
|
||||
#[pyattr]
|
||||
use libc::RTLD_GLOBAL;
|
||||
use rustpython_host_env::posix::RTLD_GLOBAL;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -110,7 +121,7 @@ pub mod module {
|
||||
target_os = "redox"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::O_PATH;
|
||||
use rustpython_host_env::os::O_PATH;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -119,7 +130,7 @@ pub mod module {
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
use rustpython_host_env::posix::{
|
||||
EFD_CLOEXEC, EFD_NONBLOCK, EFD_SEMAPHORE, TFD_CLOEXEC, TFD_NONBLOCK, TFD_TIMER_ABSTIME,
|
||||
TFD_TIMER_CANCEL_ON_SET,
|
||||
};
|
||||
@@ -131,7 +142,7 @@ pub mod module {
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{GRND_NONBLOCK, GRND_RANDOM};
|
||||
use rustpython_host_env::posix::{GRND_NONBLOCK, GRND_RANDOM};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -141,7 +152,7 @@ pub mod module {
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{F_OK, R_OK, W_OK, X_OK};
|
||||
use rustpython_host_env::os::{F_OK, R_OK, W_OK, X_OK};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -151,7 +162,7 @@ pub mod module {
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::O_NONBLOCK;
|
||||
use rustpython_host_env::os::O_NONBLOCK;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -161,7 +172,7 @@ pub mod module {
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::O_DSYNC;
|
||||
use rustpython_host_env::os::O_DSYNC;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
@@ -171,7 +182,7 @@ pub mod module {
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::SCHED_OTHER;
|
||||
use rustpython_host_env::posix::SCHED_OTHER;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -181,7 +192,7 @@ pub mod module {
|
||||
target_os = "macos"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{RTLD_NODELETE, SEEK_DATA, SEEK_HOLE};
|
||||
use rustpython_host_env::posix::{RTLD_NODELETE, SEEK_DATA, SEEK_HOLE};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -191,7 +202,7 @@ pub mod module {
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::O_DIRECT;
|
||||
use rustpython_host_env::os::O_DIRECT;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
@@ -201,7 +212,7 @@ pub mod module {
|
||||
target_os = "redox"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{O_EXLOCK, O_FSYNC, O_SHLOCK};
|
||||
use rustpython_host_env::os::{O_EXLOCK, O_FSYNC, O_SHLOCK};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -212,7 +223,7 @@ pub mod module {
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::RTLD_LOCAL;
|
||||
use rustpython_host_env::posix::RTLD_LOCAL;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -223,7 +234,7 @@ pub mod module {
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::WUNTRACED;
|
||||
use rustpython_host_env::posix::WUNTRACED;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -234,11 +245,22 @@ pub mod module {
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, O_SYNC, P_ALL,
|
||||
P_PGID, P_PID, SCHED_FIFO, SCHED_RR,
|
||||
use rustpython_host_env::posix::{
|
||||
CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, P_ALL, P_PGID,
|
||||
P_PID, SCHED_FIFO, SCHED_RR,
|
||||
};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::os::O_SYNC;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
@@ -249,7 +271,7 @@ pub mod module {
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::O_DIRECTORY;
|
||||
use rustpython_host_env::os::O_DIRECTORY;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -261,10 +283,30 @@ pub mod module {
|
||||
target_os = "redox"
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{
|
||||
F_LOCK, F_TEST, F_TLOCK, F_ULOCK, O_ASYNC, O_NDELAY, O_NOCTTY, RTLD_NOLOAD, WEXITED,
|
||||
WNOWAIT, WSTOPPED,
|
||||
};
|
||||
use rustpython_host_env::fcntl::{F_LOCK, F_TEST, F_TLOCK, F_ULOCK};
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::posix::{RTLD_NOLOAD, WEXITED, WNOWAIT, WSTOPPED};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox"
|
||||
))]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::os::{O_ASYNC, O_NDELAY, O_NOCTTY};
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
@@ -277,7 +319,20 @@ pub mod module {
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use libc::{O_CLOEXEC, WCONTINUED};
|
||||
use rustpython_host_env::posix::WCONTINUED;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "redox",
|
||||
unix
|
||||
))]
|
||||
#[pyattr]
|
||||
use rustpython_host_env::os::O_CLOEXEC;
|
||||
|
||||
#[pyattr]
|
||||
use rustpython_host_env::posix::{
|
||||
|
||||
@@ -1858,19 +1858,29 @@ for _ in range(40):
|
||||
fn eval_breaker_tripped_when_stop_requested_and_stop_bit_clear() {
|
||||
let interp = Interpreter::without_stdlib(Default::default());
|
||||
interp.enter(|vm| {
|
||||
crate::signal::clear_stop_bit();
|
||||
assert!(
|
||||
crate::vm::thread::set_stop_requested_for_current_thread(true),
|
||||
"current thread has no stop_requested flag"
|
||||
);
|
||||
crate::signal::clear_stop_bit();
|
||||
let pending = crate::signal::eval_breaker_pending();
|
||||
let tripped = vm.eval_breaker_tripped();
|
||||
// STOP_BIT is process-wide; a parallel stop-the-world test can
|
||||
// set it between the clear and the load. Retry until this thread
|
||||
// observes it clear, then sample `eval_breaker_tripped`.
|
||||
let (stop_bit, tripped) = {
|
||||
let mut stop_bit = true;
|
||||
let mut tripped = false;
|
||||
for _ in 0..10_000 {
|
||||
crate::signal::clear_stop_bit();
|
||||
stop_bit = crate::signal::stop_bit_set();
|
||||
tripped = vm.eval_breaker_tripped();
|
||||
if !stop_bit {
|
||||
break;
|
||||
}
|
||||
std::thread::yield_now();
|
||||
}
|
||||
(stop_bit, tripped)
|
||||
};
|
||||
crate::vm::thread::set_stop_requested_for_current_thread(false);
|
||||
assert!(
|
||||
!pending,
|
||||
"STOP_BIT or another process-wide breaker bit was set"
|
||||
);
|
||||
assert!(!stop_bit, "process-wide STOP_BIT was set");
|
||||
assert!(tripped);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user