Rollup merge of #139711 - thaliaarchi:hermit-args, r=jhpratt
Hermit: Unify `std::env::args` with Unix The only differences between these implementations of `std::env::args` are that Unix uses relaxed ordering, but Hermit uses acquire/release, and Unix truncates `argv` at the first null pointer, but Hermit doesn't. Since Hermit aims for Unix compatibility, unify it with Unix. The atomic orderings were established in https://github.com/rust-lang/rust/pull/74006 (cc `@euclio)` for Unix and https://github.com/rust-lang/rust/pull/100579 (cc `@joboet)` for Hermit and, before those, they used mutexes and non-atomic statics. I think the difference in orderings is simply from them being changed at different times. The commented explanation for using acquire/release for Hermit is “to broadcast writes by the OS”. I'm not experienced enough with atomics to accurately judge, but I think acquire/release is stronger than needed. Either way, they should match. Truncating at the first null pointer seems desirable, though I don't know whether it is necessary in practice on Hermit. cc `@mkroening` `@stlankes` for Hermit
This commit is contained in:
commit
5779843eda
3 changed files with 9 additions and 40 deletions
|
@ -1,35 +0,0 @@
|
|||
use crate::ffi::{CStr, OsString, c_char};
|
||||
use crate::os::hermit::ffi::OsStringExt;
|
||||
use crate::ptr;
|
||||
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
||||
use crate::sync::atomic::{AtomicIsize, AtomicPtr};
|
||||
|
||||
#[path = "common.rs"]
|
||||
mod common;
|
||||
pub use common::Args;
|
||||
|
||||
static ARGC: AtomicIsize = AtomicIsize::new(0);
|
||||
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
|
||||
|
||||
/// One-time global initialization.
|
||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||
ARGC.store(argc, Relaxed);
|
||||
// Use release ordering here to broadcast writes by the OS.
|
||||
ARGV.store(argv as *mut *const u8, Release);
|
||||
}
|
||||
|
||||
/// Returns the command line arguments
|
||||
pub fn args() -> Args {
|
||||
// Synchronize with the store above.
|
||||
let argv = ARGV.load(Acquire);
|
||||
// If argv has not been initialized yet, do not return any arguments.
|
||||
let argc = if argv.is_null() { 0 } else { ARGC.load(Relaxed) };
|
||||
let args: Vec<OsString> = (0..argc)
|
||||
.map(|i| unsafe {
|
||||
let cstr = CStr::from_ptr(*argv.offset(i) as *const c_char);
|
||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||
})
|
||||
.collect();
|
||||
|
||||
Args::new(args)
|
||||
}
|
|
@ -3,15 +3,15 @@
|
|||
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))))] {
|
||||
if #[cfg(any(
|
||||
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),
|
||||
target_os = "hermit",
|
||||
))] {
|
||||
mod unix;
|
||||
pub use unix::*;
|
||||
} else if #[cfg(target_family = "windows")] {
|
||||
mod windows;
|
||||
pub use windows::*;
|
||||
} else if #[cfg(target_os = "hermit")] {
|
||||
mod hermit;
|
||||
pub use hermit::*;
|
||||
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
|
||||
mod sgx;
|
||||
pub use sgx::*;
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#![allow(dead_code)] // runtime init functions not used during testing
|
||||
|
||||
use crate::ffi::CStr;
|
||||
#[cfg(target_os = "hermit")]
|
||||
use crate::os::hermit::ffi::OsStringExt;
|
||||
#[cfg(not(target_os = "hermit"))]
|
||||
use crate::os::unix::ffi::OsStringExt;
|
||||
|
||||
#[path = "common.rs"]
|
||||
|
@ -73,6 +76,7 @@ pub fn args() -> Args {
|
|||
target_os = "illumos",
|
||||
target_os = "emscripten",
|
||||
target_os = "haiku",
|
||||
target_os = "hermit",
|
||||
target_os = "l4re",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
|
@ -100,7 +104,7 @@ mod imp {
|
|||
|
||||
unsafe fn really_init(argc: isize, argv: *const *const u8) {
|
||||
// These don't need to be ordered with each other or other stores,
|
||||
// because they only hold the unmodified system-provide argv/argc.
|
||||
// because they only hold the unmodified system-provided argv/argc.
|
||||
ARGC.store(argc, Ordering::Relaxed);
|
||||
ARGV.store(argv as *mut _, Ordering::Relaxed);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue