2014-11-25 00:21:39 +00:00
|
|
|
//! Implementation of `std::os` functionality for unix systems
|
|
|
|
|
2015-03-10 03:04:35 +00:00
|
|
|
#![allow(unused_imports)] // lots of cfg code here
|
|
|
|
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::os::unix::prelude::*;
|
|
|
|
|
|
|
|
use crate::error::Error as StdError;
|
|
|
|
use crate::ffi::{CString, CStr, OsString, OsStr};
|
|
|
|
use crate::fmt;
|
|
|
|
use crate::io;
|
|
|
|
use crate::iter;
|
|
|
|
use crate::marker::PhantomData;
|
|
|
|
use crate::mem;
|
|
|
|
use crate::memchr;
|
|
|
|
use crate::path::{self, PathBuf};
|
|
|
|
use crate::ptr;
|
|
|
|
use crate::slice;
|
|
|
|
use crate::str;
|
|
|
|
use crate::sys_common::mutex::{Mutex, MutexGuard};
|
|
|
|
use crate::sys::cvt;
|
|
|
|
use crate::sys::fd;
|
|
|
|
use crate::vec;
|
|
|
|
|
|
|
|
use libc::{c_int, c_char, c_void};
|
2014-10-01 00:03:56 +00:00
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
const TMPBUF_SZ: usize = 128;
|
2014-11-25 00:21:39 +00:00
|
|
|
|
2019-04-07 14:39:54 +00:00
|
|
|
cfg_if! {
|
|
|
|
if #[cfg(target_os = "redox")] {
|
|
|
|
const PATH_SEPARATOR: u8 = b';';
|
|
|
|
} else {
|
|
|
|
const PATH_SEPARATOR: u8 = b':';
|
|
|
|
}
|
|
|
|
}
|
2016-07-12 04:43:53 +00:00
|
|
|
|
|
|
|
extern {
|
2016-08-06 20:01:51 +00:00
|
|
|
#[cfg(not(target_os = "dragonfly"))]
|
2017-08-18 09:50:20 +00:00
|
|
|
#[cfg_attr(any(target_os = "linux",
|
|
|
|
target_os = "emscripten",
|
|
|
|
target_os = "fuchsia",
|
|
|
|
target_os = "l4re"),
|
2016-07-12 04:43:53 +00:00
|
|
|
link_name = "__errno_location")]
|
2019-05-13 07:13:07 +00:00
|
|
|
#[cfg_attr(any(target_os = "netbsd",
|
2016-07-12 04:43:53 +00:00
|
|
|
target_os = "openbsd",
|
|
|
|
target_os = "android",
|
2018-07-30 13:50:51 +00:00
|
|
|
target_os = "hermit",
|
2019-04-07 14:39:54 +00:00
|
|
|
target_os = "redox",
|
2016-07-12 04:43:53 +00:00
|
|
|
target_env = "newlib"),
|
|
|
|
link_name = "__errno")]
|
|
|
|
#[cfg_attr(target_os = "solaris", link_name = "___errno")]
|
|
|
|
#[cfg_attr(any(target_os = "macos",
|
|
|
|
target_os = "ios",
|
|
|
|
target_os = "freebsd"),
|
|
|
|
link_name = "__error")]
|
2016-09-25 04:38:56 +00:00
|
|
|
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
|
2016-07-12 04:43:53 +00:00
|
|
|
fn errno_location() -> *mut c_int;
|
|
|
|
}
|
|
|
|
|
2014-10-01 00:03:56 +00:00
|
|
|
/// Returns the platform-specific value of errno
|
2016-04-02 17:06:16 +00:00
|
|
|
#[cfg(not(target_os = "dragonfly"))]
|
2015-01-27 20:20:58 +00:00
|
|
|
pub fn errno() -> i32 {
|
2016-07-12 04:43:53 +00:00
|
|
|
unsafe {
|
|
|
|
(*errno_location()) as i32
|
2014-10-01 00:03:56 +00:00
|
|
|
}
|
2016-07-12 04:43:53 +00:00
|
|
|
}
|
2014-10-01 00:03:56 +00:00
|
|
|
|
2016-07-12 04:43:53 +00:00
|
|
|
/// Sets the platform-specific value of errno
|
2018-12-21 13:53:37 +00:00
|
|
|
#[cfg(all(not(target_os = "linux"),
|
|
|
|
not(target_os = "dragonfly")))] // needed for readdir and syscall!
|
2016-07-12 04:43:53 +00:00
|
|
|
pub fn set_errno(e: i32) {
|
2014-10-01 00:03:56 +00:00
|
|
|
unsafe {
|
2016-07-12 04:43:53 +00:00
|
|
|
*errno_location() = e as c_int
|
2014-10-01 00:03:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-02 17:06:16 +00:00
|
|
|
#[cfg(target_os = "dragonfly")]
|
|
|
|
pub fn errno() -> i32 {
|
|
|
|
extern {
|
|
|
|
#[thread_local]
|
|
|
|
static errno: c_int;
|
|
|
|
}
|
|
|
|
|
2016-12-06 18:31:48 +00:00
|
|
|
unsafe { errno as i32 }
|
2016-04-02 17:06:16 +00:00
|
|
|
}
|
|
|
|
|
2018-12-21 13:53:37 +00:00
|
|
|
#[cfg(target_os = "dragonfly")]
|
|
|
|
pub fn set_errno(e: i32) {
|
|
|
|
extern {
|
|
|
|
#[thread_local]
|
|
|
|
static mut errno: c_int;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
errno = e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-13 14:21:32 +00:00
|
|
|
/// Gets a detailed string description for the given error number.
|
2014-10-01 00:03:56 +00:00
|
|
|
pub fn error_string(errno: i32) -> String {
|
2015-01-27 20:20:58 +00:00
|
|
|
extern {
|
2015-10-25 01:51:34 +00:00
|
|
|
#[cfg_attr(any(target_os = "linux", target_env = "newlib"),
|
|
|
|
link_name = "__xpg_strerror_r")]
|
2015-01-27 20:20:58 +00:00
|
|
|
fn strerror_r(errnum: c_int, buf: *mut c_char,
|
|
|
|
buflen: libc::size_t) -> c_int;
|
2014-10-01 00:03:56 +00:00
|
|
|
}
|
|
|
|
|
2015-01-01 04:40:24 +00:00
|
|
|
let mut buf = [0 as c_char; TMPBUF_SZ];
|
2014-10-01 00:03:56 +00:00
|
|
|
|
|
|
|
let p = buf.as_mut_ptr();
|
|
|
|
unsafe {
|
2016-10-08 13:48:28 +00:00
|
|
|
if strerror_r(errno as c_int, p, buf.len()) < 0 {
|
2014-10-01 00:03:56 +00:00
|
|
|
panic!("strerror_r failure");
|
|
|
|
}
|
|
|
|
|
2014-11-25 21:28:35 +00:00
|
|
|
let p = p as *const _;
|
2015-09-07 22:36:29 +00:00
|
|
|
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
|
2014-10-01 00:03:56 +00:00
|
|
|
}
|
|
|
|
}
|
2014-10-10 17:11:49 +00:00
|
|
|
|
2015-02-23 18:59:17 +00:00
|
|
|
pub fn getcwd() -> io::Result<PathBuf> {
|
2015-08-26 12:27:32 +00:00
|
|
|
let mut buf = Vec::with_capacity(512);
|
2015-07-10 10:33:10 +00:00
|
|
|
loop {
|
2015-07-08 19:36:46 +00:00
|
|
|
unsafe {
|
2015-07-09 13:03:10 +00:00
|
|
|
let ptr = buf.as_mut_ptr() as *mut libc::c_char;
|
2016-10-08 13:48:28 +00:00
|
|
|
if !libc::getcwd(ptr, buf.capacity()).is_null() {
|
2015-07-09 13:03:10 +00:00
|
|
|
let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len();
|
|
|
|
buf.set_len(len);
|
2015-07-10 10:33:10 +00:00
|
|
|
buf.shrink_to_fit();
|
|
|
|
return Ok(PathBuf::from(OsString::from_vec(buf)));
|
2015-07-08 19:36:46 +00:00
|
|
|
} else {
|
|
|
|
let error = io::Error::last_os_error();
|
2015-07-10 10:33:10 +00:00
|
|
|
if error.raw_os_error() != Some(libc::ERANGE) {
|
|
|
|
return Err(error);
|
2015-07-08 19:36:46 +00:00
|
|
|
}
|
2015-07-10 10:33:10 +00:00
|
|
|
}
|
2015-08-26 12:27:32 +00:00
|
|
|
|
|
|
|
// Trigger the internal buffer resizing logic of `Vec` by requiring
|
|
|
|
// more space than the current capacity.
|
|
|
|
let cap = buf.capacity();
|
|
|
|
buf.set_len(cap);
|
|
|
|
buf.reserve(1);
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
2015-07-10 10:33:10 +00:00
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
2015-02-23 18:59:17 +00:00
|
|
|
pub fn chdir(p: &path::Path) -> io::Result<()> {
|
2015-03-30 18:00:05 +00:00
|
|
|
let p: &OsStr = p.as_ref();
|
2016-03-23 03:01:37 +00:00
|
|
|
let p = CString::new(p.as_bytes())?;
|
2015-01-27 20:20:58 +00:00
|
|
|
unsafe {
|
|
|
|
match libc::chdir(p.as_ptr()) == (0 as c_int) {
|
|
|
|
true => Ok(()),
|
2015-02-23 18:59:17 +00:00
|
|
|
false => Err(io::Error::last_os_error()),
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SplitPaths<'a> {
|
2015-02-02 19:04:58 +00:00
|
|
|
iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>,
|
2015-02-23 18:59:17 +00:00
|
|
|
fn(&'a [u8]) -> PathBuf>,
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
|
2019-03-01 08:34:11 +00:00
|
|
|
pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> {
|
2015-07-09 13:03:10 +00:00
|
|
|
fn bytes_to_path(b: &[u8]) -> PathBuf {
|
|
|
|
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
|
|
|
|
}
|
2019-04-07 14:39:54 +00:00
|
|
|
fn is_separator(b: &u8) -> bool { *b == PATH_SEPARATOR }
|
2015-02-06 17:42:57 +00:00
|
|
|
let unparsed = unparsed.as_bytes();
|
2015-01-27 20:20:58 +00:00
|
|
|
SplitPaths {
|
2019-04-07 14:39:54 +00:00
|
|
|
iter: unparsed.split(is_separator as fn(&u8) -> bool)
|
2015-09-08 06:05:59 +00:00
|
|
|
.map(bytes_to_path as fn(&[u8]) -> PathBuf)
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
impl<'a> Iterator for SplitPaths<'a> {
|
2015-02-23 18:59:17 +00:00
|
|
|
type Item = PathBuf;
|
|
|
|
fn next(&mut self) -> Option<PathBuf> { self.iter.next() }
|
2015-01-27 20:20:58 +00:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct JoinPathsError;
|
|
|
|
|
|
|
|
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
|
2015-03-30 18:00:05 +00:00
|
|
|
where I: Iterator<Item=T>, T: AsRef<OsStr>
|
2015-01-27 20:20:58 +00:00
|
|
|
{
|
2014-11-25 00:21:39 +00:00
|
|
|
let mut joined = Vec::new();
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
for (i, path) in paths.enumerate() {
|
2015-03-30 18:00:05 +00:00
|
|
|
let path = path.as_ref().as_bytes();
|
2019-04-07 14:39:54 +00:00
|
|
|
if i > 0 { joined.push(PATH_SEPARATOR) }
|
|
|
|
if path.contains(&PATH_SEPARATOR) {
|
2015-01-27 20:20:58 +00:00
|
|
|
return Err(JoinPathsError)
|
|
|
|
}
|
2015-12-03 01:31:49 +00:00
|
|
|
joined.extend_from_slice(path);
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
Ok(OsStringExt::from_vec(joined))
|
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
impl fmt::Display for JoinPathsError {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2019-04-07 14:39:54 +00:00
|
|
|
write!(f, "path segment contains separator `{}`", PATH_SEPARATOR)
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl StdError for JoinPathsError {
|
|
|
|
fn description(&self) -> &str { "failed to join paths" }
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 18:31:48 +00:00
|
|
|
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
2015-02-25 08:45:24 +00:00
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
2014-11-25 00:21:39 +00:00
|
|
|
unsafe {
|
2015-11-17 00:53:06 +00:00
|
|
|
let mut mib = [libc::CTL_KERN as c_int,
|
|
|
|
libc::KERN_PROC as c_int,
|
|
|
|
libc::KERN_PROC_PATHNAME as c_int,
|
2015-10-12 10:37:28 +00:00
|
|
|
-1 as c_int];
|
2016-10-08 13:48:28 +00:00
|
|
|
let mut sz = 0;
|
2019-02-10 19:23:21 +00:00
|
|
|
cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as libc::c_uint,
|
2016-10-08 13:48:28 +00:00
|
|
|
ptr::null_mut(), &mut sz, ptr::null_mut(), 0))?;
|
2015-12-02 18:31:29 +00:00
|
|
|
if sz == 0 {
|
|
|
|
return Err(io::Error::last_os_error())
|
|
|
|
}
|
2016-10-08 13:48:28 +00:00
|
|
|
let mut v: Vec<u8> = Vec::with_capacity(sz);
|
2019-02-10 19:23:21 +00:00
|
|
|
cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as libc::c_uint,
|
2016-03-22 22:58:45 +00:00
|
|
|
v.as_mut_ptr() as *mut libc::c_void, &mut sz,
|
2016-10-08 13:48:28 +00:00
|
|
|
ptr::null_mut(), 0))?;
|
2015-12-02 18:31:29 +00:00
|
|
|
if sz == 0 {
|
|
|
|
return Err(io::Error::last_os_error());
|
|
|
|
}
|
2016-10-08 13:48:28 +00:00
|
|
|
v.set_len(sz - 1); // chop off trailing NUL
|
2015-03-25 07:42:15 +00:00
|
|
|
Ok(PathBuf::from(OsString::from_vec(v)))
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-20 15:39:52 +00:00
|
|
|
#[cfg(target_os = "netbsd")]
|
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
2017-11-29 17:31:09 +00:00
|
|
|
fn sysctl() -> io::Result<PathBuf> {
|
|
|
|
unsafe {
|
|
|
|
let mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, -1, libc::KERN_PROC_PATHNAME];
|
|
|
|
let mut path_len: usize = 0;
|
2019-02-10 19:23:21 +00:00
|
|
|
cvt(libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
|
2017-11-29 17:31:09 +00:00
|
|
|
ptr::null_mut(), &mut path_len,
|
|
|
|
ptr::null(), 0))?;
|
|
|
|
if path_len <= 1 {
|
|
|
|
return Err(io::Error::new(io::ErrorKind::Other,
|
|
|
|
"KERN_PROC_PATHNAME sysctl returned zero-length string"))
|
|
|
|
}
|
|
|
|
let mut path: Vec<u8> = Vec::with_capacity(path_len);
|
2019-02-10 19:23:21 +00:00
|
|
|
cvt(libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
|
2017-11-29 17:31:09 +00:00
|
|
|
path.as_ptr() as *mut libc::c_void, &mut path_len,
|
|
|
|
ptr::null(), 0))?;
|
|
|
|
path.set_len(path_len - 1); // chop off NUL
|
|
|
|
Ok(PathBuf::from(OsString::from_vec(path)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn procfs() -> io::Result<PathBuf> {
|
|
|
|
let curproc_exe = path::Path::new("/proc/curproc/exe");
|
|
|
|
if curproc_exe.is_file() {
|
2019-02-10 19:23:21 +00:00
|
|
|
return crate::fs::read_link(curproc_exe);
|
2017-11-29 17:31:09 +00:00
|
|
|
}
|
|
|
|
Err(io::Error::new(io::ErrorKind::Other,
|
|
|
|
"/proc/curproc/exe doesn't point to regular file."))
|
|
|
|
}
|
|
|
|
sysctl().or_else(|_| procfs())
|
2015-09-20 15:39:52 +00:00
|
|
|
}
|
|
|
|
|
2019-05-13 07:13:07 +00:00
|
|
|
#[cfg(target_os = "openbsd")]
|
2015-02-23 18:59:17 +00:00
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
2015-01-29 07:19:28 +00:00
|
|
|
unsafe {
|
2015-12-02 18:31:29 +00:00
|
|
|
let mut mib = [libc::CTL_KERN,
|
|
|
|
libc::KERN_PROC_ARGS,
|
|
|
|
libc::getpid(),
|
|
|
|
libc::KERN_PROC_ARGV];
|
|
|
|
let mib = mib.as_mut_ptr();
|
|
|
|
let mut argv_len = 0;
|
2016-06-24 18:54:52 +00:00
|
|
|
cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_len,
|
|
|
|
ptr::null_mut(), 0))?;
|
2015-12-02 18:31:29 +00:00
|
|
|
let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize);
|
2016-03-23 03:01:37 +00:00
|
|
|
cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _,
|
2016-06-24 18:54:52 +00:00
|
|
|
&mut argv_len, ptr::null_mut(), 0))?;
|
2015-12-02 18:31:29 +00:00
|
|
|
argv.set_len(argv_len as usize);
|
|
|
|
if argv[0].is_null() {
|
|
|
|
return Err(io::Error::new(io::ErrorKind::Other,
|
|
|
|
"no current exe available"))
|
|
|
|
}
|
|
|
|
let argv0 = CStr::from_ptr(argv[0]).to_bytes();
|
|
|
|
if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
|
2019-02-10 19:23:21 +00:00
|
|
|
crate::fs::canonicalize(OsStr::from_bytes(argv0))
|
2015-01-29 07:19:28 +00:00
|
|
|
} else {
|
2015-12-02 18:31:29 +00:00
|
|
|
Ok(PathBuf::from(OsStr::from_bytes(argv0)))
|
2015-01-29 07:19:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-26 19:05:10 +00:00
|
|
|
#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
|
2015-02-23 18:59:17 +00:00
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
2019-02-10 19:23:21 +00:00
|
|
|
match crate::fs::read_link("/proc/self/exe") {
|
2018-12-05 01:48:18 +00:00
|
|
|
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
|
|
|
|
Err(io::Error::new(
|
|
|
|
io::ErrorKind::Other,
|
|
|
|
"no /proc/self/exe available. Is /proc mounted?"
|
|
|
|
))
|
|
|
|
},
|
|
|
|
other => other,
|
2017-05-17 13:14:30 +00:00
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
2015-02-25 08:45:24 +00:00
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
2015-11-03 00:23:22 +00:00
|
|
|
extern {
|
|
|
|
fn _NSGetExecutablePath(buf: *mut libc::c_char,
|
|
|
|
bufsize: *mut u32) -> libc::c_int;
|
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
unsafe {
|
|
|
|
let mut sz: u32 = 0;
|
|
|
|
_NSGetExecutablePath(ptr::null_mut(), &mut sz);
|
2015-02-25 08:45:24 +00:00
|
|
|
if sz == 0 { return Err(io::Error::last_os_error()); }
|
2015-03-26 00:06:52 +00:00
|
|
|
let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
|
2014-11-25 00:21:39 +00:00
|
|
|
let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
|
2015-02-25 08:45:24 +00:00
|
|
|
if err != 0 { return Err(io::Error::last_os_error()); }
|
2015-03-26 00:06:52 +00:00
|
|
|
v.set_len(sz as usize - 1); // chop off trailing NUL
|
2015-03-18 16:14:54 +00:00
|
|
|
Ok(PathBuf::from(OsString::from_vec(v)))
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-28 11:02:31 +00:00
|
|
|
#[cfg(any(target_os = "solaris"))]
|
2016-01-21 16:30:22 +00:00
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
|
|
|
extern {
|
|
|
|
fn getexecname() -> *const c_char;
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
let path = getexecname();
|
|
|
|
if path.is_null() {
|
|
|
|
Err(io::Error::last_os_error())
|
|
|
|
} else {
|
|
|
|
let filename = CStr::from_ptr(path).to_bytes();
|
2016-01-26 14:15:10 +00:00
|
|
|
let path = PathBuf::from(<OsStr as OsStrExt>::from_bytes(filename));
|
|
|
|
|
|
|
|
// Prepend a current working directory to the path if
|
|
|
|
// it doesn't contain an absolute pathname.
|
2016-01-21 16:30:22 +00:00
|
|
|
if filename[0] == b'/' {
|
2016-01-26 14:15:10 +00:00
|
|
|
Ok(path)
|
2016-01-21 16:30:22 +00:00
|
|
|
} else {
|
2016-01-26 14:15:10 +00:00
|
|
|
getcwd().map(|cwd| cwd.join(path))
|
2016-01-21 16:30:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-25 04:38:56 +00:00
|
|
|
#[cfg(target_os = "haiku")]
|
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
|
|
|
// Use Haiku's image info functions
|
|
|
|
#[repr(C)]
|
|
|
|
struct image_info {
|
|
|
|
id: i32,
|
|
|
|
type_: i32,
|
|
|
|
sequence: i32,
|
|
|
|
init_order: i32,
|
|
|
|
init_routine: *mut libc::c_void, // function pointer
|
|
|
|
term_routine: *mut libc::c_void, // function pointer
|
|
|
|
device: libc::dev_t,
|
|
|
|
node: libc::ino_t,
|
|
|
|
name: [libc::c_char; 1024], // MAXPATHLEN
|
|
|
|
text: *mut libc::c_void,
|
|
|
|
data: *mut libc::c_void,
|
|
|
|
text_size: i32,
|
|
|
|
data_size: i32,
|
|
|
|
api_version: i32,
|
|
|
|
abi: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
extern {
|
|
|
|
fn _get_next_image_info(team_id: i32, cookie: *mut i32,
|
|
|
|
info: *mut image_info, size: i32) -> i32;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut info: image_info = mem::zeroed();
|
|
|
|
let mut cookie: i32 = 0;
|
|
|
|
// the executable can be found at team id 0
|
|
|
|
let result = _get_next_image_info(0, &mut cookie, &mut info,
|
|
|
|
mem::size_of::<image_info>() as i32);
|
|
|
|
if result != 0 {
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::io::ErrorKind;
|
2016-09-25 04:38:56 +00:00
|
|
|
Err(io::Error::new(ErrorKind::Other, "Error getting executable path"))
|
|
|
|
} else {
|
|
|
|
let name = CStr::from_ptr(info.name.as_ptr()).to_bytes();
|
|
|
|
Ok(PathBuf::from(OsStr::from_bytes(name)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-07 14:39:54 +00:00
|
|
|
#[cfg(target_os = "redox")]
|
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
|
|
|
crate::fs::read_to_string("sys:exe").map(PathBuf::from)
|
|
|
|
}
|
|
|
|
|
2018-07-30 13:50:51 +00:00
|
|
|
#[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))]
|
2016-10-18 20:43:18 +00:00
|
|
|
pub fn current_exe() -> io::Result<PathBuf> {
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::io::ErrorKind;
|
2017-08-18 09:50:20 +00:00
|
|
|
Err(io::Error::new(ErrorKind::Other, "Not yet implemented!"))
|
2016-10-18 20:43:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
pub struct Env {
|
|
|
|
iter: vec::IntoIter<(OsString, OsString)>,
|
2016-08-06 18:42:22 +00:00
|
|
|
_dont_send_or_sync_me: PhantomData<*mut ()>,
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Iterator for Env {
|
|
|
|
type Item = (OsString, OsString);
|
|
|
|
fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
pub unsafe fn environ() -> *mut *const *const c_char {
|
|
|
|
extern { fn _NSGetEnviron() -> *mut *const *const c_char; }
|
|
|
|
_NSGetEnviron()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_os = "macos"))]
|
|
|
|
pub unsafe fn environ() -> *mut *const *const c_char {
|
|
|
|
extern { static mut environ: *const *const c_char; }
|
|
|
|
&mut environ
|
|
|
|
}
|
|
|
|
|
2018-11-13 22:57:10 +00:00
|
|
|
pub unsafe fn env_lock() -> MutexGuard<'static> {
|
|
|
|
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
|
|
|
|
// acquire this mutex reentrantly!
|
|
|
|
static ENV_LOCK: Mutex = Mutex::new();
|
|
|
|
ENV_LOCK.lock()
|
|
|
|
}
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
/// Returns a vector of (variable, value) byte-vector pairs for all the
|
|
|
|
/// environment variables of the current process.
|
|
|
|
pub fn env() -> Env {
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
unsafe {
|
2018-11-13 22:57:10 +00:00
|
|
|
let _guard = env_lock();
|
2015-01-27 20:20:58 +00:00
|
|
|
let mut environ = *environ();
|
|
|
|
let mut result = Vec::new();
|
2018-08-08 22:23:52 +00:00
|
|
|
while environ != ptr::null() && *environ != ptr::null() {
|
2015-10-25 12:05:34 +00:00
|
|
|
if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
|
|
|
result.push(key_value);
|
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
environ = environ.offset(1);
|
|
|
|
}
|
2018-06-09 13:13:04 +00:00
|
|
|
return Env {
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
iter: result.into_iter(),
|
2016-08-06 18:42:22 +00:00
|
|
|
_dont_send_or_sync_me: PhantomData,
|
2018-06-09 13:13:04 +00:00
|
|
|
}
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
|
2015-10-25 12:05:34 +00:00
|
|
|
fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
|
|
|
|
// Strategy (copied from glibc): Variable name and value are separated
|
|
|
|
// by an ASCII equals sign '='. Since a variable name must not be
|
|
|
|
// empty, allow variable names starting with an equals sign. Skip all
|
|
|
|
// malformed lines.
|
|
|
|
if input.is_empty() {
|
|
|
|
return None;
|
|
|
|
}
|
2015-12-14 23:03:42 +00:00
|
|
|
let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
|
2015-10-25 12:05:34 +00:00
|
|
|
pos.map(|p| (
|
|
|
|
OsStringExt::from_vec(input[..p].to_vec()),
|
|
|
|
OsStringExt::from_vec(input[p+1..].to_vec()),
|
|
|
|
))
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-25 17:19:35 +00:00
|
|
|
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
|
|
|
// environment variables with a nul byte can't be set, so their value is
|
|
|
|
// always None as well
|
2016-03-23 03:01:37 +00:00
|
|
|
let k = CString::new(k.as_bytes())?;
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
unsafe {
|
2018-11-13 22:57:10 +00:00
|
|
|
let _guard = env_lock();
|
2017-12-22 17:40:39 +00:00
|
|
|
let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
let ret = if s.is_null() {
|
2015-01-27 20:20:58 +00:00
|
|
|
None
|
|
|
|
} else {
|
2015-02-18 06:47:40 +00:00
|
|
|
Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
};
|
2018-06-09 13:13:04 +00:00
|
|
|
Ok(ret)
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 17:19:35 +00:00
|
|
|
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
|
2016-03-23 03:01:37 +00:00
|
|
|
let k = CString::new(k.as_bytes())?;
|
|
|
|
let v = CString::new(v.as_bytes())?;
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
|
|
|
|
unsafe {
|
2018-11-13 22:57:10 +00:00
|
|
|
let _guard = env_lock();
|
2018-06-09 13:13:04 +00:00
|
|
|
cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
|
2015-10-25 17:19:35 +00:00
|
|
|
pub fn unsetenv(n: &OsStr) -> io::Result<()> {
|
2016-03-23 03:01:37 +00:00
|
|
|
let nbuf = CString::new(n.as_bytes())?;
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
|
|
|
|
unsafe {
|
2018-11-13 22:57:10 +00:00
|
|
|
let _guard = env_lock();
|
2018-06-09 13:13:04 +00:00
|
|
|
cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 18:57:07 +00:00
|
|
|
}
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 20:20:58 +00:00
|
|
|
pub fn page_size() -> usize {
|
2014-11-25 00:21:39 +00:00
|
|
|
unsafe {
|
2015-01-27 20:20:58 +00:00
|
|
|
libc::sysconf(libc::_SC_PAGESIZE) as usize
|
2014-11-25 00:21:39 +00:00
|
|
|
}
|
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
|
2015-02-23 18:59:17 +00:00
|
|
|
pub fn temp_dir() -> PathBuf {
|
2019-02-10 19:23:21 +00:00
|
|
|
crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| {
|
2015-01-27 20:20:58 +00:00
|
|
|
if cfg!(target_os = "android") {
|
2015-03-18 16:14:54 +00:00
|
|
|
PathBuf::from("/data/local/tmp")
|
2015-01-27 20:20:58 +00:00
|
|
|
} else {
|
2015-03-18 16:14:54 +00:00
|
|
|
PathBuf::from("/tmp")
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-02-23 18:59:17 +00:00
|
|
|
pub fn home_dir() -> Option<PathBuf> {
|
2019-02-10 19:23:21 +00:00
|
|
|
return crate::env::var_os("HOME").or_else(|| unsafe {
|
2015-02-02 19:04:58 +00:00
|
|
|
fallback()
|
2015-07-09 13:03:10 +00:00
|
|
|
}).map(PathBuf::from);
|
2015-02-02 19:04:58 +00:00
|
|
|
|
2015-02-03 13:30:10 +00:00
|
|
|
#[cfg(any(target_os = "android",
|
2015-10-25 01:51:34 +00:00
|
|
|
target_os = "ios",
|
2019-04-07 14:39:54 +00:00
|
|
|
target_os = "emscripten",
|
|
|
|
target_os = "redox"))]
|
2015-02-02 19:04:58 +00:00
|
|
|
unsafe fn fallback() -> Option<OsString> { None }
|
2015-02-03 13:30:10 +00:00
|
|
|
#[cfg(not(any(target_os = "android",
|
2015-10-25 01:51:34 +00:00
|
|
|
target_os = "ios",
|
2019-04-07 14:39:54 +00:00
|
|
|
target_os = "emscripten",
|
|
|
|
target_os = "redox")))]
|
2015-02-02 19:04:58 +00:00
|
|
|
unsafe fn fallback() -> Option<OsString> {
|
2015-11-03 00:23:22 +00:00
|
|
|
let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
|
2015-01-27 20:20:58 +00:00
|
|
|
n if n < 0 => 512 as usize,
|
|
|
|
n => n as usize,
|
|
|
|
};
|
2016-08-27 19:01:27 +00:00
|
|
|
let mut buf = Vec::with_capacity(amt);
|
|
|
|
let mut passwd: libc::passwd = mem::zeroed();
|
2017-02-16 06:52:47 +00:00
|
|
|
let mut result = ptr::null_mut();
|
|
|
|
match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(),
|
|
|
|
buf.capacity(), &mut result) {
|
|
|
|
0 if !result.is_null() => {
|
|
|
|
let ptr = passwd.pw_dir as *const _;
|
|
|
|
let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
|
|
|
|
Some(OsStringExt::from_vec(bytes))
|
|
|
|
},
|
|
|
|
_ => None,
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
2015-02-02 19:04:58 +00:00
|
|
|
}
|
2015-01-27 20:20:58 +00:00
|
|
|
}
|
2015-03-31 21:41:59 +00:00
|
|
|
|
|
|
|
pub fn exit(code: i32) -> ! {
|
|
|
|
unsafe { libc::exit(code as c_int) }
|
|
|
|
}
|
2017-10-06 05:49:36 +00:00
|
|
|
|
|
|
|
pub fn getpid() -> u32 {
|
|
|
|
unsafe { libc::getpid() as u32 }
|
|
|
|
}
|
2017-11-19 05:09:18 +00:00
|
|
|
|
|
|
|
pub fn getppid() -> u32 {
|
|
|
|
unsafe { libc::getppid() as u32 }
|
|
|
|
}
|
2018-03-02 20:50:07 +00:00
|
|
|
|
|
|
|
#[cfg(target_env = "gnu")]
|
|
|
|
pub fn glibc_version() -> Option<(usize, usize)> {
|
|
|
|
if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) {
|
|
|
|
parse_glibc_version(version_str)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_env = "gnu")]
|
|
|
|
fn glibc_version_cstr() -> Option<&'static CStr> {
|
|
|
|
weak! {
|
|
|
|
fn gnu_get_libc_version() -> *const libc::c_char
|
|
|
|
}
|
|
|
|
if let Some(f) = gnu_get_libc_version.get() {
|
|
|
|
unsafe { Some(CStr::from_ptr(f())) }
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns Some((major, minor)) if the string is a valid "x.y" version,
|
|
|
|
// ignoring any extra dot-separated parts. Otherwise return None.
|
|
|
|
#[cfg(target_env = "gnu")]
|
|
|
|
fn parse_glibc_version(version: &str) -> Option<(usize, usize)> {
|
2018-07-23 13:32:57 +00:00
|
|
|
let mut parsed_ints = version.split('.').map(str::parse::<usize>).fuse();
|
2018-03-02 20:50:07 +00:00
|
|
|
match (parsed_ints.next(), parsed_ints.next()) {
|
|
|
|
(Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)),
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
2018-08-27 17:25:58 +00:00
|
|
|
|
|
|
|
#[cfg(all(test, target_env = "gnu"))]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_glibc_version() {
|
|
|
|
// This mostly just tests that the weak linkage doesn't panic wildly...
|
|
|
|
glibc_version();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_parse_glibc_version() {
|
|
|
|
let cases = [
|
|
|
|
("0.0", Some((0, 0))),
|
|
|
|
("01.+2", Some((1, 2))),
|
|
|
|
("3.4.5.six", Some((3, 4))),
|
|
|
|
("1", None),
|
|
|
|
("1.-2", None),
|
|
|
|
("1.foo", None),
|
|
|
|
("foo.1", None),
|
|
|
|
];
|
|
|
|
for &(version_str, parsed) in cases.iter() {
|
|
|
|
assert_eq!(parsed, parse_glibc_version(version_str));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|