Hermit: Unify std::env::args with Unix
The only differences between these implementations 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.
diff --git a/library/std/src/sys/args/hermit.rs b/library/std/src/sys/args/hermit.rs
deleted file mode 100644
index ddd644a..0000000
--- a/library/std/src/sys/args/hermit.rs
+++ /dev/null
@@ -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)
-}
diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs
index f24d6eb..6a37b32 100644
--- a/library/std/src/sys/args/mod.rs
+++ b/library/std/src/sys/args/mod.rs
@@ -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::*;
diff --git a/library/std/src/sys/args/unix.rs b/library/std/src/sys/args/unix.rs
index 7d7815c..c087fd6 100644
--- a/library/std/src/sys/args/unix.rs
+++ b/library/std/src/sys/args/unix.rs
@@ -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);
}