diff options
| author | bors <bors@rust-lang.org> | 2019-11-29 05:04:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-29 05:04:51 +0000 |
| commit | 3907d59bcf6824f32bf9c91205f0c2dbcc467658 (patch) | |
| tree | e136b73a01468cbac8f3e9b6c1666f9dd9927cd1 /src/libstd/sys | |
| parent | 861e96f2e9fabe04965899f30598115dd3a163e9 (diff) | |
| parent | c6bcea965d3efd57b87ef590ad3b593a89253d96 (diff) | |
| download | rust-3907d59bcf6824f32bf9c91205f0c2dbcc467658.tar.gz rust-3907d59bcf6824f32bf9c91205f0c2dbcc467658.zip | |
Auto merge of #66547 - leo60228:procfs-fallback, r=dtolnay
Fallback to .init_array when no arguments are available on glibc Linux Linux is one of the only platforms where `std::env::args` doesn't work in a cdylib.
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/args.rs | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 82ef35ea7b5..15dafb1bcf9 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -72,12 +72,40 @@ mod imp { // acquire this mutex reentrantly! static LOCK: Mutex = Mutex::new(); - pub unsafe fn init(argc: isize, argv: *const *const u8) { + unsafe fn really_init(argc: isize, argv: *const *const u8) { let _guard = LOCK.lock(); ARGC = argc; ARGV = argv; } + #[inline(always)] + pub unsafe fn init(_argc: isize, _argv: *const *const u8) { + #[cfg(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 = 0; |
