about summary refs log tree commit diff
path: root/src/libstd/sys/unix/args.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-28 00:51:53 +0000
committerbors <bors@rust-lang.org>2020-07-28 00:51:53 +0000
commitac48e62db85e6db4bbe026490381ab205f4a614d (patch)
tree14f64e683e3f64dcbcfb8c2c7cb45ac7592e6e09 /src/libstd/sys/unix/args.rs
parent9be8ffcb0206fc1558069a7b4766090df7877659 (diff)
parent2c31b45ae878b821975c4ebd94cc1e49f6073fd0 (diff)
downloadrust-ac48e62db85e6db4bbe026490381ab205f4a614d.tar.gz
rust-ac48e62db85e6db4bbe026490381ab205f4a614d.zip
Auto merge of #73265 - mark-i-m:mv-std, r=Mark-Simulacrum,mark-i-m
mv std libs to library/

This is the first step in refactoring the directory layout of this repository, with further followup steps planned (but not done yet).

Background: currently, all crates are under src/, without nested src directories and with the unconventional `lib*` prefixes (e.g., `src/libcore/lib.rs`). This directory structures is not idiomatic and makes the `src/` directory rather overwhelming. To improve contributor experience and make things a bit more approachable, we are reorganizing the repo a bit.

In this PR, we move the standard libs (basically anything that is "runtime", as opposed to part of the compiler, build system, or one of the tools, etc). The new layout moves these libraries to a new `library/` directory in the root of the repo. Additionally, we remove the `lib*` prefixes and add nested `src/` directories.  The other crates/tools in this repo are not touched. So in summary:

```
library/<crate>/src/*.rs
src/<all the rest>     // unchanged
```

where `<crate>` is:
- core
- alloc
- std
- test
- proc_macro
- panic_abort
- panic_unwind
- profiler_builtins
- term
- unwind
- rtstartup
- backtrace
- rustc-std-workspace-*

There was a lot of discussion about this and a few rounds of compiler team approvals, FCPs, MCPs, and nominations. The original MCP is https://github.com/rust-lang/compiler-team/issues/298. The final approval of the compiler team was given here: https://github.com/rust-lang/rust/pull/73265#issuecomment-659498446.

The name `library` was chosen to complement a later move of the compiler crates to a `compiler/` directory. There was a lot of discussion around adding the nested `src/` directories. Note that this does increase the nesting depth (plausibly important for manual traversal of the tree, e.g., through GitHub's UI or `cd`), but this is deemed to be better as it fits the standard layout of Rust crates throughout most of the ecosystem, though there is some debate about how much this should apply to multi-crate projects. Overall, there seem to be more people in favor of nested `src/` than against.

After this PR, there are no dependencies out of the `library/` directory except on the `build_helper` (or crates.io crates).
Diffstat (limited to 'src/libstd/sys/unix/args.rs')
-rw-r--r--src/libstd/sys/unix/args.rs251
1 files changed, 0 insertions, 251 deletions
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
deleted file mode 100644
index 9bc44a59482..00000000000
--- a/src/libstd/sys/unix/args.rs
+++ /dev/null
@@ -1,251 +0,0 @@
-//! Global initialization and retrieval of command line arguments.
-//!
-//! On some platforms these are stored during runtime startup,
-//! and on some they are retrieved from the system on demand.
-
-#![allow(dead_code)] // runtime init functions not used during testing
-
-use crate::ffi::OsString;
-use crate::marker::PhantomData;
-use crate::vec;
-
-/// One-time global initialization.
-pub unsafe fn init(argc: isize, argv: *const *const u8) {
-    imp::init(argc, argv)
-}
-
-/// One-time global cleanup.
-pub unsafe fn cleanup() {
-    imp::cleanup()
-}
-
-/// Returns the command line arguments
-pub fn args() -> Args {
-    imp::args()
-}
-
-pub struct Args {
-    iter: vec::IntoIter<OsString>,
-    _dont_send_or_sync_me: PhantomData<*mut ()>,
-}
-
-impl Args {
-    pub fn inner_debug(&self) -> &[OsString] {
-        self.iter.as_slice()
-    }
-}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.iter.next()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.iter.len()
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.iter.next_back()
-    }
-}
-
-#[cfg(any(
-    target_os = "linux",
-    target_os = "android",
-    target_os = "freebsd",
-    target_os = "dragonfly",
-    target_os = "netbsd",
-    target_os = "openbsd",
-    target_os = "solaris",
-    target_os = "illumos",
-    target_os = "emscripten",
-    target_os = "haiku",
-    target_os = "l4re",
-    target_os = "fuchsia",
-    target_os = "redox"
-))]
-mod imp {
-    use super::Args;
-    use crate::ffi::{CStr, OsString};
-    use crate::marker::PhantomData;
-    use crate::os::unix::prelude::*;
-    use crate::ptr;
-    use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
-
-    use crate::sys_common::mutex::Mutex;
-
-    static ARGC: AtomicIsize = AtomicIsize::new(0);
-    static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
-    // We never call `ENV_LOCK.init()`, so it is UB to attempt to
-    // acquire this mutex reentrantly!
-    static LOCK: Mutex = Mutex::new();
-
-    unsafe fn really_init(argc: isize, argv: *const *const u8) {
-        let _guard = LOCK.lock();
-        ARGC.store(argc, Ordering::Relaxed);
-        ARGV.store(argv as *mut _, Ordering::Relaxed);
-    }
-
-    #[inline(always)]
-    pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
-        // On Linux-GNU, we rely on `ARGV_INIT_ARRAY` below to initialize
-        // `ARGC` and `ARGV`. But in Miri that does not actually happen so we
-        // still initialize here.
-        #[cfg(any(miri, not(all(target_os = "linux", target_env = "gnu"))))]
-        really_init(_argc, _argv);
-    }
-
-    /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension.
-    /// This allows `std::env::args` to work even in a `cdylib`, as it does on macOS and Windows.
-    #[cfg(all(target_os = "linux", target_env = "gnu"))]
-    #[used]
-    #[link_section = ".init_array.00099"]
-    static ARGV_INIT_ARRAY: extern "C" fn(
-        crate::os::raw::c_int,
-        *const *const u8,
-        *const *const u8,
-    ) = {
-        extern "C" fn init_wrapper(
-            argc: crate::os::raw::c_int,
-            argv: *const *const u8,
-            _envp: *const *const u8,
-        ) {
-            unsafe {
-                really_init(argc as isize, argv);
-            }
-        }
-        init_wrapper
-    };
-
-    pub unsafe fn cleanup() {
-        let _guard = LOCK.lock();
-        ARGC.store(0, Ordering::Relaxed);
-        ARGV.store(ptr::null_mut(), Ordering::Relaxed);
-    }
-
-    pub fn args() -> Args {
-        Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData }
-    }
-
-    fn clone() -> Vec<OsString> {
-        unsafe {
-            let _guard = LOCK.lock();
-            let argc = ARGC.load(Ordering::Relaxed);
-            let argv = ARGV.load(Ordering::Relaxed);
-            (0..argc)
-                .map(|i| {
-                    let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
-                    OsStringExt::from_vec(cstr.to_bytes().to_vec())
-                })
-                .collect()
-        }
-    }
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-mod imp {
-    use super::Args;
-    use crate::ffi::CStr;
-    use crate::marker::PhantomData;
-
-    pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
-
-    pub fn cleanup() {}
-
-    #[cfg(target_os = "macos")]
-    pub fn args() -> Args {
-        use crate::os::unix::prelude::*;
-        extern "C" {
-            // These functions are in crt_externs.h.
-            fn _NSGetArgc() -> *mut libc::c_int;
-            fn _NSGetArgv() -> *mut *mut *mut libc::c_char;
-        }
-
-        let vec = unsafe {
-            let (argc, argv) =
-                (*_NSGetArgc() as isize, *_NSGetArgv() as *const *const libc::c_char);
-            (0..argc as isize)
-                .map(|i| {
-                    let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec();
-                    OsStringExt::from_vec(bytes)
-                })
-                .collect::<Vec<_>>()
-        };
-        Args { iter: vec.into_iter(), _dont_send_or_sync_me: PhantomData }
-    }
-
-    // As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs
-    // and use underscores in their names - they're most probably
-    // are considered private and therefore should be avoided
-    // Here is another way to get arguments using Objective C
-    // runtime
-    //
-    // In general it looks like:
-    // res = Vec::new()
-    // let args = [[NSProcessInfo processInfo] arguments]
-    // for i in (0..[args count])
-    //      res.push([args objectAtIndex:i])
-    // res
-    #[cfg(target_os = "ios")]
-    pub fn args() -> Args {
-        use crate::ffi::OsString;
-        use crate::mem;
-        use crate::str;
-
-        extern "C" {
-            fn sel_registerName(name: *const libc::c_uchar) -> Sel;
-            fn objc_getClass(class_name: *const libc::c_uchar) -> NsId;
-        }
-
-        #[cfg(target_arch = "aarch64")]
-        extern "C" {
-            fn objc_msgSend(obj: NsId, sel: Sel) -> NsId;
-            #[allow(clashing_extern_declarations)]
-            #[link_name = "objc_msgSend"]
-            fn objc_msgSend_ul(obj: NsId, sel: Sel, i: libc::c_ulong) -> NsId;
-        }
-
-        #[cfg(not(target_arch = "aarch64"))]
-        extern "C" {
-            fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
-            #[allow(clashing_extern_declarations)]
-            #[link_name = "objc_msgSend"]
-            fn objc_msgSend_ul(obj: NsId, sel: Sel, ...) -> NsId;
-        }
-
-        type Sel = *const libc::c_void;
-        type NsId = *const libc::c_void;
-
-        let mut res = Vec::new();
-
-        unsafe {
-            let process_info_sel = sel_registerName("processInfo\0".as_ptr());
-            let arguments_sel = sel_registerName("arguments\0".as_ptr());
-            let utf8_sel = sel_registerName("UTF8String\0".as_ptr());
-            let count_sel = sel_registerName("count\0".as_ptr());
-            let object_at_sel = sel_registerName("objectAtIndex:\0".as_ptr());
-
-            let klass = objc_getClass("NSProcessInfo\0".as_ptr());
-            let info = objc_msgSend(klass, process_info_sel);
-            let args = objc_msgSend(info, arguments_sel);
-
-            let cnt: usize = mem::transmute(objc_msgSend(args, count_sel));
-            for i in 0..cnt {
-                let tmp = objc_msgSend_ul(args, object_at_sel, i as libc::c_ulong);
-                let utf_c_str: *const libc::c_char = mem::transmute(objc_msgSend(tmp, utf8_sel));
-                let bytes = CStr::from_ptr(utf_c_str).to_bytes();
-                res.push(OsString::from(str::from_utf8(bytes).unwrap()))
-            }
-        }
-
-        Args { iter: res.into_iter(), _dont_send_or_sync_me: PhantomData }
-    }
-}