Format libstd/sys with rustfmt
This commit applies rustfmt with rust-lang/rust's default settings to files in src/libstd/sys *that are not involved in any currently open PR* to minimize merge conflicts. THe list of files involved in open PRs was determined by querying GitHub's GraphQL API with this script: https://gist.github.com/dtolnay/aa9c34993dc051a4f344d1b10e4487e8 With the list of files from the script in outstanding_files, the relevant commands were: $ find src/libstd/sys -name '*.rs' \ | xargs rustfmt --edition=2018 --unstable-features --skip-children $ rg libstd/sys outstanding_files | xargs git checkout -- Repeating this process several months apart should get us coverage of most of the rest of the files. To confirm no funny business: $ git checkout $THIS_COMMIT^ $ git show --pretty= --name-only $THIS_COMMIT \ | xargs rustfmt --edition=2018 --unstable-features --skip-children $ git diff $THIS_COMMIT # there should be no difference
This commit is contained in:
parent
9081929d45
commit
c34fbfaad3
144 changed files with 2527 additions and 2285 deletions
|
@ -18,9 +18,7 @@ pub fn errno() -> i32 {
|
|||
pub fn error_string(errno: i32) -> String {
|
||||
// cloudlibc's strerror() is guaranteed to be thread-safe. There is
|
||||
// thus no need to use strerror_r().
|
||||
str::from_utf8(unsafe { CStr::from_ptr(libc::strerror(errno)) }.to_bytes())
|
||||
.unwrap()
|
||||
.to_owned()
|
||||
str::from_utf8(unsafe { CStr::from_ptr(libc::strerror(errno)) }.to_bytes()).unwrap().to_owned()
|
||||
}
|
||||
|
||||
pub fn exit(code: i32) -> ! {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, SeekFrom, IoSlice, IoSliceMut};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
|
|
|
@ -4,19 +4,16 @@ pub mod args;
|
|||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
#[path = "../../unix/path.rs"]
|
||||
pub mod path;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod os;
|
||||
|
||||
// This enum is used as the storage for a bunch of types which can't actually exist.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub enum Void {}
|
||||
|
||||
pub fn unsupported<T>() -> io::Result<T> {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"This function is not available on CloudABI.",
|
||||
))
|
||||
Err(io::Error::new(io::ErrorKind::Other, "This function is not available on CloudABI."))
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::convert::TryFrom;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||
use crate::time::Duration;
|
||||
use crate::sys::{unsupported, Void};
|
||||
use crate::convert::TryFrom;
|
||||
use crate::time::Duration;
|
||||
|
||||
#[allow(unused_extern_crates)]
|
||||
pub extern crate libc as netc;
|
||||
|
|
|
@ -32,9 +32,7 @@ pub enum Stdio {
|
|||
|
||||
impl Command {
|
||||
pub fn new(_program: &OsStr) -> Command {
|
||||
Command {
|
||||
env: Default::default(),
|
||||
}
|
||||
Command { env: Default::default() }
|
||||
}
|
||||
|
||||
pub fn arg(&mut self, _arg: &OsStr) {}
|
||||
|
|
|
@ -58,8 +58,8 @@ impl Thread {
|
|||
}
|
||||
|
||||
pub fn sleep(dur: Duration) {
|
||||
let timeout = checked_dur2intervals(&dur)
|
||||
.expect("overflow converting duration to nanoseconds");
|
||||
let timeout =
|
||||
checked_dur2intervals(&dur).expect("overflow converting duration to nanoseconds");
|
||||
unsafe {
|
||||
let subscription = abi::subscription {
|
||||
type_: abi::eventtype::CLOCK,
|
||||
|
@ -85,11 +85,7 @@ impl Thread {
|
|||
unsafe {
|
||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||
mem::forget(self);
|
||||
assert!(
|
||||
ret == 0,
|
||||
"failed to join thread: {}",
|
||||
io::Error::from_raw_os_error(ret)
|
||||
);
|
||||
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,7 @@ pub struct Instant {
|
|||
}
|
||||
|
||||
pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
|
||||
dur.as_secs()
|
||||
.checked_mul(NSEC_PER_SEC)?
|
||||
.checked_add(dur.subsec_nanos() as abi::timestamp)
|
||||
dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as abi::timestamp)
|
||||
}
|
||||
|
||||
impl Instant {
|
||||
|
@ -39,15 +37,11 @@ impl Instant {
|
|||
}
|
||||
|
||||
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
|
||||
Some(Instant {
|
||||
t: self.t.checked_add(checked_dur2intervals(other)?)?,
|
||||
})
|
||||
Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
|
||||
}
|
||||
|
||||
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
|
||||
Some(Instant {
|
||||
t: self.t.checked_sub(checked_dur2intervals(other)?)?,
|
||||
})
|
||||
Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,29 +63,19 @@ impl SystemTime {
|
|||
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||
if self.t >= other.t {
|
||||
let diff = self.t - other.t;
|
||||
Ok(Duration::new(
|
||||
diff / NSEC_PER_SEC,
|
||||
(diff % NSEC_PER_SEC) as u32,
|
||||
))
|
||||
Ok(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
|
||||
} else {
|
||||
let diff = other.t - self.t;
|
||||
Err(Duration::new(
|
||||
diff / NSEC_PER_SEC,
|
||||
(diff % NSEC_PER_SEC) as u32,
|
||||
))
|
||||
Err(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
|
||||
Some(SystemTime {
|
||||
t: self.t.checked_add(checked_dur2intervals(other)?)?,
|
||||
})
|
||||
Some(SystemTime { t: self.t.checked_add(checked_dur2intervals(other)?)? })
|
||||
}
|
||||
|
||||
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
|
||||
Some(SystemTime {
|
||||
t: self.t.checked_sub(checked_dur2intervals(other)?)?,
|
||||
})
|
||||
Some(SystemTime { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,7 @@ unsafe impl GlobalAlloc for System {
|
|||
let addr = abi::malloc(layout.size(), layout.align());
|
||||
|
||||
if !addr.is_null() {
|
||||
ptr::write_bytes(
|
||||
addr,
|
||||
0x00,
|
||||
layout.size()
|
||||
);
|
||||
ptr::write_bytes(addr, 0x00, layout.size());
|
||||
}
|
||||
|
||||
addr
|
||||
|
|
|
@ -3,10 +3,14 @@ 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) }
|
||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||
imp::init(argc, argv)
|
||||
}
|
||||
|
||||
/// One-time global cleanup.
|
||||
pub unsafe fn cleanup() { imp::cleanup() }
|
||||
pub unsafe fn cleanup() {
|
||||
imp::cleanup()
|
||||
}
|
||||
|
||||
/// Returns the command line arguments
|
||||
pub fn args() -> Args {
|
||||
|
@ -26,24 +30,32 @@ impl Args {
|
|||
|
||||
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() }
|
||||
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() }
|
||||
fn len(&self) -> usize {
|
||||
self.iter.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl DoubleEndedIterator for Args {
|
||||
fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
|
||||
fn next_back(&mut self) -> Option<OsString> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use crate::sys_common::os_str_bytes::*;
|
||||
use crate::ptr;
|
||||
use super::Args;
|
||||
use crate::ffi::{CStr, OsString};
|
||||
use crate::marker::PhantomData;
|
||||
use super::Args;
|
||||
use crate::ptr;
|
||||
use crate::sys_common::os_str_bytes::*;
|
||||
|
||||
use crate::sys_common::mutex::Mutex;
|
||||
|
||||
|
@ -64,19 +76,18 @@ mod imp {
|
|||
}
|
||||
|
||||
pub fn args() -> Args {
|
||||
Args {
|
||||
iter: clone().into_iter(),
|
||||
_dont_send_or_sync_me: PhantomData
|
||||
}
|
||||
Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData }
|
||||
}
|
||||
|
||||
fn clone() -> Vec<OsString> {
|
||||
unsafe {
|
||||
let _guard = LOCK.lock();
|
||||
(0..ARGC).map(|i| {
|
||||
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
|
||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||
}).collect()
|
||||
(0..ARGC)
|
||||
.map(|i| {
|
||||
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
|
||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// These symbols are all defined in `compiler-builtins`
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn acos(n: f64) -> f64;
|
||||
pub fn acosf(n: f32) -> f32;
|
||||
pub fn asin(n: f64) -> f64;
|
||||
|
|
|
@ -18,12 +18,12 @@ impl Condvar {
|
|||
}
|
||||
|
||||
pub unsafe fn notify_one(&self) {
|
||||
let _ = abi::notify(self.id(), 1);
|
||||
let _ = abi::notify(self.id(), 1);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn notify_all(&self) {
|
||||
let _ = abi::notify(self.id(), -1 /* =all */);
|
||||
let _ = abi::notify(self.id(), -1 /* =all */);
|
||||
}
|
||||
|
||||
pub unsafe fn wait(&self, mutex: &Mutex) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
||||
|
||||
use crate::io::{self, Read, ErrorKind};
|
||||
use crate::io::{self, ErrorKind, Read};
|
||||
use crate::mem;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::hermit::abi;
|
||||
|
@ -16,7 +16,9 @@ impl FileDesc {
|
|||
FileDesc { fd }
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> i32 { self.fd }
|
||||
pub fn raw(&self) -> i32 {
|
||||
self.fd
|
||||
}
|
||||
|
||||
/// Extracts the actual file descriptor without closing it.
|
||||
pub fn into_raw(self) -> i32 {
|
||||
|
@ -67,7 +69,9 @@ impl<'a> Read for &'a FileDesc {
|
|||
}
|
||||
|
||||
impl AsInner<i32> for FileDesc {
|
||||
fn as_inner(&self) -> &i32 { &self.fd }
|
||||
fn as_inner(&self) -> &i32 {
|
||||
&self.fd
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FileDesc {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use crate::ffi::{OsString, CString, CStr};
|
||||
use crate::ffi::{CStr, CString, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, ErrorKind};
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{SeekFrom, IoSlice, IoSliceMut};
|
||||
use crate::io::{self, Error, ErrorKind};
|
||||
use crate::io::{IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::hermit::abi;
|
||||
use crate::sys::hermit::fd::FileDesc;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
use crate::sys_common::os_str_bytes::OsStrExt;
|
||||
|
||||
pub use crate::sys_common::fs::copy;
|
||||
|
@ -45,7 +45,7 @@ pub struct OpenOptions {
|
|||
create: bool,
|
||||
create_new: bool,
|
||||
// system-specific
|
||||
mode: i32
|
||||
mode: i32,
|
||||
}
|
||||
|
||||
pub struct FilePermissions(Void);
|
||||
|
@ -53,7 +53,7 @@ pub struct FilePermissions(Void);
|
|||
pub struct FileType(Void);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DirBuilder { }
|
||||
pub struct DirBuilder {}
|
||||
|
||||
impl FileAttr {
|
||||
pub fn size(&self) -> u64 {
|
||||
|
@ -109,8 +109,7 @@ impl PartialEq for FilePermissions {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for FilePermissions {
|
||||
}
|
||||
impl Eq for FilePermissions {}
|
||||
|
||||
impl fmt::Debug for FilePermissions {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
@ -146,8 +145,7 @@ impl PartialEq for FileType {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for FileType {
|
||||
}
|
||||
impl Eq for FileType {}
|
||||
|
||||
impl Hash for FileType {
|
||||
fn hash<H: Hasher>(&self, _h: &mut H) {
|
||||
|
@ -204,50 +202,64 @@ impl OpenOptions {
|
|||
create: false,
|
||||
create_new: false,
|
||||
// system-specific
|
||||
mode: 0x777
|
||||
mode: 0x777,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&mut self, read: bool) { self.read = read; }
|
||||
pub fn write(&mut self, write: bool) { self.write = write; }
|
||||
pub fn append(&mut self, append: bool) { self.append = append; }
|
||||
pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
|
||||
pub fn create(&mut self, create: bool) { self.create = create; }
|
||||
pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
|
||||
pub fn read(&mut self, read: bool) {
|
||||
self.read = read;
|
||||
}
|
||||
pub fn write(&mut self, write: bool) {
|
||||
self.write = write;
|
||||
}
|
||||
pub fn append(&mut self, append: bool) {
|
||||
self.append = append;
|
||||
}
|
||||
pub fn truncate(&mut self, truncate: bool) {
|
||||
self.truncate = truncate;
|
||||
}
|
||||
pub fn create(&mut self, create: bool) {
|
||||
self.create = create;
|
||||
}
|
||||
pub fn create_new(&mut self, create_new: bool) {
|
||||
self.create_new = create_new;
|
||||
}
|
||||
|
||||
fn get_access_mode(&self) -> io::Result<i32> {
|
||||
match (self.read, self.write, self.append) {
|
||||
(true, false, false) => Ok(O_RDONLY),
|
||||
(false, true, false) => Ok(O_WRONLY),
|
||||
(true, true, false) => Ok(O_RDWR),
|
||||
(false, _, true) => Ok(O_WRONLY | O_APPEND),
|
||||
(true, _, true) => Ok(O_RDWR | O_APPEND),
|
||||
(true, false, false) => Ok(O_RDONLY),
|
||||
(false, true, false) => Ok(O_WRONLY),
|
||||
(true, true, false) => Ok(O_RDWR),
|
||||
(false, _, true) => Ok(O_WRONLY | O_APPEND),
|
||||
(true, _, true) => Ok(O_RDWR | O_APPEND),
|
||||
(false, false, false) => {
|
||||
Err(io::Error::new(ErrorKind::InvalidInput, "invalid access mode"))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_creation_mode(&self) -> io::Result<i32> {
|
||||
match (self.write, self.append) {
|
||||
(true, false) => {}
|
||||
(false, false) =>
|
||||
(false, false) => {
|
||||
if self.truncate || self.create || self.create_new {
|
||||
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode"));
|
||||
},
|
||||
(_, true) =>
|
||||
}
|
||||
}
|
||||
(_, true) => {
|
||||
if self.truncate && !self.create_new {
|
||||
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode"));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(match (self.create, self.truncate, self.create_new) {
|
||||
(false, false, false) => 0,
|
||||
(true, false, false) => O_CREAT,
|
||||
(false, true, false) => O_TRUNC,
|
||||
(true, true, false) => O_CREAT | O_TRUNC,
|
||||
(_, _, true) => O_CREAT | O_EXCL,
|
||||
})
|
||||
(false, false, false) => 0,
|
||||
(true, false, false) => O_CREAT,
|
||||
(false, true, false) => O_TRUNC,
|
||||
(true, true, false) => O_CREAT | O_TRUNC,
|
||||
(_, _, true) => O_CREAT | O_EXCL,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +339,7 @@ impl File {
|
|||
|
||||
impl DirBuilder {
|
||||
pub fn new() -> DirBuilder {
|
||||
DirBuilder { }
|
||||
DirBuilder {}
|
||||
}
|
||||
|
||||
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
|
||||
|
|
|
@ -13,34 +13,34 @@
|
|||
//! compiling for wasm. That way it's a compile time error for something that's
|
||||
//! guaranteed to be a runtime error!
|
||||
|
||||
use crate::os::raw::c_char;
|
||||
use crate::intrinsics;
|
||||
use crate::os::raw::c_char;
|
||||
|
||||
pub mod alloc;
|
||||
pub mod args;
|
||||
pub mod condvar;
|
||||
pub mod stdio;
|
||||
pub mod memchr;
|
||||
pub mod io;
|
||||
pub mod mutex;
|
||||
pub mod rwlock;
|
||||
pub mod os;
|
||||
pub mod cmath;
|
||||
pub mod thread;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod fast_thread_local;
|
||||
pub mod fd;
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
pub mod path;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stack_overflow;
|
||||
pub mod time;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
pub mod thread_local;
|
||||
pub mod fast_thread_local;
|
||||
pub mod time;
|
||||
|
||||
pub use crate::sys_common::os_str_bytes as os_str;
|
||||
use crate::io::ErrorKind;
|
||||
pub use crate::sys_common::os_str_bytes as os_str;
|
||||
|
||||
#[allow(unused_extern_crates)]
|
||||
pub extern crate hermit_abi as abi;
|
||||
|
@ -50,8 +50,7 @@ pub fn unsupported<T>() -> crate::io::Result<T> {
|
|||
}
|
||||
|
||||
pub fn unsupported_err() -> crate::io::Error {
|
||||
crate::io::Error::new(crate::io::ErrorKind::Other,
|
||||
"operation not supported on HermitCore yet")
|
||||
crate::io::Error::new(crate::io::ErrorKind::Other, "operation not supported on HermitCore yet")
|
||||
}
|
||||
|
||||
// This enum is used as the storage for a bunch of types which can't actually
|
||||
|
@ -71,9 +70,7 @@ pub unsafe fn strlen(start: *const c_char) -> usize {
|
|||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn floor(x: f64) -> f64 {
|
||||
unsafe {
|
||||
intrinsics::floorf64(x)
|
||||
}
|
||||
unsafe { intrinsics::floorf64(x) }
|
||||
}
|
||||
|
||||
pub unsafe fn abort_internal() -> ! {
|
||||
|
@ -103,8 +100,11 @@ pub fn init() {
|
|||
|
||||
#[cfg(not(test))]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn runtime_entry(argc: i32, argv: *const *const c_char,
|
||||
env: *const *const c_char) -> ! {
|
||||
pub unsafe extern "C" fn runtime_entry(
|
||||
argc: i32,
|
||||
argv: *const *const c_char,
|
||||
env: *const *const c_char,
|
||||
) -> ! {
|
||||
extern "C" {
|
||||
fn main(argc: isize, argv: *const *const c_char) -> i32;
|
||||
}
|
||||
|
@ -139,9 +139,5 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
|||
}
|
||||
|
||||
pub fn cvt(result: i32) -> crate::io::Result<usize> {
|
||||
if result < 0 {
|
||||
Err(crate::io::Error::from_raw_os_error(-result))
|
||||
} else {
|
||||
Ok(result as usize)
|
||||
}
|
||||
if result < 0 { Err(crate::io::Error::from_raw_os_error(-result)) } else { Ok(result as usize) }
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::ptr;
|
||||
use crate::ffi::c_void;
|
||||
use crate::ptr;
|
||||
use crate::sys::hermit::abi;
|
||||
|
||||
pub struct Mutex {
|
||||
inner: *const c_void
|
||||
inner: *const c_void,
|
||||
}
|
||||
|
||||
unsafe impl Send for Mutex {}
|
||||
|
@ -42,7 +42,7 @@ impl Mutex {
|
|||
}
|
||||
|
||||
pub struct ReentrantMutex {
|
||||
inner: *const c_void
|
||||
inner: *const c_void,
|
||||
}
|
||||
|
||||
impl ReentrantMutex {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::fmt;
|
||||
use crate::convert::TryFrom;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
|
||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||
use crate::str;
|
||||
use crate::sys::{unsupported, Void};
|
||||
use crate::time::Duration;
|
||||
|
@ -234,23 +234,19 @@ impl UdpSocket {
|
|||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
|
@ -357,8 +353,7 @@ pub mod netc {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr {
|
||||
}
|
||||
pub struct sockaddr {}
|
||||
|
||||
pub type socklen_t = usize;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::collections::HashMap;
|
||||
use crate::error::Error as StdError;
|
||||
use crate::ffi::{CStr, OsString, OsStr};
|
||||
use crate::ffi::{CStr, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::marker::PhantomData;
|
||||
|
@ -7,12 +8,11 @@ use crate::memchr;
|
|||
use crate::path::{self, PathBuf};
|
||||
use crate::ptr;
|
||||
use crate::str;
|
||||
use crate::sys::{unsupported, Void};
|
||||
use crate::collections::HashMap;
|
||||
use crate::vec;
|
||||
use crate::sync::Mutex;
|
||||
use crate::sys_common::os_str_bytes::*;
|
||||
use crate::sys::hermit::abi;
|
||||
use crate::sys::{unsupported, Void};
|
||||
use crate::sys_common::os_str_bytes::*;
|
||||
use crate::vec;
|
||||
|
||||
pub fn errno() -> i32 {
|
||||
0
|
||||
|
@ -47,7 +47,9 @@ impl<'a> Iterator for SplitPaths<'a> {
|
|||
pub struct JoinPathsError;
|
||||
|
||||
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
|
||||
where I: Iterator<Item=T>, T: AsRef<OsStr>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: AsRef<OsStr>,
|
||||
{
|
||||
Err(JoinPathsError)
|
||||
}
|
||||
|
@ -77,7 +79,7 @@ pub fn init_environment(env: *const *const i8) {
|
|||
let mut guard = ENV.as_ref().unwrap().lock().unwrap();
|
||||
let mut environ = env;
|
||||
while environ != ptr::null() && *environ != ptr::null() {
|
||||
if let Some((key,value)) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
if let Some((key, value)) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
guard.insert(key, value);
|
||||
}
|
||||
environ = environ.offset(1);
|
||||
|
@ -93,10 +95,12 @@ pub fn init_environment(env: *const *const i8) {
|
|||
return None;
|
||||
}
|
||||
let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
|
||||
pos.map(|p| (
|
||||
OsStringExt::from_vec(input[..p].to_vec()),
|
||||
OsStringExt::from_vec(input[p+1..].to_vec()),
|
||||
))
|
||||
pos.map(|p| {
|
||||
(
|
||||
OsStringExt::from_vec(input[..p].to_vec()),
|
||||
OsStringExt::from_vec(input[p + 1..].to_vec()),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,14 +111,18 @@ pub struct Env {
|
|||
|
||||
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() }
|
||||
fn next(&mut self) -> Option<(OsString, OsString)> {
|
||||
self.iter.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a vector of (variable, value) byte-vector pairs for all the
|
||||
/// environment variables of the current process.
|
||||
pub fn env() -> Env {
|
||||
unsafe {
|
||||
unsafe {
|
||||
let guard = ENV.as_ref().unwrap().lock().unwrap();
|
||||
let mut result = Vec::new();
|
||||
|
||||
|
@ -122,18 +130,15 @@ pub fn env() -> Env {
|
|||
result.push((key.clone(), value.clone()));
|
||||
}
|
||||
|
||||
return Env {
|
||||
iter: result.into_iter(),
|
||||
_dont_send_or_sync_me: PhantomData,
|
||||
}
|
||||
return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData };
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
||||
unsafe {
|
||||
match ENV.as_ref().unwrap().lock().unwrap().get_mut(k) {
|
||||
Some(value) => { Ok(Some(value.clone())) },
|
||||
None => { Ok(None) },
|
||||
Some(value) => Ok(Some(value.clone())),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +173,5 @@ pub fn exit(code: i32) -> ! {
|
|||
}
|
||||
|
||||
pub fn getpid() -> u32 {
|
||||
unsafe {
|
||||
abi::getpid()
|
||||
}
|
||||
unsafe { abi::getpid() }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::path::Prefix;
|
||||
use crate::ffi::OsStr;
|
||||
use crate::path::Prefix;
|
||||
|
||||
#[inline]
|
||||
pub fn is_sep_byte(b: u8) -> bool {
|
||||
|
|
|
@ -25,9 +25,6 @@ impl AnonPipe {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe,
|
||||
_v1: &mut Vec<u8>,
|
||||
_p2: AnonPipe,
|
||||
_v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
match p1.0 {}
|
||||
}
|
||||
|
|
|
@ -32,32 +32,28 @@ pub enum Stdio {
|
|||
|
||||
impl Command {
|
||||
pub fn new(_program: &OsStr) -> Command {
|
||||
Command {
|
||||
env: Default::default()
|
||||
}
|
||||
Command { env: Default::default() }
|
||||
}
|
||||
|
||||
pub fn arg(&mut self, _arg: &OsStr) {
|
||||
}
|
||||
pub fn arg(&mut self, _arg: &OsStr) {}
|
||||
|
||||
pub fn env_mut(&mut self) -> &mut CommandEnv {
|
||||
&mut self.env
|
||||
}
|
||||
|
||||
pub fn cwd(&mut self, _dir: &OsStr) {
|
||||
}
|
||||
pub fn cwd(&mut self, _dir: &OsStr) {}
|
||||
|
||||
pub fn stdin(&mut self, _stdin: Stdio) {
|
||||
}
|
||||
pub fn stdin(&mut self, _stdin: Stdio) {}
|
||||
|
||||
pub fn stdout(&mut self, _stdout: Stdio) {
|
||||
}
|
||||
pub fn stdout(&mut self, _stdout: Stdio) {}
|
||||
|
||||
pub fn stderr(&mut self, _stderr: Stdio) {
|
||||
}
|
||||
pub fn stderr(&mut self, _stderr: Stdio) {}
|
||||
|
||||
pub fn spawn(&mut self, _default: Stdio, _needs_stdin: bool)
|
||||
-> io::Result<(Process, StdioPipes)> {
|
||||
pub fn spawn(
|
||||
&mut self,
|
||||
_default: Stdio,
|
||||
_needs_stdin: bool,
|
||||
) -> io::Result<(Process, StdioPipes)> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
@ -106,8 +102,7 @@ impl PartialEq for ExitStatus {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for ExitStatus {
|
||||
}
|
||||
impl Eq for ExitStatus {}
|
||||
|
||||
impl fmt::Debug for ExitStatus {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::mutex::Mutex;
|
||||
|
||||
pub struct RWLock {
|
||||
mutex: Mutex
|
||||
mutex: Mutex,
|
||||
}
|
||||
|
||||
unsafe impl Send for RWLock {}
|
||||
|
@ -9,9 +9,7 @@ unsafe impl Sync for RWLock {}
|
|||
|
||||
impl RWLock {
|
||||
pub const fn new() -> RWLock {
|
||||
RWLock {
|
||||
mutex: Mutex::new()
|
||||
}
|
||||
RWLock { mutex: Mutex::new() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -7,9 +7,7 @@ impl Handler {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init() {
|
||||
}
|
||||
pub unsafe fn init() {}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn cleanup() {
|
||||
}
|
||||
pub unsafe fn cleanup() {}
|
||||
|
|
|
@ -20,7 +20,6 @@ impl Stdin {
|
|||
// .read(data)
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Stdout {
|
||||
|
@ -31,9 +30,7 @@ impl Stdout {
|
|||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe {
|
||||
len = abi::write(1, data.as_ptr() as *const u8, data.len())
|
||||
}
|
||||
unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
|
||||
|
@ -45,9 +42,7 @@ impl Stdout {
|
|||
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe {
|
||||
len = abi::write(1, data.as_ptr() as *const u8, data.len())
|
||||
}
|
||||
unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
|
||||
|
@ -69,9 +64,7 @@ impl Stderr {
|
|||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe {
|
||||
len = abi::write(2, data.as_ptr() as *const u8, data.len())
|
||||
}
|
||||
unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
|
||||
|
@ -83,9 +76,7 @@ impl Stderr {
|
|||
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe {
|
||||
len = abi::write(2, data.as_ptr() as *const u8, data.len())
|
||||
}
|
||||
unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use crate::ffi::CStr;
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::mem;
|
||||
use crate::sys::hermit::abi;
|
||||
use crate::time::Duration;
|
||||
use crate::mem;
|
||||
use crate::fmt;
|
||||
use core::u32;
|
||||
|
||||
use crate::sys_common::thread::*;
|
||||
|
@ -35,7 +35,7 @@ impl fmt::Display for Priority {
|
|||
pub const NORMAL_PRIO: Priority = Priority::from(2);
|
||||
|
||||
pub struct Thread {
|
||||
tid: Tid
|
||||
tid: Tid,
|
||||
}
|
||||
|
||||
unsafe impl Send for Thread {}
|
||||
|
@ -44,14 +44,20 @@ unsafe impl Sync for Thread {}
|
|||
pub const DEFAULT_MIN_STACK_SIZE: usize = 262144;
|
||||
|
||||
impl Thread {
|
||||
pub unsafe fn new_with_coreid(_stack: usize, p: Box<dyn FnOnce()>, core_id: isize)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
pub unsafe fn new_with_coreid(
|
||||
_stack: usize,
|
||||
p: Box<dyn FnOnce()>,
|
||||
core_id: isize,
|
||||
) -> io::Result<Thread> {
|
||||
let p = box p;
|
||||
let mut tid: Tid = u32::MAX;
|
||||
let ret = abi::spawn(&mut tid as *mut Tid, thread_start,
|
||||
&*p as *const _ as *const u8 as usize,
|
||||
Priority::into(NORMAL_PRIO), core_id);
|
||||
let ret = abi::spawn(
|
||||
&mut tid as *mut Tid,
|
||||
thread_start,
|
||||
&*p as *const _ as *const u8 as usize,
|
||||
Priority::into(NORMAL_PRIO),
|
||||
core_id,
|
||||
);
|
||||
|
||||
return if ret == 0 {
|
||||
mem::forget(p); // ownership passed to pthread_create
|
||||
|
@ -60,16 +66,14 @@ impl Thread {
|
|||
Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!"))
|
||||
};
|
||||
|
||||
extern fn thread_start(main: usize) {
|
||||
extern "C" fn thread_start(main: usize) {
|
||||
unsafe {
|
||||
start_thread(main as *mut u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
Thread::new_with_coreid(stack, p, -1 /* = no specific core */)
|
||||
}
|
||||
|
||||
|
@ -99,7 +103,9 @@ impl Thread {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> Tid { self.tid }
|
||||
pub fn id(&self) -> Tid {
|
||||
self.tid
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_id(self) -> Tid {
|
||||
|
@ -111,6 +117,10 @@ impl Thread {
|
|||
|
||||
pub mod guard {
|
||||
pub type Guard = !;
|
||||
pub unsafe fn current() -> Option<Guard> { None }
|
||||
pub unsafe fn init() -> Option<Guard> { None }
|
||||
pub unsafe fn current() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
pub unsafe fn init() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::sys_common::mutex::Mutex;
|
|||
|
||||
pub type Key = usize;
|
||||
|
||||
type Dtor = unsafe extern fn(*mut u8);
|
||||
type Dtor = unsafe extern "C" fn(*mut u8);
|
||||
|
||||
static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
|
@ -41,11 +41,7 @@ pub unsafe fn create(dtor: Option<Dtor>) -> Key {
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn get(key: Key) -> *mut u8 {
|
||||
if let Some(&entry) = locals().get(&key) {
|
||||
entry
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
if let Some(&entry) = locals().get(&key) { entry } else { ptr::null_mut() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -1,34 +1,35 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use crate::time::Duration;
|
||||
use crate::cmp::Ordering;
|
||||
use crate::convert::TryInto;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use crate::sys::hermit::abi;
|
||||
use crate::sys::hermit::abi::{CLOCK_REALTIME, CLOCK_MONOTONIC, NSEC_PER_SEC};
|
||||
use crate::sys::hermit::abi::timespec;
|
||||
use crate::sys::hermit::abi::{CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
|
||||
use crate::time::Duration;
|
||||
use core::hash::{Hash, Hasher};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Timespec {
|
||||
t: timespec
|
||||
t: timespec,
|
||||
}
|
||||
|
||||
impl Timespec {
|
||||
const fn zero() -> Timespec {
|
||||
Timespec {
|
||||
t: timespec { tv_sec: 0, tv_nsec: 0 },
|
||||
}
|
||||
Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
|
||||
}
|
||||
|
||||
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
||||
if self >= other {
|
||||
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
||||
Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
|
||||
(self.t.tv_nsec - other.t.tv_nsec) as u32)
|
||||
Duration::new(
|
||||
(self.t.tv_sec - other.t.tv_sec) as u64,
|
||||
(self.t.tv_nsec - other.t.tv_nsec) as u32,
|
||||
)
|
||||
} else {
|
||||
Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
|
||||
other.t.tv_nsec as u32)
|
||||
Duration::new(
|
||||
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
||||
)
|
||||
})
|
||||
} else {
|
||||
match other.sub_timespec(self) {
|
||||
|
@ -52,12 +53,7 @@ impl Timespec {
|
|||
nsec -= NSEC_PER_SEC as u32;
|
||||
secs = secs.checked_add(1)?;
|
||||
}
|
||||
Some(Timespec {
|
||||
t: timespec {
|
||||
tv_sec: secs,
|
||||
tv_nsec: nsec as _,
|
||||
},
|
||||
})
|
||||
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||
}
|
||||
|
||||
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
|
||||
|
@ -73,12 +69,7 @@ impl Timespec {
|
|||
nsec += NSEC_PER_SEC as i32;
|
||||
secs = secs.checked_sub(1)?;
|
||||
}
|
||||
Some(Timespec {
|
||||
t: timespec {
|
||||
tv_sec: secs,
|
||||
tv_nsec: nsec as _,
|
||||
},
|
||||
})
|
||||
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +96,7 @@ impl Ord for Timespec {
|
|||
}
|
||||
|
||||
impl Hash for Timespec {
|
||||
fn hash<H : Hasher>(&self, state: &mut H) {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.t.tv_sec.hash(state);
|
||||
self.t.tv_nsec.hash(state);
|
||||
}
|
||||
|
@ -150,9 +141,7 @@ pub struct SystemTime {
|
|||
t: Timespec,
|
||||
}
|
||||
|
||||
pub const UNIX_EPOCH: SystemTime = SystemTime {
|
||||
t: Timespec::zero(),
|
||||
};
|
||||
pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
|
||||
|
||||
impl SystemTime {
|
||||
pub fn now() -> SystemTime {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
|
||||
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::io::Write;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
// runtime features
|
||||
mod reloc;
|
||||
pub(super) mod panic;
|
||||
mod reloc;
|
||||
|
||||
// library features
|
||||
pub mod mem;
|
||||
|
@ -38,14 +38,16 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
|
|||
UNINIT => {
|
||||
reloc::relocate_elf_rela();
|
||||
RELOC_STATE.store(DONE, Ordering::Release);
|
||||
},
|
||||
}
|
||||
// We need to wait until the initialization is done.
|
||||
BUSY => while RELOC_STATE.load(Ordering::Acquire) == BUSY {
|
||||
core::arch::x86_64::_mm_pause()
|
||||
},
|
||||
BUSY => {
|
||||
while RELOC_STATE.load(Ordering::Acquire) == BUSY {
|
||||
core::arch::x86_64::_mm_pause()
|
||||
}
|
||||
}
|
||||
// Initialization is done.
|
||||
DONE => {},
|
||||
_ => unreachable!()
|
||||
DONE => {}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,21 +16,13 @@ fn empty_user_slice() -> &'static mut UserRef<[u8]> {
|
|||
|
||||
impl SgxPanicOutput {
|
||||
pub(crate) fn new() -> Option<Self> {
|
||||
if unsafe { DEBUG == 0 } {
|
||||
None
|
||||
} else {
|
||||
Some(SgxPanicOutput(None))
|
||||
}
|
||||
if unsafe { DEBUG == 0 } { None } else { Some(SgxPanicOutput(None)) }
|
||||
}
|
||||
|
||||
fn init(&mut self) -> &mut &'static mut UserRef<[u8]> {
|
||||
self.0.get_or_insert_with(|| unsafe {
|
||||
let ptr = take_debug_panic_buf_ptr();
|
||||
if ptr.is_null() {
|
||||
empty_user_slice()
|
||||
} else {
|
||||
UserRef::from_raw_parts_mut(ptr, 1024)
|
||||
}
|
||||
if ptr.is_null() { empty_user_slice() } else { UserRef::from_raw_parts_mut(ptr, 1024) }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::slice::from_raw_parts;
|
||||
use super::mem;
|
||||
use crate::slice::from_raw_parts;
|
||||
|
||||
const R_X86_64_RELATIVE: u32 = 8;
|
||||
|
||||
|
@ -11,18 +11,20 @@ struct Rela<T> {
|
|||
}
|
||||
|
||||
pub fn relocate_elf_rela() {
|
||||
extern {
|
||||
extern "C" {
|
||||
static RELA: u64;
|
||||
static RELACOUNT: usize;
|
||||
}
|
||||
|
||||
if unsafe { RELACOUNT } == 0 { return } // unsafe ok: link-time constant
|
||||
if unsafe { RELACOUNT } == 0 {
|
||||
return;
|
||||
} // unsafe ok: link-time constant
|
||||
|
||||
let relas = unsafe {
|
||||
from_raw_parts::<Rela<u64>>(mem::rel_ptr(RELA), RELACOUNT) // unsafe ok: link-time constant
|
||||
from_raw_parts::<Rela<u64>>(mem::rel_ptr(RELA), RELACOUNT) // unsafe ok: link-time constant
|
||||
};
|
||||
for rela in relas {
|
||||
if rela.info != (/*0 << 32 |*/ R_X86_64_RELATIVE as u64) {
|
||||
if rela.info != (/*0 << 32 |*/R_X86_64_RELATIVE as u64) {
|
||||
rtabort!("Invalid relocation");
|
||||
}
|
||||
unsafe { *mem::rel_ptr_mut::<*const ()>(rela.offset) = mem::rel_ptr(rela.addend) };
|
||||
|
|
|
@ -6,6 +6,8 @@ use fortanix_sgx_abi::Tcs;
|
|||
/// is a one-to-one correspondence of the ID to the address of the TCS.
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub fn current() -> Tcs {
|
||||
extern "C" { fn get_tcs_addr() -> Tcs; }
|
||||
extern "C" {
|
||||
fn get_tcs_addr() -> Tcs;
|
||||
}
|
||||
unsafe { get_tcs_addr() }
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::ptr;
|
||||
use crate::mem;
|
||||
use crate::cell::Cell;
|
||||
use crate::num::NonZeroUsize;
|
||||
use self::sync_bitset::*;
|
||||
use crate::cell::Cell;
|
||||
use crate::mem;
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ptr;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
#[cfg(target_pointer_width="64")]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const USIZE_BITS: usize = 64;
|
||||
const TLS_KEYS: usize = 128; // Same as POSIX minimum
|
||||
const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
|
||||
|
@ -50,18 +50,18 @@ impl Key {
|
|||
|
||||
#[repr(C)]
|
||||
pub struct Tls {
|
||||
data: [Cell<*mut u8>; TLS_KEYS]
|
||||
data: [Cell<*mut u8>; TLS_KEYS],
|
||||
}
|
||||
|
||||
pub struct ActiveTls<'a> {
|
||||
tls: &'a Tls
|
||||
tls: &'a Tls,
|
||||
}
|
||||
|
||||
impl<'a> Drop for ActiveTls<'a> {
|
||||
fn drop(&mut self) {
|
||||
let value_with_destructor = |key: usize| {
|
||||
let ptr = TLS_DESTRUCTOR[key].load(Ordering::Relaxed);
|
||||
unsafe { mem::transmute::<_,Option<unsafe extern fn(*mut u8)>>(ptr) }
|
||||
unsafe { mem::transmute::<_, Option<unsafe extern "C" fn(*mut u8)>>(ptr) }
|
||||
.map(|dtor| (&self.tls.data[key], dtor))
|
||||
};
|
||||
|
||||
|
@ -99,7 +99,7 @@ impl Tls {
|
|||
&*(get_tls_ptr() as *const Tls)
|
||||
}
|
||||
|
||||
pub fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||
let index = if let Some(index) = TLS_KEY_IN_USE.set() {
|
||||
index
|
||||
} else {
|
||||
|
@ -127,10 +127,10 @@ impl Tls {
|
|||
}
|
||||
|
||||
mod sync_bitset {
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
|
||||
use crate::iter::{Enumerate, Peekable};
|
||||
use crate::slice::Iter;
|
||||
use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
/// A bitset that can be used synchronously.
|
||||
pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
|
||||
|
@ -146,10 +146,7 @@ mod sync_bitset {
|
|||
|
||||
/// Not atomic.
|
||||
pub fn iter(&self) -> SyncBitsetIter<'_> {
|
||||
SyncBitsetIter {
|
||||
iter: self.0.iter().enumerate().peekable(),
|
||||
elem_idx: 0,
|
||||
}
|
||||
SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 }
|
||||
}
|
||||
|
||||
pub fn clear(&self, index: usize) {
|
||||
|
@ -171,7 +168,7 @@ mod sync_bitset {
|
|||
current,
|
||||
current | (1 << trailing_ones),
|
||||
Ordering::AcqRel,
|
||||
Ordering::Relaxed
|
||||
Ordering::Relaxed,
|
||||
) {
|
||||
Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
|
||||
Err(previous) => current = previous,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use crate::ptr::{self, NonNull};
|
||||
use crate::mem;
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::mem;
|
||||
use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut};
|
||||
use crate::ptr::{self, NonNull};
|
||||
use crate::slice;
|
||||
use crate::ops::{Deref, DerefMut, Index, IndexMut, CoerceUnsized};
|
||||
use crate::slice::SliceIndex;
|
||||
|
||||
use fortanix_sgx_abi::*;
|
||||
use super::super::mem::is_user_range;
|
||||
use fortanix_sgx_abi::*;
|
||||
|
||||
/// A type that can be safely read from or written to userspace.
|
||||
///
|
||||
|
@ -109,9 +109,7 @@ pub unsafe trait UserSafe {
|
|||
/// * the pointer is null.
|
||||
/// * the pointed-to range is not in user memory.
|
||||
unsafe fn check_ptr(ptr: *const Self) {
|
||||
let is_aligned = |p| -> bool {
|
||||
0 == (p as usize) & (Self::align_of() - 1)
|
||||
};
|
||||
let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
|
||||
|
||||
assert!(is_aligned(ptr as *const u8));
|
||||
assert!(is_user_range(ptr as _, mem::size_of_val(&*ptr)));
|
||||
|
@ -183,7 +181,10 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T: ?Sized> User<T> where T: UserSafe {
|
||||
impl<T: ?Sized> User<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
// This function returns memory that is practically uninitialized, but is
|
||||
// not considered "unspecified" or "undefined" for purposes of an
|
||||
// optimizing compiler. This is achieved by returning a pointer from
|
||||
|
@ -211,7 +212,7 @@ impl<T: ?Sized> User<T> where T: UserSafe {
|
|||
ptr::copy(
|
||||
val as *const T as *const u8,
|
||||
ret.0.as_ptr() as *mut u8,
|
||||
mem::size_of_val(val)
|
||||
mem::size_of_val(val),
|
||||
);
|
||||
ret
|
||||
}
|
||||
|
@ -244,7 +245,10 @@ impl<T: ?Sized> User<T> where T: UserSafe {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T> User<T> where T: UserSafe {
|
||||
impl<T> User<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
/// Allocate space for `T` in user memory.
|
||||
pub fn uninitialized() -> Self {
|
||||
Self::new_uninit_bytes(mem::size_of::<T>())
|
||||
|
@ -252,7 +256,10 @@ impl<T> User<T> where T: UserSafe {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T> User<[T]> where [T]: UserSafe {
|
||||
impl<T> User<[T]>
|
||||
where
|
||||
[T]: UserSafe,
|
||||
{
|
||||
/// Allocate space for a `[T]` of `n` elements in user memory.
|
||||
pub fn uninitialized(n: usize) -> Self {
|
||||
Self::new_uninit_bytes(n * mem::size_of::<T>())
|
||||
|
@ -278,7 +285,10 @@ impl<T> User<[T]> where [T]: UserSafe {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T: ?Sized> UserRef<T> where T: UserSafe {
|
||||
impl<T: ?Sized> UserRef<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
/// Creates a `&UserRef<[T]>` from a raw pointer.
|
||||
///
|
||||
/// # Safety
|
||||
|
@ -309,7 +319,7 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe {
|
|||
/// * The pointed-to range is not in user memory
|
||||
pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self {
|
||||
T::check_ptr(ptr);
|
||||
&mut*(ptr as *mut Self)
|
||||
&mut *(ptr as *mut Self)
|
||||
}
|
||||
|
||||
/// Copies `val` into user memory.
|
||||
|
@ -319,11 +329,11 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe {
|
|||
/// the source. This can happen for dynamically-sized types such as slices.
|
||||
pub fn copy_from_enclave(&mut self, val: &T) {
|
||||
unsafe {
|
||||
assert_eq!(mem::size_of_val(val), mem::size_of_val( &*self.0.get() ));
|
||||
assert_eq!(mem::size_of_val(val), mem::size_of_val(&*self.0.get()));
|
||||
ptr::copy(
|
||||
val as *const T as *const u8,
|
||||
self.0.get() as *mut T as *mut u8,
|
||||
mem::size_of_val(val)
|
||||
mem::size_of_val(val),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -335,11 +345,11 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe {
|
|||
/// the source. This can happen for dynamically-sized types such as slices.
|
||||
pub fn copy_to_enclave(&self, dest: &mut T) {
|
||||
unsafe {
|
||||
assert_eq!(mem::size_of_val(dest), mem::size_of_val( &*self.0.get() ));
|
||||
assert_eq!(mem::size_of_val(dest), mem::size_of_val(&*self.0.get()));
|
||||
ptr::copy(
|
||||
self.0.get() as *const T as *const u8,
|
||||
dest as *mut T as *mut u8,
|
||||
mem::size_of_val(dest)
|
||||
mem::size_of_val(dest),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -356,7 +366,10 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T> UserRef<T> where T: UserSafe {
|
||||
impl<T> UserRef<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
/// Copies the value from user memory into enclave memory.
|
||||
pub fn to_enclave(&self) -> T {
|
||||
unsafe { ptr::read(self.0.get()) }
|
||||
|
@ -364,7 +377,10 @@ impl<T> UserRef<T> where T: UserSafe {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T> UserRef<[T]> where [T]: UserSafe {
|
||||
impl<T> UserRef<[T]>
|
||||
where
|
||||
[T]: UserSafe,
|
||||
{
|
||||
/// Creates a `&UserRef<[T]>` from a raw thin pointer and a slice length.
|
||||
///
|
||||
/// # Safety
|
||||
|
@ -396,7 +412,7 @@ impl<T> UserRef<[T]> where [T]: UserSafe {
|
|||
/// * The pointed-to range does not fit in the address space
|
||||
/// * The pointed-to range is not in user memory
|
||||
pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self {
|
||||
&mut*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
|
||||
&mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
|
||||
}
|
||||
|
||||
/// Obtain a raw pointer to the first element of this user slice.
|
||||
|
@ -439,20 +455,18 @@ impl<T> UserRef<[T]> where [T]: UserSafe {
|
|||
|
||||
/// Returns an iterator over the slice.
|
||||
pub fn iter(&self) -> Iter<'_, T>
|
||||
where T: UserSafe // FIXME: should be implied by [T]: UserSafe?
|
||||
where
|
||||
T: UserSafe, // FIXME: should be implied by [T]: UserSafe?
|
||||
{
|
||||
unsafe {
|
||||
Iter((&*self.as_raw_ptr()).iter())
|
||||
}
|
||||
unsafe { Iter((&*self.as_raw_ptr()).iter()) }
|
||||
}
|
||||
|
||||
/// Returns an iterator that allows modifying each value.
|
||||
pub fn iter_mut(&mut self) -> IterMut<'_, T>
|
||||
where T: UserSafe // FIXME: should be implied by [T]: UserSafe?
|
||||
where
|
||||
T: UserSafe, // FIXME: should be implied by [T]: UserSafe?
|
||||
{
|
||||
unsafe {
|
||||
IterMut((&mut*self.as_raw_mut_ptr()).iter_mut())
|
||||
}
|
||||
unsafe { IterMut((&mut *self.as_raw_mut_ptr()).iter_mut()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,9 +482,7 @@ impl<'a, T: UserSafe> Iterator for Iter<'a, T> {
|
|||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
self.0.next().map(|e| UserRef::from_ptr(e))
|
||||
}
|
||||
unsafe { self.0.next().map(|e| UserRef::from_ptr(e)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,14 +498,15 @@ impl<'a, T: UserSafe> Iterator for IterMut<'a, T> {
|
|||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
self.0.next().map(|e| UserRef::from_mut_ptr(e))
|
||||
}
|
||||
unsafe { self.0.next().map(|e| UserRef::from_mut_ptr(e)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T: ?Sized> Deref for User<T> where T: UserSafe {
|
||||
impl<T: ?Sized> Deref for User<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
type Target = UserRef<T>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -502,18 +515,24 @@ impl<T: ?Sized> Deref for User<T> where T: UserSafe {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T: ?Sized> DerefMut for User<T> where T: UserSafe {
|
||||
impl<T: ?Sized> DerefMut for User<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { &mut*self.0.as_ptr() }
|
||||
unsafe { &mut *self.0.as_ptr() }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T: ?Sized> Drop for User<T> where T: UserSafe {
|
||||
impl<T: ?Sized> Drop for User<T>
|
||||
where
|
||||
T: UserSafe,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let ptr = (*self.0.as_ptr()).0.get();
|
||||
super::free(ptr as _, mem::size_of_val(&mut*ptr), T::align_of());
|
||||
super::free(ptr as _, mem::size_of_val(&mut *ptr), T::align_of());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -550,7 +569,7 @@ where
|
|||
#[inline]
|
||||
fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
|
||||
unsafe {
|
||||
if let Some(slice) = index.get_mut(&mut*self.as_raw_mut_ptr()) {
|
||||
if let Some(slice) = index.get_mut(&mut *self.as_raw_mut_ptr()) {
|
||||
UserRef::from_mut_ptr(slice)
|
||||
} else {
|
||||
rtabort!("index out of range for user slice");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::cmp;
|
||||
use crate::io::{Error as IoError, Result as IoResult, IoSlice, IoSliceMut};
|
||||
use crate::io::{Error as IoError, IoSlice, IoSliceMut, Result as IoResult};
|
||||
use crate::time::Duration;
|
||||
|
||||
pub(crate) mod alloc;
|
||||
|
@ -26,7 +26,7 @@ pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
|
|||
userbuf[index..end].copy_to_enclave(&mut buf[..buflen]);
|
||||
index += buf.len();
|
||||
} else {
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(userbuf.len())
|
||||
|
@ -60,7 +60,7 @@ pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> IoResult<usize> {
|
|||
userbuf[index..end].copy_from_enclave(&buf[..buflen]);
|
||||
index += buf.len();
|
||||
} else {
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
|
||||
|
@ -90,11 +90,8 @@ pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> {
|
|||
unsafe {
|
||||
let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
|
||||
let mut local = alloc::User::<ByteBuffer>::uninitialized();
|
||||
let fd = raw::bind_stream(
|
||||
addr_user.as_ptr(),
|
||||
addr_user.len(),
|
||||
local.as_raw_mut_ptr()
|
||||
).from_sgx_result()?;
|
||||
let fd = raw::bind_stream(addr_user.as_ptr(), addr_user.len(), local.as_raw_mut_ptr())
|
||||
.from_sgx_result()?;
|
||||
let local = string_from_bytebuffer(&local, "bind_stream", "local_addr");
|
||||
Ok((fd, local))
|
||||
}
|
||||
|
@ -106,13 +103,10 @@ pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> {
|
|||
unsafe {
|
||||
let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized();
|
||||
let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
|
||||
// without forcing coercion?
|
||||
// without forcing coercion?
|
||||
let (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
|
||||
let fd = raw::accept_stream(
|
||||
fd,
|
||||
local.as_raw_mut_ptr(),
|
||||
peer.as_raw_mut_ptr()
|
||||
).from_sgx_result()?;
|
||||
let fd = raw::accept_stream(fd, local.as_raw_mut_ptr(), peer.as_raw_mut_ptr())
|
||||
.from_sgx_result()?;
|
||||
let local = string_from_bytebuffer(&local, "accept_stream", "local_addr");
|
||||
let peer = string_from_bytebuffer(&peer, "accept_stream", "peer_addr");
|
||||
Ok((fd, local, peer))
|
||||
|
@ -126,14 +120,15 @@ pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> {
|
|||
let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
|
||||
let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized();
|
||||
let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
|
||||
// without forcing coercion?
|
||||
// without forcing coercion?
|
||||
let (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
|
||||
let fd = raw::connect_stream(
|
||||
addr_user.as_ptr(),
|
||||
addr_user.len(),
|
||||
local.as_raw_mut_ptr(),
|
||||
peer.as_raw_mut_ptr()
|
||||
).from_sgx_result()?;
|
||||
peer.as_raw_mut_ptr(),
|
||||
)
|
||||
.from_sgx_result()?;
|
||||
let local = string_from_bytebuffer(&local, "connect_stream", "local_addr");
|
||||
let peer = string_from_bytebuffer(&peer, "connect_stream", "peer_addr");
|
||||
Ok((fd, local, peer))
|
||||
|
@ -183,25 +178,25 @@ pub use self::raw::free;
|
|||
|
||||
fn check_os_error(err: Result) -> i32 {
|
||||
// FIXME: not sure how to make sure all variants of Error are covered
|
||||
if err == Error::NotFound as _ ||
|
||||
err == Error::PermissionDenied as _ ||
|
||||
err == Error::ConnectionRefused as _ ||
|
||||
err == Error::ConnectionReset as _ ||
|
||||
err == Error::ConnectionAborted as _ ||
|
||||
err == Error::NotConnected as _ ||
|
||||
err == Error::AddrInUse as _ ||
|
||||
err == Error::AddrNotAvailable as _ ||
|
||||
err == Error::BrokenPipe as _ ||
|
||||
err == Error::AlreadyExists as _ ||
|
||||
err == Error::WouldBlock as _ ||
|
||||
err == Error::InvalidInput as _ ||
|
||||
err == Error::InvalidData as _ ||
|
||||
err == Error::TimedOut as _ ||
|
||||
err == Error::WriteZero as _ ||
|
||||
err == Error::Interrupted as _ ||
|
||||
err == Error::Other as _ ||
|
||||
err == Error::UnexpectedEof as _ ||
|
||||
((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
|
||||
if err == Error::NotFound as _
|
||||
|| err == Error::PermissionDenied as _
|
||||
|| err == Error::ConnectionRefused as _
|
||||
|| err == Error::ConnectionReset as _
|
||||
|| err == Error::ConnectionAborted as _
|
||||
|| err == Error::NotConnected as _
|
||||
|| err == Error::AddrInUse as _
|
||||
|| err == Error::AddrNotAvailable as _
|
||||
|| err == Error::BrokenPipe as _
|
||||
|| err == Error::AlreadyExists as _
|
||||
|| err == Error::WouldBlock as _
|
||||
|| err == Error::InvalidInput as _
|
||||
|| err == Error::InvalidData as _
|
||||
|| err == Error::TimedOut as _
|
||||
|| err == Error::WriteZero as _
|
||||
|| err == Error::Interrupted as _
|
||||
|| err == Error::Other as _
|
||||
|| err == Error::UnexpectedEof as _
|
||||
|| ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
|
||||
{
|
||||
err
|
||||
} else {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub use fortanix_sgx_abi::*;
|
||||
|
||||
use crate::ptr::NonNull;
|
||||
use crate::num::NonZeroU64;
|
||||
use crate::ptr::NonNull;
|
||||
|
||||
#[repr(C)]
|
||||
struct UsercallReturn(u64, u64);
|
||||
|
@ -25,9 +25,14 @@ extern "C" {
|
|||
/// Panics if `nr` is `0`.
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
#[inline]
|
||||
pub unsafe fn do_usercall(nr: NonZeroU64, p1: u64, p2: u64, p3: u64, p4: u64, abort: bool)
|
||||
-> (u64, u64)
|
||||
{
|
||||
pub unsafe fn do_usercall(
|
||||
nr: NonZeroU64,
|
||||
p1: u64,
|
||||
p2: u64,
|
||||
p3: u64,
|
||||
p4: u64,
|
||||
abort: bool,
|
||||
) -> (u64, u64) {
|
||||
let UsercallReturn(a, b) = usercall(nr, p1, p2, abort as _, p3, p4);
|
||||
(a, b)
|
||||
}
|
||||
|
@ -109,11 +114,7 @@ define_ra!(<T> *mut T);
|
|||
|
||||
impl RegisterArgument for bool {
|
||||
fn from_register(a: Register) -> bool {
|
||||
if a != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
if a != 0 { true } else { false }
|
||||
}
|
||||
fn into_register(self) -> Register {
|
||||
self as _
|
||||
|
@ -152,16 +153,17 @@ impl<T: RegisterArgument> ReturnValue for T {
|
|||
|
||||
impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
|
||||
fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self {
|
||||
(
|
||||
T::from_register(regs.0),
|
||||
U::from_register(regs.1)
|
||||
)
|
||||
(T::from_register(regs.0), U::from_register(regs.1))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! return_type_is_abort {
|
||||
(!) => { true };
|
||||
($r:ty) => { false };
|
||||
(!) => {
|
||||
true
|
||||
};
|
||||
($r:ty) => {
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
// In this macro: using `$r:tt` because `$r:ty` doesn't match ! in `return_type_is_abort`
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use super::abi::usercalls::{alloc, raw::ByteBuffer};
|
||||
use crate::ffi::OsString;
|
||||
use crate::slice;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::sys::os_str::Buf;
|
||||
use crate::sys_common::FromInner;
|
||||
use crate::slice;
|
||||
|
||||
#[cfg_attr(test, linkage = "available_externally")]
|
||||
#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
|
||||
|
@ -14,8 +14,9 @@ type ArgsStore = Vec<OsString>;
|
|||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||
if argc != 0 {
|
||||
let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
|
||||
let args = args.iter()
|
||||
.map( |a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }) )
|
||||
let args = args
|
||||
.iter()
|
||||
.map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))
|
||||
.collect::<ArgsStore>();
|
||||
ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed);
|
||||
}
|
||||
|
@ -30,11 +31,7 @@ pub unsafe fn cleanup() {
|
|||
|
||||
pub fn args() -> Args {
|
||||
let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
|
||||
if let Some(args) = args {
|
||||
Args(args.iter())
|
||||
} else {
|
||||
Args([].iter())
|
||||
}
|
||||
if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
|
||||
}
|
||||
|
||||
pub struct Args(slice::Iter<'static, OsString>);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![cfg(not(test))]
|
||||
|
||||
// These symbols are all defined in `compiler-builtins`
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn acos(n: f64) -> f64;
|
||||
pub fn acosf(n: f32) -> f32;
|
||||
pub fn asin(n: f64) -> f64;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details.
|
||||
#![unstable(feature = "sgx_platform", issue = "56975")]
|
||||
|
||||
pub use crate::sys::abi::usercalls::raw::Fd as RawFd;
|
||||
use crate::net;
|
||||
pub use crate::sys::abi::usercalls::raw::Fd as RawFd;
|
||||
use crate::sys::{self, AsInner, FromInner, IntoInner, TryIntoInner};
|
||||
|
||||
/// A trait to extract the raw SGX file descriptor from an underlying
|
||||
|
@ -60,11 +60,15 @@ pub trait TryIntoRawFd: Sized {
|
|||
}
|
||||
|
||||
impl AsRawFd for net::TcpStream {
|
||||
fn as_raw_fd(&self) -> RawFd { *self.as_inner().as_inner().as_inner().as_inner() }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
*self.as_inner().as_inner().as_inner().as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for net::TcpListener {
|
||||
fn as_raw_fd(&self) -> RawFd { *self.as_inner().as_inner().as_inner().as_inner() }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
*self.as_inner().as_inner().as_inner().as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRawFd for net::TcpStream {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#![unstable(feature = "sgx_platform", issue = "56975")]
|
||||
|
||||
pub mod arch;
|
||||
pub mod io;
|
||||
pub mod ffi;
|
||||
pub mod io;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use fortanix_sgx_abi::Fd;
|
||||
|
||||
use super::abi::usercalls;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::mem;
|
||||
use crate::sys::{AsInner, FromInner, IntoInner};
|
||||
use super::abi::usercalls;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FileDesc {
|
||||
|
@ -15,7 +15,9 @@ impl FileDesc {
|
|||
FileDesc { fd: fd }
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> Fd { self.fd }
|
||||
pub fn raw(&self) -> Fd {
|
||||
self.fd
|
||||
}
|
||||
|
||||
/// Extracts the actual filedescriptor without closing it.
|
||||
pub fn into_raw(self) -> Fd {
|
||||
|
@ -46,7 +48,9 @@ impl FileDesc {
|
|||
}
|
||||
|
||||
impl AsInner<Fd> for FileDesc {
|
||||
fn as_inner(&self) -> &Fd { &self.fd }
|
||||
fn as_inner(&self) -> &Fd {
|
||||
&self.fd
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<Fd> for FileDesc {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, SeekFrom, IoSlice, IoSliceMut};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
|
@ -15,14 +15,14 @@ pub struct ReadDir(Void);
|
|||
pub struct DirEntry(Void);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OpenOptions { }
|
||||
pub struct OpenOptions {}
|
||||
|
||||
pub struct FilePermissions(Void);
|
||||
|
||||
pub struct FileType(Void);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DirBuilder { }
|
||||
pub struct DirBuilder {}
|
||||
|
||||
impl FileAttr {
|
||||
pub fn size(&self) -> u64 {
|
||||
|
@ -78,8 +78,7 @@ impl PartialEq for FilePermissions {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for FilePermissions {
|
||||
}
|
||||
impl Eq for FilePermissions {}
|
||||
|
||||
impl fmt::Debug for FilePermissions {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
@ -115,8 +114,7 @@ impl PartialEq for FileType {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for FileType {
|
||||
}
|
||||
impl Eq for FileType {}
|
||||
|
||||
impl Hash for FileType {
|
||||
fn hash<H: Hasher>(&self, _h: &mut H) {
|
||||
|
@ -164,15 +162,15 @@ impl DirEntry {
|
|||
|
||||
impl OpenOptions {
|
||||
pub fn new() -> OpenOptions {
|
||||
OpenOptions { }
|
||||
OpenOptions {}
|
||||
}
|
||||
|
||||
pub fn read(&mut self, _read: bool) { }
|
||||
pub fn write(&mut self, _write: bool) { }
|
||||
pub fn append(&mut self, _append: bool) { }
|
||||
pub fn truncate(&mut self, _truncate: bool) { }
|
||||
pub fn create(&mut self, _create: bool) { }
|
||||
pub fn create_new(&mut self, _create_new: bool) { }
|
||||
pub fn read(&mut self, _read: bool) {}
|
||||
pub fn write(&mut self, _write: bool) {}
|
||||
pub fn append(&mut self, _append: bool) {}
|
||||
pub fn truncate(&mut self, _truncate: bool) {}
|
||||
pub fn create(&mut self, _create: bool) {}
|
||||
pub fn create_new(&mut self, _create_new: bool) {}
|
||||
}
|
||||
|
||||
impl File {
|
||||
|
@ -235,7 +233,7 @@ impl File {
|
|||
|
||||
impl DirBuilder {
|
||||
pub fn new() -> DirBuilder {
|
||||
DirBuilder { }
|
||||
DirBuilder {}
|
||||
}
|
||||
|
||||
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
|
||||
use crate::time::Duration;
|
||||
use crate::sys::{unsupported, Void, sgx_ineffective, AsInner, FromInner, IntoInner, TryIntoInner};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::convert::TryFrom;
|
||||
use crate::error;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
|
||||
use crate::sync::Arc;
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys::{sgx_ineffective, unsupported, AsInner, FromInner, IntoInner, TryIntoInner, Void};
|
||||
use crate::time::Duration;
|
||||
|
||||
use super::abi::usercalls;
|
||||
|
||||
|
@ -25,13 +25,15 @@ impl Socket {
|
|||
}
|
||||
|
||||
impl AsInner<FileDesc> for Socket {
|
||||
fn as_inner(&self) -> &FileDesc { &self.inner }
|
||||
fn as_inner(&self) -> &FileDesc {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl TryIntoInner<FileDesc> for Socket {
|
||||
fn try_into_inner(self) -> Result<FileDesc, Socket> {
|
||||
let Socket { inner, local_addr } = self;
|
||||
Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr } )
|
||||
Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +61,7 @@ impl fmt::Debug for TcpStream {
|
|||
res.field("peer", peer);
|
||||
}
|
||||
|
||||
res.field("fd", &self.inner.inner.as_inner())
|
||||
.finish()
|
||||
res.field("fd", &self.inner.inner.as_inner()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,10 +70,12 @@ fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
|
|||
Ok(saddr) => Ok(saddr.to_string()),
|
||||
// need to downcast twice because io::Error::into_inner doesn't return the original
|
||||
// value if the conversion fails
|
||||
Err(e) => if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
|
||||
Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
|
||||
} else {
|
||||
Err(e)
|
||||
Err(e) => {
|
||||
if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
|
||||
Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,8 +97,10 @@ impl TcpStream {
|
|||
|
||||
pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
|
||||
if dur == Duration::default() {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
Self::connect(Ok(addr)) // FIXME: ignoring timeout
|
||||
}
|
||||
|
@ -103,20 +108,24 @@ impl TcpStream {
|
|||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
match dur {
|
||||
Some(dur) if dur == Duration::default() => {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
_ => sgx_ineffective(())
|
||||
_ => sgx_ineffective(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
match dur {
|
||||
Some(dur) if dur == Duration::default() => {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
_ => sgx_ineffective(())
|
||||
_ => sgx_ineffective(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,7 +199,9 @@ impl TcpStream {
|
|||
}
|
||||
|
||||
impl AsInner<Socket> for TcpStream {
|
||||
fn as_inner(&self) -> &Socket { &self.inner }
|
||||
fn as_inner(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
// `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly
|
||||
|
@ -220,8 +231,7 @@ impl fmt::Debug for TcpListener {
|
|||
res.field("addr", addr);
|
||||
}
|
||||
|
||||
res.field("fd", &self.inner.inner.as_inner())
|
||||
.finish()
|
||||
res.field("fd", &self.inner.inner.as_inner()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,7 +283,9 @@ impl TcpListener {
|
|||
}
|
||||
|
||||
impl AsInner<Socket> for TcpListener {
|
||||
fn as_inner(&self) -> &Socket { &self.inner }
|
||||
fn as_inner(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<Socket> for TcpListener {
|
||||
|
@ -367,23 +379,19 @@ impl UdpSocket {
|
|||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
|
@ -428,7 +436,7 @@ impl fmt::Debug for UdpSocket {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct NonIpSockAddr {
|
||||
host: String
|
||||
host: String,
|
||||
}
|
||||
|
||||
impl error::Error for NonIpSockAddr {
|
||||
|
@ -511,8 +519,7 @@ pub mod netc {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr {
|
||||
}
|
||||
pub struct sockaddr {}
|
||||
|
||||
pub type socklen_t = usize;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
|
||||
|
||||
use crate::collections::HashMap;
|
||||
use crate::error::Error as StdError;
|
||||
use crate::ffi::{OsString, OsStr};
|
||||
use crate::ffi::{OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::path::{self, PathBuf};
|
||||
use crate::str;
|
||||
use crate::sys::{unsupported, Void, sgx_ineffective, decode_error_kind};
|
||||
use crate::collections::HashMap;
|
||||
use crate::vec;
|
||||
use crate::sync::Mutex;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::sync::Mutex;
|
||||
use crate::sync::Once;
|
||||
use crate::sys::{decode_error_kind, sgx_ineffective, unsupported, Void};
|
||||
use crate::vec;
|
||||
|
||||
pub fn errno() -> i32 {
|
||||
RESULT_SUCCESS
|
||||
|
@ -52,7 +52,9 @@ impl<'a> Iterator for SplitPaths<'a> {
|
|||
pub struct JoinPathsError;
|
||||
|
||||
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
|
||||
where I: Iterator<Item=T>, T: AsRef<OsStr>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: AsRef<OsStr>,
|
||||
{
|
||||
Err(JoinPathsError)
|
||||
}
|
||||
|
@ -89,26 +91,21 @@ fn create_env_store() -> &'static EnvStore {
|
|||
ENV_INIT.call_once(|| {
|
||||
ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed)
|
||||
});
|
||||
unsafe {
|
||||
&*(ENV.load(Ordering::Relaxed) as *const EnvStore)
|
||||
}
|
||||
unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) }
|
||||
}
|
||||
|
||||
pub type Env = vec::IntoIter<(OsString, OsString)>;
|
||||
|
||||
pub fn env() -> Env {
|
||||
let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
|
||||
map.iter().map(|(k, v)| (k.clone(), v.clone()) ).collect()
|
||||
map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
|
||||
};
|
||||
|
||||
get_env_store()
|
||||
.map(|env| clone_to_vec(&env.lock().unwrap()) )
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default().into_iter()
|
||||
}
|
||||
|
||||
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
||||
Ok(get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned() ))
|
||||
Ok(get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned()))
|
||||
}
|
||||
|
||||
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::path::Prefix;
|
||||
use crate::ffi::OsStr;
|
||||
use crate::path::Prefix;
|
||||
|
||||
#[inline]
|
||||
pub fn is_sep_byte(b: u8) -> bool {
|
||||
|
|
|
@ -32,32 +32,28 @@ pub enum Stdio {
|
|||
|
||||
impl Command {
|
||||
pub fn new(_program: &OsStr) -> Command {
|
||||
Command {
|
||||
env: Default::default()
|
||||
}
|
||||
Command { env: Default::default() }
|
||||
}
|
||||
|
||||
pub fn arg(&mut self, _arg: &OsStr) {
|
||||
}
|
||||
pub fn arg(&mut self, _arg: &OsStr) {}
|
||||
|
||||
pub fn env_mut(&mut self) -> &mut CommandEnv {
|
||||
&mut self.env
|
||||
}
|
||||
|
||||
pub fn cwd(&mut self, _dir: &OsStr) {
|
||||
}
|
||||
pub fn cwd(&mut self, _dir: &OsStr) {}
|
||||
|
||||
pub fn stdin(&mut self, _stdin: Stdio) {
|
||||
}
|
||||
pub fn stdin(&mut self, _stdin: Stdio) {}
|
||||
|
||||
pub fn stdout(&mut self, _stdout: Stdio) {
|
||||
}
|
||||
pub fn stdout(&mut self, _stdout: Stdio) {}
|
||||
|
||||
pub fn stderr(&mut self, _stderr: Stdio) {
|
||||
}
|
||||
pub fn stderr(&mut self, _stderr: Stdio) {}
|
||||
|
||||
pub fn spawn(&mut self, _default: Stdio, _needs_stdin: bool)
|
||||
-> io::Result<(Process, StdioPipes)> {
|
||||
pub fn spawn(
|
||||
&mut self,
|
||||
_default: Stdio,
|
||||
_needs_stdin: bool,
|
||||
) -> io::Result<(Process, StdioPipes)> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
@ -106,8 +102,7 @@ impl PartialEq for ExitStatus {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for ExitStatus {
|
||||
}
|
||||
impl Eq for ExitStatus {}
|
||||
|
||||
impl fmt::Debug for ExitStatus {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
|
@ -7,8 +7,6 @@ impl Handler {
|
|||
}
|
||||
|
||||
#[cfg_attr(test, allow(dead_code))]
|
||||
pub unsafe fn init() {
|
||||
}
|
||||
pub unsafe fn init() {}
|
||||
|
||||
pub unsafe fn cleanup() {
|
||||
}
|
||||
pub unsafe fn cleanup() {}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use fortanix_sgx_abi as abi;
|
||||
|
||||
use crate::io;
|
||||
use crate::sys::fd::FileDesc;
|
||||
#[cfg(not(test))]
|
||||
use crate::slice;
|
||||
#[cfg(not(test))]
|
||||
use crate::str;
|
||||
use crate::sys::fd::FileDesc;
|
||||
|
||||
pub struct Stdin(());
|
||||
pub struct Stdout(());
|
||||
|
@ -19,7 +19,9 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
|
|||
}
|
||||
|
||||
impl Stdin {
|
||||
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
|
||||
pub fn new() -> io::Result<Stdin> {
|
||||
Ok(Stdin(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for Stdin {
|
||||
|
@ -29,7 +31,9 @@ impl io::Read for Stdin {
|
|||
}
|
||||
|
||||
impl Stdout {
|
||||
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
|
||||
pub fn new() -> io::Result<Stdout> {
|
||||
Ok(Stdout(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stdout {
|
||||
|
@ -43,7 +47,9 @@ impl io::Write for Stdout {
|
|||
}
|
||||
|
||||
impl Stderr {
|
||||
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
|
||||
pub fn new() -> io::Result<Stderr> {
|
||||
Ok(Stderr(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stderr {
|
||||
|
|
|
@ -10,8 +10,8 @@ pub struct Thread(task_queue::JoinHandle);
|
|||
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
||||
|
||||
mod task_queue {
|
||||
use crate::sync::{Mutex, MutexGuard, Once};
|
||||
use crate::sync::mpsc;
|
||||
use crate::sync::{Mutex, MutexGuard, Once};
|
||||
|
||||
pub type JoinHandle = mpsc::Receiver<()>;
|
||||
|
||||
|
@ -41,7 +41,7 @@ mod task_queue {
|
|||
|
||||
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
|
||||
unsafe {
|
||||
TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()) );
|
||||
TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()));
|
||||
TASK_QUEUE.as_ref().unwrap().lock().unwrap()
|
||||
}
|
||||
}
|
||||
|
@ -49,9 +49,7 @@ mod task_queue {
|
|||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
let mut queue_lock = task_queue::lock();
|
||||
usercalls::launch_thread()?;
|
||||
let (task, handle) = task_queue::Task::new(p);
|
||||
|
@ -86,6 +84,10 @@ impl Thread {
|
|||
|
||||
pub mod guard {
|
||||
pub type Guard = !;
|
||||
pub unsafe fn current() -> Option<Guard> { None }
|
||||
pub unsafe fn init() -> Option<Guard> { None }
|
||||
pub unsafe fn current() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
pub unsafe fn init() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use super::abi::tls::{Tls, Key as AbiKey};
|
||||
use super::abi::tls::{Key as AbiKey, Tls};
|
||||
|
||||
pub type Key = usize;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||
Tls::create(dtor).as_usize()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::time::Duration;
|
||||
use super::abi::usercalls;
|
||||
use crate::time::Duration;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub struct Instant(Duration);
|
||||
|
@ -40,8 +40,7 @@ impl SystemTime {
|
|||
SystemTime(usercalls::insecure_time())
|
||||
}
|
||||
|
||||
pub fn sub_time(&self, other: &SystemTime)
|
||||
-> Result<Duration, Duration> {
|
||||
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ptr;
|
||||
use crate::sys_common::alloc::{MIN_ALIGN, realloc_fallback};
|
||||
use crate::alloc::{GlobalAlloc, Layout, System};
|
||||
use crate::ptr;
|
||||
use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
|
||||
|
||||
#[stable(feature = "alloc_system_type", since = "1.28.0")]
|
||||
unsafe impl GlobalAlloc for System {
|
||||
|
@ -16,7 +16,7 @@ unsafe impl GlobalAlloc for System {
|
|||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if layout.align() > (1 << 31) {
|
||||
return ptr::null_mut()
|
||||
return ptr::null_mut();
|
||||
}
|
||||
}
|
||||
aligned_malloc(&layout)
|
||||
|
@ -52,9 +52,7 @@ unsafe impl GlobalAlloc for System {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android",
|
||||
target_os = "redox",
|
||||
target_os = "solaris"))]
|
||||
#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
|
||||
#[inline]
|
||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||
// On android we currently target API level 9 which unfortunately
|
||||
|
@ -77,9 +75,7 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
|||
libc::memalign(layout.align(), layout.size()) as *mut u8
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android",
|
||||
target_os = "redox",
|
||||
target_os = "solaris")))]
|
||||
#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
|
||||
#[inline]
|
||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||
let mut out = ptr::null_mut();
|
||||
|
@ -87,9 +83,5 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
|||
// Since these are all powers of 2, we can just use max.
|
||||
let align = layout.align().max(crate::mem::size_of::<usize>());
|
||||
let ret = libc::posix_memalign(&mut out, align, layout.size());
|
||||
if ret != 0 {
|
||||
ptr::null_mut()
|
||||
} else {
|
||||
out as *mut u8
|
||||
}
|
||||
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
use libc::{c_int, c_void, sighandler_t, size_t, ssize_t};
|
||||
use libc::{ftruncate, pread, pwrite};
|
||||
|
||||
use crate::io;
|
||||
use super::{cvt, cvt_r};
|
||||
use crate::io;
|
||||
|
||||
// The `log2` and `log2f` functions apparently appeared in android-18, or at
|
||||
// least you can see they're not present in the android-17 header [1] and they
|
||||
|
@ -96,8 +96,7 @@ pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
|||
Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()),
|
||||
None => {
|
||||
if size > i32::max_value() as u64 {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot truncate >2GB"))
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot truncate >2GB"))
|
||||
} else {
|
||||
cvt_r(|| ftruncate(fd, size as i32)).map(|_| ())
|
||||
}
|
||||
|
@ -108,53 +107,61 @@ pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
|||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
||||
unsafe {
|
||||
cvt_r(|| ftruncate(fd, size as i64)).map(|_| ())
|
||||
}
|
||||
unsafe { cvt_r(|| ftruncate(fd, size as i64)).map(|_| ()) }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
pub unsafe fn cvt_pread64(
|
||||
fd: c_int,
|
||||
buf: *mut c_void,
|
||||
count: size_t,
|
||||
offset: i64,
|
||||
) -> io::Result<ssize_t> {
|
||||
use crate::convert::TryInto;
|
||||
weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
|
||||
pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||
if let Ok(o) = offset.try_into() {
|
||||
cvt(pread(fd, buf, count, o))
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot pread >2GB"))
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot pread >2GB"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
pub unsafe fn cvt_pwrite64(
|
||||
fd: c_int,
|
||||
buf: *const c_void,
|
||||
count: size_t,
|
||||
offset: i64,
|
||||
) -> io::Result<ssize_t> {
|
||||
use crate::convert::TryInto;
|
||||
weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
|
||||
pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||
if let Ok(o) = offset.try_into() {
|
||||
cvt(pwrite(fd, buf, count, o))
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot pwrite >2GB"))
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot pwrite >2GB"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
pub unsafe fn cvt_pread64(
|
||||
fd: c_int,
|
||||
buf: *mut c_void,
|
||||
count: size_t,
|
||||
offset: i64,
|
||||
) -> io::Result<ssize_t> {
|
||||
cvt(pread(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
pub unsafe fn cvt_pwrite64(
|
||||
fd: c_int,
|
||||
buf: *const c_void,
|
||||
count: size_t,
|
||||
offset: i64,
|
||||
) -> io::Result<ssize_t> {
|
||||
cvt(pwrite(fd, buf, count, offset))
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![cfg(not(test))]
|
||||
|
||||
use libc::{c_float, c_double};
|
||||
use libc::{c_double, c_float};
|
||||
|
||||
#[link_name = "m"]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn acos(n: c_double) -> c_double;
|
||||
pub fn acosf(n: c_float) -> c_float;
|
||||
pub fn asin(n: c_double) -> c_double;
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::fs::{self, Permissions, OpenOptions};
|
||||
use crate::fs::{self, OpenOptions, Permissions};
|
||||
use crate::io;
|
||||
use crate::path::Path;
|
||||
use crate::sys;
|
||||
use crate::sys_common::{FromInner, AsInner, AsInnerMut};
|
||||
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
|
||||
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
|
||||
|
||||
/// Unix-specific extensions to [`File`].
|
||||
///
|
||||
|
@ -112,8 +112,7 @@ pub trait FileExt {
|
|||
}
|
||||
}
|
||||
if !buf.is_empty() {
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
||||
"failed to fill whole buffer"))
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -195,8 +194,12 @@ pub trait FileExt {
|
|||
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
|
||||
while !buf.is_empty() {
|
||||
match self.write_at(buf, offset) {
|
||||
Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
|
||||
"failed to write whole buffer")),
|
||||
Ok(0) => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::WriteZero,
|
||||
"failed to write whole buffer",
|
||||
));
|
||||
}
|
||||
Ok(n) => {
|
||||
buf = &buf[n..];
|
||||
offset += n as u64
|
||||
|
@ -356,11 +359,13 @@ pub trait OpenOptionsExt {
|
|||
#[stable(feature = "fs_ext", since = "1.1.0")]
|
||||
impl OpenOptionsExt for OpenOptions {
|
||||
fn mode(&mut self, mode: u32) -> &mut OpenOptions {
|
||||
self.as_inner_mut().mode(mode); self
|
||||
self.as_inner_mut().mode(mode);
|
||||
self
|
||||
}
|
||||
|
||||
fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
|
||||
self.as_inner_mut().custom_flags(flags); self
|
||||
self.as_inner_mut().custom_flags(flags);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -657,22 +662,54 @@ pub trait MetadataExt {
|
|||
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
impl MetadataExt for fs::Metadata {
|
||||
fn dev(&self) -> u64 { self.st_dev() }
|
||||
fn ino(&self) -> u64 { self.st_ino() }
|
||||
fn mode(&self) -> u32 { self.st_mode() }
|
||||
fn nlink(&self) -> u64 { self.st_nlink() }
|
||||
fn uid(&self) -> u32 { self.st_uid() }
|
||||
fn gid(&self) -> u32 { self.st_gid() }
|
||||
fn rdev(&self) -> u64 { self.st_rdev() }
|
||||
fn size(&self) -> u64 { self.st_size() }
|
||||
fn atime(&self) -> i64 { self.st_atime() }
|
||||
fn atime_nsec(&self) -> i64 { self.st_atime_nsec() }
|
||||
fn mtime(&self) -> i64 { self.st_mtime() }
|
||||
fn mtime_nsec(&self) -> i64 { self.st_mtime_nsec() }
|
||||
fn ctime(&self) -> i64 { self.st_ctime() }
|
||||
fn ctime_nsec(&self) -> i64 { self.st_ctime_nsec() }
|
||||
fn blksize(&self) -> u64 { self.st_blksize() }
|
||||
fn blocks(&self) -> u64 { self.st_blocks() }
|
||||
fn dev(&self) -> u64 {
|
||||
self.st_dev()
|
||||
}
|
||||
fn ino(&self) -> u64 {
|
||||
self.st_ino()
|
||||
}
|
||||
fn mode(&self) -> u32 {
|
||||
self.st_mode()
|
||||
}
|
||||
fn nlink(&self) -> u64 {
|
||||
self.st_nlink()
|
||||
}
|
||||
fn uid(&self) -> u32 {
|
||||
self.st_uid()
|
||||
}
|
||||
fn gid(&self) -> u32 {
|
||||
self.st_gid()
|
||||
}
|
||||
fn rdev(&self) -> u64 {
|
||||
self.st_rdev()
|
||||
}
|
||||
fn size(&self) -> u64 {
|
||||
self.st_size()
|
||||
}
|
||||
fn atime(&self) -> i64 {
|
||||
self.st_atime()
|
||||
}
|
||||
fn atime_nsec(&self) -> i64 {
|
||||
self.st_atime_nsec()
|
||||
}
|
||||
fn mtime(&self) -> i64 {
|
||||
self.st_mtime()
|
||||
}
|
||||
fn mtime_nsec(&self) -> i64 {
|
||||
self.st_mtime_nsec()
|
||||
}
|
||||
fn ctime(&self) -> i64 {
|
||||
self.st_ctime()
|
||||
}
|
||||
fn ctime_nsec(&self) -> i64 {
|
||||
self.st_ctime_nsec()
|
||||
}
|
||||
fn blksize(&self) -> u64 {
|
||||
self.st_blksize()
|
||||
}
|
||||
fn blocks(&self) -> u64 {
|
||||
self.st_blocks()
|
||||
}
|
||||
}
|
||||
|
||||
/// Unix-specific extensions for [`FileType`].
|
||||
|
@ -759,10 +796,18 @@ pub trait FileTypeExt {
|
|||
|
||||
#[stable(feature = "file_type_ext", since = "1.5.0")]
|
||||
impl FileTypeExt for fs::FileType {
|
||||
fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
|
||||
fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
|
||||
fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) }
|
||||
fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
|
||||
fn is_block_device(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFBLK)
|
||||
}
|
||||
fn is_char_device(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFCHR)
|
||||
}
|
||||
fn is_fifo(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFIFO)
|
||||
}
|
||||
fn is_socket(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFSOCK)
|
||||
}
|
||||
}
|
||||
|
||||
/// Unix-specific extension methods for [`fs::DirEntry`].
|
||||
|
@ -794,7 +839,9 @@ pub trait DirEntryExt {
|
|||
|
||||
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
|
||||
impl DirEntryExt for fs::DirEntry {
|
||||
fn ino(&self) -> u64 { self.as_inner().ino() }
|
||||
fn ino(&self) -> u64 {
|
||||
self.as_inner().ino()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new symbolic link on the filesystem.
|
||||
|
@ -821,8 +868,7 @@ impl DirEntryExt for fs::DirEntry {
|
|||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "symlink", since = "1.1.0")]
|
||||
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
|
||||
{
|
||||
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
|
||||
sys::fs::symlink(src.as_ref(), dst.as_ref())
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::fs;
|
||||
use crate::io;
|
||||
use crate::os::raw;
|
||||
use crate::sys;
|
||||
use crate::io;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
|
||||
/// Raw file descriptors.
|
||||
|
@ -83,30 +83,42 @@ impl IntoRawFd for fs::File {
|
|||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for io::Stdin {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDIN_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for io::Stdout {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDOUT_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for io::Stderr {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDERR_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||
impl<'a> AsRawFd for io::StdinLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDIN_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||
impl<'a> AsRawFd for io::StdoutLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDOUT_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||
impl<'a> AsRawFd for io::StderrLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDERR_FILENO
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
use crate::ffi::OsStr;
|
||||
use crate::io;
|
||||
use crate::os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
|
||||
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use crate::process;
|
||||
use crate::sys;
|
||||
use crate::sys_common::{AsInnerMut, AsInner, FromInner, IntoInner};
|
||||
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
||||
|
||||
/// Unix-specific extensions to the [`process::Command`] builder.
|
||||
///
|
||||
|
@ -56,7 +56,8 @@ pub trait CommandExt {
|
|||
/// locations may not appear where intended.
|
||||
#[stable(feature = "process_pre_exec", since = "1.34.0")]
|
||||
unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
|
||||
where F: FnMut() -> io::Result<()> + Send + Sync + 'static;
|
||||
where
|
||||
F: FnMut() -> io::Result<()> + Send + Sync + 'static;
|
||||
|
||||
/// Schedules a closure to be run just before the `exec` function is
|
||||
/// invoked.
|
||||
|
@ -68,7 +69,8 @@ pub trait CommandExt {
|
|||
#[stable(feature = "process_exec", since = "1.15.0")]
|
||||
#[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
|
||||
fn before_exec<F>(&mut self, f: F) -> &mut process::Command
|
||||
where F: FnMut() -> io::Result<()> + Send + Sync + 'static
|
||||
where
|
||||
F: FnMut() -> io::Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
unsafe { self.pre_exec(f) }
|
||||
}
|
||||
|
@ -111,7 +113,8 @@ pub trait CommandExt {
|
|||
/// default executable path.
|
||||
#[unstable(feature = "process_set_argv0", issue = "66510")]
|
||||
fn arg0<S>(&mut self, arg: S) -> &mut process::Command
|
||||
where S: AsRef<OsStr>;
|
||||
where
|
||||
S: AsRef<OsStr>;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -127,7 +130,8 @@ impl CommandExt for process::Command {
|
|||
}
|
||||
|
||||
unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
|
||||
where F: FnMut() -> io::Result<()> + Send + Sync + 'static
|
||||
where
|
||||
F: FnMut() -> io::Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
self.as_inner_mut().pre_exec(Box::new(f));
|
||||
self
|
||||
|
@ -138,7 +142,8 @@ impl CommandExt for process::Command {
|
|||
}
|
||||
|
||||
fn arg0<S>(&mut self, arg: S) -> &mut process::Command
|
||||
where S: AsRef<OsStr>
|
||||
where
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
self.as_inner_mut().set_arg_0(arg.as_ref());
|
||||
self
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
//! Unix-specific primitives available on all unix platforms
|
||||
|
||||
#![stable(feature = "raw_ext", since = "1.1.0")]
|
||||
#![rustc_deprecated(since = "1.8.0",
|
||||
reason = "these type aliases are no longer supported by \
|
||||
the standard library, the `libc` crate on \
|
||||
crates.io should be used instead for the correct \
|
||||
definitions")]
|
||||
#![rustc_deprecated(
|
||||
since = "1.8.0",
|
||||
reason = "these type aliases are no longer supported by \
|
||||
the standard library, the `libc` crate on \
|
||||
crates.io should be used instead for the correct \
|
||||
definitions"
|
||||
)]
|
||||
#![allow(deprecated)]
|
||||
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type uid_t = u32;
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type gid_t = u32;
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type pid_t = i32;
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||
pub type uid_t = u32;
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||
pub type gid_t = u32;
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||
pub type pid_t = i32;
|
||||
|
||||
#[doc(inline)]
|
||||
#[stable(feature = "pthread_t", since = "1.8.0")]
|
||||
pub use crate::sys::platform::raw::pthread_t;
|
||||
#[doc(inline)]
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||
pub use crate::sys::platform::raw::{dev_t, ino_t, mode_t, nlink_t, off_t, blksize_t};
|
||||
pub use crate::sys::platform::raw::{blkcnt_t, time_t};
|
||||
#[doc(inline)]
|
||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||
pub use crate::sys::platform::raw::{blkcnt_t, time_t};
|
||||
pub use crate::sys::platform::raw::{blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t};
|
||||
|
|
|
@ -10,25 +10,34 @@
|
|||
// fallback implementation to use as well.
|
||||
//
|
||||
// Due to rust-lang/rust#18804, make sure this is not generic!
|
||||
#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox",
|
||||
target_os = "emscripten"))]
|
||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "emscripten"
|
||||
))]
|
||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
||||
use crate::mem;
|
||||
use crate::sys_common::thread_local::register_dtor_fallback;
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
#[linkage = "extern_weak"]
|
||||
static __dso_handle: *mut u8;
|
||||
#[linkage = "extern_weak"]
|
||||
static __cxa_thread_atexit_impl: *const libc::c_void;
|
||||
}
|
||||
if !__cxa_thread_atexit_impl.is_null() {
|
||||
type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
|
||||
arg: *mut u8,
|
||||
dso_handle: *mut u8) -> libc::c_int;
|
||||
mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
|
||||
(dtor, t, &__dso_handle as *const _ as *mut _);
|
||||
return
|
||||
type F = unsafe extern "C" fn(
|
||||
dtor: unsafe extern "C" fn(*mut u8),
|
||||
arg: *mut u8,
|
||||
dso_handle: *mut u8,
|
||||
) -> libc::c_int;
|
||||
mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)(
|
||||
dtor,
|
||||
t,
|
||||
&__dso_handle as *const _ as *mut _,
|
||||
);
|
||||
return;
|
||||
}
|
||||
register_dtor_fallback(t, dtor);
|
||||
}
|
||||
|
@ -44,7 +53,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
|||
// thread. thread_local dtors are pushed to the DTOR list without calling
|
||||
// _tlv_atexit.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
||||
use crate::cell::Cell;
|
||||
use crate::ptr;
|
||||
|
||||
|
@ -55,7 +64,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
|||
REGISTERED.set(true);
|
||||
}
|
||||
|
||||
type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
|
||||
type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
|
||||
|
||||
#[thread_local]
|
||||
static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut());
|
||||
|
@ -64,15 +73,14 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
|||
DTORS.set(Box::into_raw(v));
|
||||
}
|
||||
|
||||
extern {
|
||||
fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
|
||||
arg: *mut u8);
|
||||
extern "C" {
|
||||
fn _tlv_atexit(dtor: unsafe extern "C" fn(*mut u8), arg: *mut u8);
|
||||
}
|
||||
|
||||
let list: &mut List = &mut *DTORS.get();
|
||||
list.push((t, dtor));
|
||||
|
||||
unsafe extern fn run_dtors(_: *mut u8) {
|
||||
unsafe extern "C" fn run_dtors(_: *mut u8) {
|
||||
let mut ptr = DTORS.replace(ptr::null_mut());
|
||||
while !ptr.is_null() {
|
||||
let list = Box::from_raw(ptr);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
||||
|
||||
use crate::cmp;
|
||||
use crate::io::{self, Read, Initializer, IoSlice, IoSliceMut};
|
||||
use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
|
||||
use crate::mem;
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
use crate::sys::cvt;
|
||||
|
@ -35,7 +35,9 @@ impl FileDesc {
|
|||
FileDesc { fd }
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> c_int { self.fd }
|
||||
pub fn raw(&self) -> c_int {
|
||||
self.fd
|
||||
}
|
||||
|
||||
/// Extracts the actual file descriptor without closing it.
|
||||
pub fn into_raw(self) -> c_int {
|
||||
|
@ -46,18 +48,18 @@ impl FileDesc {
|
|||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::read(self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
cmp::min(buf.len(), max_len()))
|
||||
libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::readv(self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
||||
libc::readv(
|
||||
self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
@ -72,39 +74,44 @@ impl FileDesc {
|
|||
use super::android::cvt_pread64;
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
|
||||
-> io::Result<isize>
|
||||
{
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::pread64;
|
||||
unsafe fn cvt_pread64(
|
||||
fd: c_int,
|
||||
buf: *mut c_void,
|
||||
count: usize,
|
||||
offset: i64,
|
||||
) -> io::Result<isize> {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::pread as pread64;
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::pread64;
|
||||
cvt(pread64(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cvt_pread64(self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
cmp::min(buf.len(), max_len()),
|
||||
offset as i64)
|
||||
.map(|n| n as usize)
|
||||
cvt_pread64(
|
||||
self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
cmp::min(buf.len(), max_len()),
|
||||
offset as i64,
|
||||
)
|
||||
.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::write(self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
cmp::min(buf.len(), max_len()))
|
||||
libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::writev(self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
||||
libc::writev(
|
||||
self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
@ -114,54 +121,61 @@ impl FileDesc {
|
|||
use super::android::cvt_pwrite64;
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
|
||||
-> io::Result<isize>
|
||||
{
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::pwrite64;
|
||||
unsafe fn cvt_pwrite64(
|
||||
fd: c_int,
|
||||
buf: *const c_void,
|
||||
count: usize,
|
||||
offset: i64,
|
||||
) -> io::Result<isize> {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::pwrite as pwrite64;
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::pwrite64;
|
||||
cvt(pwrite64(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cvt_pwrite64(self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
cmp::min(buf.len(), max_len()),
|
||||
offset as i64)
|
||||
.map(|n| n as usize)
|
||||
cvt_pwrite64(
|
||||
self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
cmp::min(buf.len(), max_len()),
|
||||
offset as i64,
|
||||
)
|
||||
.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn get_cloexec(&self) -> io::Result<bool> {
|
||||
unsafe {
|
||||
Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
|
||||
}
|
||||
unsafe { Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_env = "newlib",
|
||||
target_os = "solaris",
|
||||
target_os = "emscripten",
|
||||
target_os = "fuchsia",
|
||||
target_os = "l4re",
|
||||
target_os = "linux",
|
||||
target_os = "haiku",
|
||||
target_os = "redox")))]
|
||||
#[cfg(not(any(
|
||||
target_env = "newlib",
|
||||
target_os = "solaris",
|
||||
target_os = "emscripten",
|
||||
target_os = "fuchsia",
|
||||
target_os = "l4re",
|
||||
target_os = "linux",
|
||||
target_os = "haiku",
|
||||
target_os = "redox"
|
||||
)))]
|
||||
pub fn set_cloexec(&self) -> io::Result<()> {
|
||||
unsafe {
|
||||
cvt(libc::ioctl(self.fd, libc::FIOCLEX))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_env = "newlib",
|
||||
target_os = "solaris",
|
||||
target_os = "emscripten",
|
||||
target_os = "fuchsia",
|
||||
target_os = "l4re",
|
||||
target_os = "linux",
|
||||
target_os = "haiku",
|
||||
target_os = "redox"))]
|
||||
#[cfg(any(
|
||||
target_env = "newlib",
|
||||
target_os = "solaris",
|
||||
target_os = "emscripten",
|
||||
target_os = "fuchsia",
|
||||
target_os = "l4re",
|
||||
target_os = "linux",
|
||||
target_os = "haiku",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub fn set_cloexec(&self) -> io::Result<()> {
|
||||
unsafe {
|
||||
let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
|
||||
|
@ -216,7 +230,7 @@ impl FileDesc {
|
|||
// [1]: http://comments.gmane.org/gmane.linux.lib.musl.general/2963
|
||||
#[cfg(any(target_os = "android", target_os = "haiku"))]
|
||||
use libc::F_DUPFD as F_DUPFD_CLOEXEC;
|
||||
#[cfg(not(any(target_os = "android", target_os="haiku")))]
|
||||
#[cfg(not(any(target_os = "android", target_os = "haiku")))]
|
||||
use libc::F_DUPFD_CLOEXEC;
|
||||
|
||||
let make_filedesc = |fd| {
|
||||
|
@ -224,8 +238,7 @@ impl FileDesc {
|
|||
fd.set_cloexec()?;
|
||||
Ok(fd)
|
||||
};
|
||||
static TRY_CLOEXEC: AtomicBool =
|
||||
AtomicBool::new(!cfg!(target_os = "android"));
|
||||
static TRY_CLOEXEC: AtomicBool = AtomicBool::new(!cfg!(target_os = "android"));
|
||||
let fd = self.raw();
|
||||
if TRY_CLOEXEC.load(Ordering::Relaxed) {
|
||||
match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) {
|
||||
|
@ -237,7 +250,7 @@ impl FileDesc {
|
|||
make_filedesc(fd)?
|
||||
} else {
|
||||
FileDesc::new(fd)
|
||||
})
|
||||
});
|
||||
}
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
|
||||
TRY_CLOEXEC.store(false, Ordering::Relaxed);
|
||||
|
@ -261,7 +274,9 @@ impl<'a> Read for &'a FileDesc {
|
|||
}
|
||||
|
||||
impl AsInner<c_int> for FileDesc {
|
||||
fn as_inner(&self) -> &c_int { &self.fd }
|
||||
fn as_inner(&self) -> &c_int {
|
||||
&self.fd
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FileDesc {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::marker::PhantomData;
|
||||
use crate::slice;
|
||||
|
||||
use libc::{iovec, c_void};
|
||||
use libc::{c_void, iovec};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct IoSlice<'a> {
|
||||
|
@ -13,10 +13,7 @@ impl<'a> IoSlice<'a> {
|
|||
#[inline]
|
||||
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||
IoSlice {
|
||||
vec: iovec {
|
||||
iov_base: buf.as_ptr() as *mut u8 as *mut c_void,
|
||||
iov_len: buf.len()
|
||||
},
|
||||
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +32,7 @@ impl<'a> IoSlice<'a> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
||||
}
|
||||
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,10 +46,7 @@ impl<'a> IoSliceMut<'a> {
|
|||
#[inline]
|
||||
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||
IoSliceMut {
|
||||
vec: iovec {
|
||||
iov_base: buf.as_mut_ptr() as *mut c_void,
|
||||
iov_len: buf.len()
|
||||
},
|
||||
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -73,15 +65,11 @@ impl<'a> IoSliceMut<'a> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
||||
}
|
||||
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
||||
}
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
macro_rules! unimpl {
|
||||
() => (return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));)
|
||||
() => {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));
|
||||
};
|
||||
}
|
||||
|
||||
pub mod net {
|
||||
#![allow(warnings)]
|
||||
use crate::convert::TryFrom;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::Duration;
|
||||
use crate::convert::TryFrom;
|
||||
|
||||
#[allow(unused_extern_crates)]
|
||||
pub extern crate libc as netc;
|
||||
|
@ -33,8 +35,11 @@ pub mod net {
|
|||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t)
|
||||
-> io::Result<Socket> {
|
||||
pub fn accept(
|
||||
&self,
|
||||
_: *mut libc::sockaddr,
|
||||
_: *mut libc::socklen_t,
|
||||
) -> io::Result<Socket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
|
@ -100,15 +105,21 @@ pub mod net {
|
|||
}
|
||||
|
||||
impl AsInner<libc::c_int> for Socket {
|
||||
fn as_inner(&self) -> &libc::c_int { self.0.as_inner() }
|
||||
fn as_inner(&self) -> &libc::c_int {
|
||||
self.0.as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<libc::c_int> for Socket {
|
||||
fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) }
|
||||
fn from_inner(fd: libc::c_int) -> Socket {
|
||||
Socket(FileDesc::new(fd))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<libc::c_int> for Socket {
|
||||
fn into_inner(self) -> libc::c_int { self.0.into_raw() }
|
||||
fn into_inner(self) -> libc::c_int {
|
||||
self.0.into_raw()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpStream {
|
||||
|
@ -124,9 +135,13 @@ pub mod net {
|
|||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket { &self.inner }
|
||||
pub fn socket(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
pub fn into_socket(self) -> Socket {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
unimpl!();
|
||||
|
@ -226,9 +241,13 @@ pub mod net {
|
|||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket { &self.inner }
|
||||
pub fn socket(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
pub fn into_socket(self) -> Socket {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
|
@ -288,9 +307,13 @@ pub mod net {
|
|||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket { &self.inner }
|
||||
pub fn socket(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
pub fn into_socket(self) -> Socket {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
|
@ -364,24 +387,20 @@ pub mod net {
|
|||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
|
@ -450,7 +469,6 @@ pub mod net {
|
|||
unsafe impl Sync for LookupHost {}
|
||||
unsafe impl Send for LookupHost {}
|
||||
|
||||
|
||||
impl TryFrom<&str> for LookupHost {
|
||||
type Error = io::Error;
|
||||
|
||||
|
|
|
@ -6,32 +6,27 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
|||
libc::memchr(
|
||||
haystack.as_ptr() as *const libc::c_void,
|
||||
needle as libc::c_int,
|
||||
haystack.len())
|
||||
haystack.len(),
|
||||
)
|
||||
};
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(p as usize - (haystack.as_ptr() as usize))
|
||||
}
|
||||
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
|
||||
}
|
||||
|
||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
|
||||
if haystack.is_empty() {return None}
|
||||
if haystack.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let p = unsafe {
|
||||
libc::memrchr(
|
||||
haystack.as_ptr() as *const libc::c_void,
|
||||
needle as libc::c_int,
|
||||
haystack.len())
|
||||
haystack.len(),
|
||||
)
|
||||
};
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(p as usize - (haystack.as_ptr() as usize))
|
||||
}
|
||||
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::cmp;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::mem;
|
||||
use crate::net::{SocketAddr, Shutdown};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::str;
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::{Duration, Instant};
|
||||
use crate::cmp;
|
||||
|
||||
use libc::{c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
|
||||
|
||||
|
@ -42,23 +42,23 @@ pub fn init() {}
|
|||
|
||||
pub fn cvt_gai(err: c_int) -> io::Result<()> {
|
||||
if err == 0 {
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
|
||||
on_resolver_failure();
|
||||
|
||||
if err == EAI_SYSTEM {
|
||||
return Err(io::Error::last_os_error())
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let detail = unsafe {
|
||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
|
||||
.to_owned()
|
||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap().to_owned()
|
||||
};
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
&format!("failed to lookup address information: {}",
|
||||
detail)[..]))
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
&format!("failed to lookup address information: {}", detail)[..],
|
||||
))
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
|
@ -106,7 +106,7 @@ impl Socket {
|
|||
Ok(_) => {
|
||||
return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
|
||||
}
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {},
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
@ -135,15 +135,13 @@ impl Socket {
|
|||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
let mut pollfd = libc::pollfd {
|
||||
fd: self.0.raw(),
|
||||
events: libc::POLLOUT,
|
||||
revents: 0,
|
||||
};
|
||||
let mut pollfd = libc::pollfd { fd: self.0.raw(), events: libc::POLLOUT, revents: 0 };
|
||||
|
||||
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
|
||||
let start = Instant::now();
|
||||
|
@ -155,7 +153,8 @@ impl Socket {
|
|||
}
|
||||
|
||||
let timeout = timeout - elapsed;
|
||||
let mut timeout = timeout.as_secs()
|
||||
let mut timeout = timeout
|
||||
.as_secs()
|
||||
.saturating_mul(1_000)
|
||||
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
||||
if timeout == 0 {
|
||||
|
@ -176,10 +175,9 @@ impl Socket {
|
|||
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
||||
// for POLLHUP rather than read readiness
|
||||
if pollfd.revents & libc::POLLHUP != 0 {
|
||||
let e = self.take_error()?
|
||||
.unwrap_or_else(|| {
|
||||
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
||||
});
|
||||
let e = self.take_error()?.unwrap_or_else(|| {
|
||||
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
||||
});
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
|
@ -189,8 +187,7 @@ impl Socket {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
|
||||
-> io::Result<Socket> {
|
||||
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
|
||||
// Unfortunately the only known way right now to accept a socket and
|
||||
// atomically set the CLOEXEC flag is to use the `accept4` syscall on
|
||||
// Linux. This was added in 2.6.28, however, and because we support
|
||||
|
@ -204,9 +201,7 @@ impl Socket {
|
|||
flags: c_int
|
||||
) -> c_int
|
||||
}
|
||||
let res = cvt_r(|| unsafe {
|
||||
accept4(self.0.raw(), storage, len, SOCK_CLOEXEC)
|
||||
});
|
||||
let res = cvt_r(|| unsafe { accept4(self.0.raw(), storage, len, SOCK_CLOEXEC) });
|
||||
match res {
|
||||
Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
|
||||
|
@ -214,9 +209,7 @@ impl Socket {
|
|||
}
|
||||
}
|
||||
|
||||
let fd = cvt_r(|| unsafe {
|
||||
libc::accept(self.0.raw(), storage, len)
|
||||
})?;
|
||||
let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?;
|
||||
let fd = FileDesc::new(fd);
|
||||
fd.set_cloexec()?;
|
||||
Ok(Socket(fd))
|
||||
|
@ -228,10 +221,7 @@ impl Socket {
|
|||
|
||||
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::recv(self.0.raw(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
flags)
|
||||
libc::recv(self.0.raw(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
@ -248,18 +238,23 @@ impl Socket {
|
|||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
|
||||
-> io::Result<(usize, SocketAddr)> {
|
||||
fn recv_from_with_flags(
|
||||
&self,
|
||||
buf: &mut [u8],
|
||||
flags: c_int,
|
||||
) -> io::Result<(usize, SocketAddr)> {
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
|
||||
|
||||
let n = cvt(unsafe {
|
||||
libc::recvfrom(self.0.raw(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
flags,
|
||||
&mut storage as *mut _ as *mut _,
|
||||
&mut addrlen)
|
||||
libc::recvfrom(
|
||||
self.0.raw(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
flags,
|
||||
&mut storage as *mut _ as *mut _,
|
||||
&mut addrlen,
|
||||
)
|
||||
})?;
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
}
|
||||
|
@ -284,8 +279,10 @@ impl Socket {
|
|||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
|
||||
let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
|
||||
|
@ -302,12 +299,7 @@ impl Socket {
|
|||
}
|
||||
timeout
|
||||
}
|
||||
None => {
|
||||
libc::timeval {
|
||||
tv_sec: 0,
|
||||
tv_usec: 0,
|
||||
}
|
||||
}
|
||||
None => libc::timeval { tv_sec: 0, tv_usec: 0 },
|
||||
};
|
||||
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
||||
}
|
||||
|
@ -349,24 +341,26 @@ impl Socket {
|
|||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
|
||||
if raw == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(io::Error::from_raw_os_error(raw as i32)))
|
||||
}
|
||||
if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<c_int> for Socket {
|
||||
fn as_inner(&self) -> &c_int { self.0.as_inner() }
|
||||
fn as_inner(&self) -> &c_int {
|
||||
self.0.as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<c_int> for Socket {
|
||||
fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
|
||||
fn from_inner(fd: c_int) -> Socket {
|
||||
Socket(FileDesc::new(fd))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<c_int> for Socket {
|
||||
fn into_inner(self) -> c_int { self.0.into_raw() }
|
||||
fn into_inner(self) -> c_int {
|
||||
self.0.into_raw()
|
||||
}
|
||||
}
|
||||
|
||||
// In versions of glibc prior to 2.26, there's a bug where the DNS resolver
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::path::Prefix;
|
||||
use crate::ffi::OsStr;
|
||||
use crate::path::Prefix;
|
||||
|
||||
#[inline]
|
||||
pub fn is_sep_byte(b: u8) -> bool {
|
||||
|
|
|
@ -22,15 +22,15 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
|||
// CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in
|
||||
// 2.6.27, however, and because we support 2.6.18 we must detect this
|
||||
// support dynamically.
|
||||
if cfg!(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "redox")) &&
|
||||
!INVALID.load(Ordering::SeqCst)
|
||||
if cfg!(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "redox"
|
||||
)) && !INVALID.load(Ordering::SeqCst)
|
||||
{
|
||||
|
||||
// Note that despite calling a glibc function here we may still
|
||||
// get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
|
||||
// emulate on older kernels, so if you happen to be running on
|
||||
|
@ -38,8 +38,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
|||
// see the syscall.
|
||||
match cvt(unsafe { pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
|
||||
Ok(_) => {
|
||||
return Ok((AnonPipe(FileDesc::new(fds[0])),
|
||||
AnonPipe(FileDesc::new(fds[1]))));
|
||||
return Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1]))));
|
||||
}
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
|
||||
INVALID.store(true, Ordering::SeqCst);
|
||||
|
@ -73,15 +72,15 @@ impl AnonPipe {
|
|||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
||||
pub fn fd(&self) -> &FileDesc {
|
||||
&self.0
|
||||
}
|
||||
pub fn into_fd(self) -> FileDesc {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe,
|
||||
v1: &mut Vec<u8>,
|
||||
p2: AnonPipe,
|
||||
v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
|
||||
pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
// Set both pipes into nonblocking mode as we're gonna be reading from both
|
||||
// in the `select` loop below, and we wouldn't want one to block the other!
|
||||
let p1 = p1.into_fd();
|
||||
|
@ -117,8 +116,9 @@ pub fn read2(p1: AnonPipe,
|
|||
match fd.read_to_end(dst) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) => {
|
||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
|
||||
e.raw_os_error() == Some(libc::EAGAIN) {
|
||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK)
|
||||
|| e.raw_os_error() == Some(libc::EAGAIN)
|
||||
{
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(e)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::os::unix::prelude::*;
|
||||
|
||||
use crate::ffi::{OsString, OsStr, CString, CStr};
|
||||
use crate::collections::BTreeMap;
|
||||
use crate::ffi::{CStr, CString, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::ptr;
|
||||
|
@ -8,12 +9,11 @@ use crate::sys::fd::FileDesc;
|
|||
use crate::sys::fs::File;
|
||||
use crate::sys::pipe::{self, AnonPipe};
|
||||
use crate::sys_common::process::CommandEnv;
|
||||
use crate::collections::BTreeMap;
|
||||
|
||||
#[cfg(not(target_os = "fuchsia"))]
|
||||
use crate::sys::fs::OpenOptions;
|
||||
|
||||
use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
|
||||
use libc::{c_char, c_int, gid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "fuchsia")] {
|
||||
|
@ -204,10 +204,7 @@ impl Command {
|
|||
&mut self.closures
|
||||
}
|
||||
|
||||
pub unsafe fn pre_exec(
|
||||
&mut self,
|
||||
f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>,
|
||||
) {
|
||||
pub unsafe fn pre_exec(&mut self, f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
|
||||
self.closures.push(f);
|
||||
}
|
||||
|
||||
|
@ -236,26 +233,21 @@ impl Command {
|
|||
self.env.have_changed_path()
|
||||
}
|
||||
|
||||
pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
|
||||
-> io::Result<(StdioPipes, ChildPipes)> {
|
||||
pub fn setup_io(
|
||||
&self,
|
||||
default: Stdio,
|
||||
needs_stdin: bool,
|
||||
) -> io::Result<(StdioPipes, ChildPipes)> {
|
||||
let null = Stdio::Null;
|
||||
let default_stdin = if needs_stdin {&default} else {&null};
|
||||
let default_stdin = if needs_stdin { &default } else { &null };
|
||||
let stdin = self.stdin.as_ref().unwrap_or(default_stdin);
|
||||
let stdout = self.stdout.as_ref().unwrap_or(&default);
|
||||
let stderr = self.stderr.as_ref().unwrap_or(&default);
|
||||
let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;
|
||||
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
|
||||
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
|
||||
let ours = StdioPipes {
|
||||
stdin: our_stdin,
|
||||
stdout: our_stdout,
|
||||
stderr: our_stderr,
|
||||
};
|
||||
let theirs = ChildPipes {
|
||||
stdin: their_stdin,
|
||||
stdout: their_stdout,
|
||||
stderr: their_stderr,
|
||||
};
|
||||
let ours = StdioPipes { stdin: our_stdin, stdout: our_stdout, stderr: our_stderr };
|
||||
let theirs = ChildPipes { stdin: their_stdin, stdout: their_stdout, stderr: their_stderr };
|
||||
Ok((ours, theirs))
|
||||
}
|
||||
}
|
||||
|
@ -270,21 +262,21 @@ fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString {
|
|||
// Helper type to manage ownership of the strings within a C-style array.
|
||||
pub struct CStringArray {
|
||||
items: Vec<CString>,
|
||||
ptrs: Vec<*const c_char>
|
||||
ptrs: Vec<*const c_char>,
|
||||
}
|
||||
|
||||
impl CStringArray {
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
let mut result = CStringArray {
|
||||
items: Vec::with_capacity(capacity),
|
||||
ptrs: Vec::with_capacity(capacity+1)
|
||||
ptrs: Vec::with_capacity(capacity + 1),
|
||||
};
|
||||
result.ptrs.push(ptr::null());
|
||||
result
|
||||
}
|
||||
pub fn push(&mut self, item: CString) {
|
||||
let l = self.ptrs.len();
|
||||
self.ptrs[l-1] = item.as_ptr();
|
||||
self.ptrs[l - 1] = item.as_ptr();
|
||||
self.ptrs.push(ptr::null());
|
||||
self.items.push(item);
|
||||
}
|
||||
|
@ -315,12 +307,9 @@ fn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStr
|
|||
}
|
||||
|
||||
impl Stdio {
|
||||
pub fn to_child_stdio(&self, readable: bool)
|
||||
-> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
||||
pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
||||
match *self {
|
||||
Stdio::Inherit => {
|
||||
Ok((ChildStdio::Inherit, None))
|
||||
},
|
||||
Stdio::Inherit => Ok((ChildStdio::Inherit, None)),
|
||||
|
||||
// Make sure that the source descriptors are not an stdio
|
||||
// descriptor, otherwise the order which we set the child's
|
||||
|
@ -339,11 +328,7 @@ impl Stdio {
|
|||
|
||||
Stdio::MakePipe => {
|
||||
let (reader, writer) = pipe::anon_pipe()?;
|
||||
let (ours, theirs) = if readable {
|
||||
(writer, reader)
|
||||
} else {
|
||||
(reader, writer)
|
||||
};
|
||||
let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) };
|
||||
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
|
||||
}
|
||||
|
||||
|
@ -352,17 +337,13 @@ impl Stdio {
|
|||
let mut opts = OpenOptions::new();
|
||||
opts.read(readable);
|
||||
opts.write(!readable);
|
||||
let path = unsafe {
|
||||
CStr::from_ptr(DEV_NULL.as_ptr() as *const _)
|
||||
};
|
||||
let path = unsafe { CStr::from_ptr(DEV_NULL.as_ptr() as *const _) };
|
||||
let fd = File::open_c(&path, &opts)?;
|
||||
Ok((ChildStdio::Owned(fd.into_fd()), None))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
Stdio::Null => {
|
||||
Ok((ChildStdio::Null, None))
|
||||
}
|
||||
Stdio::Null => Ok((ChildStdio::Null, None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +411,7 @@ mod tests {
|
|||
Ok(t) => t,
|
||||
Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// See #14232 for more information, but it appears that signal delivery to a
|
||||
|
@ -461,8 +442,7 @@ mod tests {
|
|||
let stdin_write = pipes.stdin.take().unwrap();
|
||||
let stdout_read = pipes.stdout.take().unwrap();
|
||||
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
|
||||
ptr::null_mut())));
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut())));
|
||||
|
||||
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
|
||||
// We need to wait until SIGINT is definitely delivered. The
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::convert::TryInto;
|
||||
use crate::io;
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::mem;
|
||||
use crate::ptr;
|
||||
|
||||
use crate::sys::process::zircon::{Handle, zx_handle_t};
|
||||
use crate::sys::process::process_common::*;
|
||||
use crate::sys::process::zircon::{zx_handle_t, Handle};
|
||||
|
||||
use libc::{c_int, size_t};
|
||||
|
||||
|
@ -14,13 +14,18 @@ use libc::{c_int, size_t};
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Command {
|
||||
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
|
||||
-> io::Result<(Process, StdioPipes)> {
|
||||
pub fn spawn(
|
||||
&mut self,
|
||||
default: Stdio,
|
||||
needs_stdin: bool,
|
||||
) -> io::Result<(Process, StdioPipes)> {
|
||||
let envp = self.capture_env();
|
||||
|
||||
if self.saw_nul() {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"nul byte found in provided data"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"nul byte found in provided data",
|
||||
));
|
||||
}
|
||||
|
||||
let (ours, theirs) = self.setup_io(default, needs_stdin)?;
|
||||
|
@ -32,21 +37,23 @@ impl Command {
|
|||
|
||||
pub fn exec(&mut self, default: Stdio) -> io::Error {
|
||||
if self.saw_nul() {
|
||||
return io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"nul byte found in provided data")
|
||||
return io::Error::new(io::ErrorKind::InvalidInput, "nul byte found in provided data");
|
||||
}
|
||||
|
||||
match self.setup_io(default, true) {
|
||||
Ok((_, _)) => {
|
||||
// FIXME: This is tough because we don't support the exec syscalls
|
||||
unimplemented!();
|
||||
},
|
||||
}
|
||||
Err(e) => e,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray>)
|
||||
-> io::Result<zx_handle_t> {
|
||||
unsafe fn do_exec(
|
||||
&mut self,
|
||||
stdio: ChildPipes,
|
||||
maybe_envp: Option<&CStringArray>,
|
||||
) -> io::Result<zx_handle_t> {
|
||||
use crate::sys::process::zircon::*;
|
||||
|
||||
let envp = match maybe_envp {
|
||||
|
@ -108,10 +115,15 @@ impl Command {
|
|||
let mut process_handle: zx_handle_t = 0;
|
||||
zx_cvt(fdio_spawn_etc(
|
||||
ZX_HANDLE_INVALID,
|
||||
FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE
|
||||
| FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null
|
||||
self.get_program().as_ptr(), self.get_argv().as_ptr(), envp,
|
||||
actions.len() as size_t, actions.as_ptr(),
|
||||
FDIO_SPAWN_CLONE_JOB
|
||||
| FDIO_SPAWN_CLONE_LDSVC
|
||||
| FDIO_SPAWN_CLONE_NAMESPACE
|
||||
| FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null
|
||||
self.get_program().as_ptr(),
|
||||
self.get_argv().as_ptr(),
|
||||
envp,
|
||||
actions.len() as size_t,
|
||||
actions.as_ptr(),
|
||||
&mut process_handle,
|
||||
ptr::null_mut(),
|
||||
))?;
|
||||
|
@ -137,7 +149,9 @@ impl Process {
|
|||
pub fn kill(&mut self) -> io::Result<()> {
|
||||
use crate::sys::process::zircon::*;
|
||||
|
||||
unsafe { zx_cvt(zx_task_kill(self.handle.raw()))?; }
|
||||
unsafe {
|
||||
zx_cvt(zx_task_kill(self.handle.raw()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -151,16 +165,26 @@ impl Process {
|
|||
let mut avail: size_t = 0;
|
||||
|
||||
unsafe {
|
||||
zx_cvt(zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
|
||||
ZX_TIME_INFINITE, ptr::null_mut()))?;
|
||||
zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
|
||||
&mut proc_info as *mut _ as *mut libc::c_void,
|
||||
mem::size_of::<zx_info_process_t>(), &mut actual,
|
||||
&mut avail))?;
|
||||
zx_cvt(zx_object_wait_one(
|
||||
self.handle.raw(),
|
||||
ZX_TASK_TERMINATED,
|
||||
ZX_TIME_INFINITE,
|
||||
ptr::null_mut(),
|
||||
))?;
|
||||
zx_cvt(zx_object_get_info(
|
||||
self.handle.raw(),
|
||||
ZX_INFO_PROCESS,
|
||||
&mut proc_info as *mut _ as *mut libc::c_void,
|
||||
mem::size_of::<zx_info_process_t>(),
|
||||
&mut actual,
|
||||
&mut avail,
|
||||
))?;
|
||||
}
|
||||
if actual != 1 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData,
|
||||
"Failed to get exit status of process"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Failed to get exit status of process",
|
||||
));
|
||||
}
|
||||
Ok(ExitStatus(proc_info.return_code))
|
||||
}
|
||||
|
@ -174,23 +198,31 @@ impl Process {
|
|||
let mut avail: size_t = 0;
|
||||
|
||||
unsafe {
|
||||
let status = zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
|
||||
0, ptr::null_mut());
|
||||
let status =
|
||||
zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut());
|
||||
match status {
|
||||
0 => { }, // Success
|
||||
0 => {} // Success
|
||||
x if x == ERR_TIMED_OUT => {
|
||||
return Ok(None);
|
||||
},
|
||||
_ => { panic!("Failed to wait on process handle: {}", status); },
|
||||
}
|
||||
_ => {
|
||||
panic!("Failed to wait on process handle: {}", status);
|
||||
}
|
||||
}
|
||||
zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
|
||||
&mut proc_info as *mut _ as *mut libc::c_void,
|
||||
mem::size_of::<zx_info_process_t>(), &mut actual,
|
||||
&mut avail))?;
|
||||
zx_cvt(zx_object_get_info(
|
||||
self.handle.raw(),
|
||||
ZX_INFO_PROCESS,
|
||||
&mut proc_info as *mut _ as *mut libc::c_void,
|
||||
mem::size_of::<zx_info_process_t>(),
|
||||
&mut actual,
|
||||
&mut avail,
|
||||
))?;
|
||||
}
|
||||
if actual != 1 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData,
|
||||
"Failed to get exit status of process"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Failed to get exit status of process",
|
||||
));
|
||||
}
|
||||
Ok(Some(ExitStatus(proc_info.return_code)))
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#![allow(non_camel_case_types, unused)]
|
||||
|
||||
use crate::convert::TryInto;
|
||||
use crate::io;
|
||||
use crate::i64;
|
||||
use crate::io;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::os::raw::c_char;
|
||||
|
||||
|
@ -16,27 +16,26 @@ pub type zx_status_t = i32;
|
|||
pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
|
||||
|
||||
pub type zx_time_t = i64;
|
||||
pub const ZX_TIME_INFINITE : zx_time_t = i64::MAX;
|
||||
pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
|
||||
|
||||
pub type zx_signals_t = u32;
|
||||
|
||||
pub const ZX_OBJECT_SIGNAL_3 : zx_signals_t = 1 << 3;
|
||||
pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
|
||||
|
||||
pub const ZX_TASK_TERMINATED : zx_signals_t = ZX_OBJECT_SIGNAL_3;
|
||||
pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
|
||||
|
||||
pub const ZX_RIGHT_SAME_RIGHTS : zx_rights_t = 1 << 31;
|
||||
pub const ZX_RIGHT_SAME_RIGHTS: zx_rights_t = 1 << 31;
|
||||
|
||||
pub type zx_object_info_topic_t = u32;
|
||||
|
||||
pub const ZX_INFO_PROCESS : zx_object_info_topic_t = 3;
|
||||
pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3;
|
||||
|
||||
pub fn zx_cvt<T>(t: T) -> io::Result<T> where T: TryInto<zx_status_t>+Copy {
|
||||
pub fn zx_cvt<T>(t: T) -> io::Result<T>
|
||||
where
|
||||
T: TryInto<zx_status_t> + Copy,
|
||||
{
|
||||
if let Ok(status) = TryInto::try_into(t) {
|
||||
if status < 0 {
|
||||
Err(io::Error::from_raw_os_error(status))
|
||||
} else {
|
||||
Ok(t)
|
||||
}
|
||||
if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
|
||||
} else {
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
|
@ -49,9 +48,7 @@ pub struct Handle {
|
|||
|
||||
impl Handle {
|
||||
pub fn new(raw: zx_handle_t) -> Handle {
|
||||
Handle {
|
||||
raw,
|
||||
}
|
||||
Handle { raw }
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> zx_handle_t {
|
||||
|
@ -61,7 +58,9 @@ impl Handle {
|
|||
|
||||
impl Drop for Handle {
|
||||
fn drop(&mut self) {
|
||||
unsafe { zx_cvt(zx_handle_close(self.raw)).expect("Failed to close zx_handle_t"); }
|
||||
unsafe {
|
||||
zx_cvt(zx_handle_close(self.raw)).expect("Failed to close zx_handle_t");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,22 +74,34 @@ pub struct zx_info_process_t {
|
|||
pub debugger_attached: bool,
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn zx_job_default() -> zx_handle_t;
|
||||
|
||||
pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
|
||||
|
||||
pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
|
||||
|
||||
pub fn zx_handle_duplicate(handle: zx_handle_t, rights: zx_rights_t,
|
||||
out: *const zx_handle_t) -> zx_handle_t;
|
||||
pub fn zx_handle_duplicate(
|
||||
handle: zx_handle_t,
|
||||
rights: zx_rights_t,
|
||||
out: *const zx_handle_t,
|
||||
) -> zx_handle_t;
|
||||
|
||||
pub fn zx_object_wait_one(handle: zx_handle_t, signals: zx_signals_t, timeout: zx_time_t,
|
||||
pending: *mut zx_signals_t) -> zx_status_t;
|
||||
pub fn zx_object_wait_one(
|
||||
handle: zx_handle_t,
|
||||
signals: zx_signals_t,
|
||||
timeout: zx_time_t,
|
||||
pending: *mut zx_signals_t,
|
||||
) -> zx_status_t;
|
||||
|
||||
pub fn zx_object_get_info(handle: zx_handle_t, topic: u32, buffer: *mut c_void,
|
||||
buffer_size: size_t, actual_size: *mut size_t,
|
||||
avail: *mut size_t) -> zx_status_t;
|
||||
pub fn zx_object_get_info(
|
||||
handle: zx_handle_t,
|
||||
topic: u32,
|
||||
buffer: *mut c_void,
|
||||
buffer_size: size_t,
|
||||
actual_size: *mut size_t,
|
||||
avail: *mut size_t,
|
||||
) -> zx_status_t;
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -103,11 +114,18 @@ pub struct fdio_spawn_action_t {
|
|||
pub reserved1: u64,
|
||||
}
|
||||
|
||||
extern {
|
||||
pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char,
|
||||
argv: *const *const c_char, envp: *const *const c_char,
|
||||
action_count: size_t, actions: *const fdio_spawn_action_t,
|
||||
process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
|
||||
extern "C" {
|
||||
pub fn fdio_spawn_etc(
|
||||
job: zx_handle_t,
|
||||
flags: u32,
|
||||
path: *const c_char,
|
||||
argv: *const *const c_char,
|
||||
envp: *const *const c_char,
|
||||
action_count: size_t,
|
||||
actions: *const fdio_spawn_action_t,
|
||||
process: *mut zx_handle_t,
|
||||
err_msg: *mut c_char,
|
||||
) -> zx_status_t;
|
||||
|
||||
pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
|
||||
pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
|
||||
|
@ -129,60 +147,74 @@ pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
|
|||
|
||||
// Errors
|
||||
|
||||
#[allow(unused)] pub const ERR_INTERNAL: zx_status_t = -1;
|
||||
#[allow(unused)]
|
||||
pub const ERR_INTERNAL: zx_status_t = -1;
|
||||
|
||||
// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
|
||||
// or enabled.
|
||||
#[allow(unused)] pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
|
||||
|
||||
// ERR_NO_RESOURCES: The system was not able to allocate some resource
|
||||
// needed for the operation.
|
||||
#[allow(unused)] pub const ERR_NO_RESOURCES: zx_status_t = -3;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NO_RESOURCES: zx_status_t = -3;
|
||||
|
||||
// ERR_NO_MEMORY: The system was not able to allocate memory needed
|
||||
// for the operation.
|
||||
#[allow(unused)] pub const ERR_NO_MEMORY: zx_status_t = -4;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NO_MEMORY: zx_status_t = -4;
|
||||
|
||||
// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
|
||||
// successfully.
|
||||
#[allow(unused)] pub const ERR_CALL_FAILED: zx_status_t = -5;
|
||||
#[allow(unused)]
|
||||
pub const ERR_CALL_FAILED: zx_status_t = -5;
|
||||
|
||||
// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
|
||||
// retried. This should not be seen outside of the VDSO.
|
||||
#[allow(unused)] pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
|
||||
#[allow(unused)]
|
||||
pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
|
||||
|
||||
// ======= Parameter errors =======
|
||||
// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
|
||||
#[allow(unused)] pub const ERR_INVALID_ARGS: zx_status_t = -10;
|
||||
#[allow(unused)]
|
||||
pub const ERR_INVALID_ARGS: zx_status_t = -10;
|
||||
|
||||
// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
|
||||
#[allow(unused)] pub const ERR_BAD_HANDLE: zx_status_t = -11;
|
||||
#[allow(unused)]
|
||||
pub const ERR_BAD_HANDLE: zx_status_t = -11;
|
||||
|
||||
// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
|
||||
// perform the operation.
|
||||
// Example: Attempting a message_read on a thread handle.
|
||||
#[allow(unused)] pub const ERR_WRONG_TYPE: zx_status_t = -12;
|
||||
#[allow(unused)]
|
||||
pub const ERR_WRONG_TYPE: zx_status_t = -12;
|
||||
|
||||
// ERR_BAD_SYSCALL: The specified syscall number is invalid.
|
||||
#[allow(unused)] pub const ERR_BAD_SYSCALL: zx_status_t = -13;
|
||||
#[allow(unused)]
|
||||
pub const ERR_BAD_SYSCALL: zx_status_t = -13;
|
||||
|
||||
// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
|
||||
// operation.
|
||||
#[allow(unused)] pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
|
||||
#[allow(unused)]
|
||||
pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
|
||||
|
||||
// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
|
||||
// this operation.
|
||||
#[allow(unused)] pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
|
||||
#[allow(unused)]
|
||||
pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
|
||||
|
||||
// ======= Precondition or state errors =======
|
||||
// ERR_BAD_STATE: operation failed because the current state of the
|
||||
// object does not allow it, or a precondition of the operation is
|
||||
// not satisfied
|
||||
#[allow(unused)] pub const ERR_BAD_STATE: zx_status_t = -20;
|
||||
#[allow(unused)]
|
||||
pub const ERR_BAD_STATE: zx_status_t = -20;
|
||||
|
||||
// ERR_TIMED_OUT: The time limit for the operation elapsed before
|
||||
// the operation completed.
|
||||
#[allow(unused)] pub const ERR_TIMED_OUT: zx_status_t = -21;
|
||||
#[allow(unused)]
|
||||
pub const ERR_TIMED_OUT: zx_status_t = -21;
|
||||
|
||||
// ERR_SHOULD_WAIT: The operation cannot be performed currently but
|
||||
// potentially could succeed if the caller waits for a prerequisite
|
||||
|
@ -192,67 +224,84 @@ pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
|
|||
// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
|
||||
// Attempting to read from a message pipe that has no messages waiting
|
||||
// and has a closed remote end will return ERR_REMOTE_CLOSED.
|
||||
#[allow(unused)] pub const ERR_SHOULD_WAIT: zx_status_t = -22;
|
||||
#[allow(unused)]
|
||||
pub const ERR_SHOULD_WAIT: zx_status_t = -22;
|
||||
|
||||
// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
|
||||
// // canceled.
|
||||
#[allow(unused)] pub const ERR_CANCELED: zx_status_t = -23;
|
||||
#[allow(unused)]
|
||||
pub const ERR_CANCELED: zx_status_t = -23;
|
||||
|
||||
// ERR_PEER_CLOSED: The operation failed because the remote end
|
||||
// of the subject of the operation was closed.
|
||||
#[allow(unused)] pub const ERR_PEER_CLOSED: zx_status_t = -24;
|
||||
#[allow(unused)]
|
||||
pub const ERR_PEER_CLOSED: zx_status_t = -24;
|
||||
|
||||
// ERR_NOT_FOUND: The requested entity is not found.
|
||||
#[allow(unused)] pub const ERR_NOT_FOUND: zx_status_t = -25;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NOT_FOUND: zx_status_t = -25;
|
||||
|
||||
// ERR_ALREADY_EXISTS: An object with the specified identifier
|
||||
// already exists.
|
||||
// Example: Attempting to create a file when a file already exists
|
||||
// with that name.
|
||||
#[allow(unused)] pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
|
||||
#[allow(unused)]
|
||||
pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
|
||||
|
||||
// ERR_ALREADY_BOUND: The operation failed because the named entity
|
||||
// is already owned or controlled by another entity. The operation
|
||||
// could succeed later if the current owner releases the entity.
|
||||
#[allow(unused)] pub const ERR_ALREADY_BOUND: zx_status_t = -27;
|
||||
#[allow(unused)]
|
||||
pub const ERR_ALREADY_BOUND: zx_status_t = -27;
|
||||
|
||||
// ERR_UNAVAILABLE: The subject of the operation is currently unable
|
||||
// to perform the operation.
|
||||
// Note: This is used when there's no direct way for the caller to
|
||||
// observe when the subject will be able to perform the operation
|
||||
// and should thus retry.
|
||||
#[allow(unused)] pub const ERR_UNAVAILABLE: zx_status_t = -28;
|
||||
#[allow(unused)]
|
||||
pub const ERR_UNAVAILABLE: zx_status_t = -28;
|
||||
|
||||
// ======= Permission check errors =======
|
||||
// ERR_ACCESS_DENIED: The caller did not have permission to perform
|
||||
// the specified operation.
|
||||
#[allow(unused)] pub const ERR_ACCESS_DENIED: zx_status_t = -30;
|
||||
#[allow(unused)]
|
||||
pub const ERR_ACCESS_DENIED: zx_status_t = -30;
|
||||
|
||||
// ======= Input-output errors =======
|
||||
// ERR_IO: Otherwise unspecified error occurred during I/O.
|
||||
#[allow(unused)] pub const ERR_IO: zx_status_t = -40;
|
||||
#[allow(unused)]
|
||||
pub const ERR_IO: zx_status_t = -40;
|
||||
|
||||
// ERR_REFUSED: The entity the I/O operation is being performed on
|
||||
// rejected the operation.
|
||||
// Example: an I2C device NAK'ing a transaction or a disk controller
|
||||
// rejecting an invalid command.
|
||||
#[allow(unused)] pub const ERR_IO_REFUSED: zx_status_t = -41;
|
||||
#[allow(unused)]
|
||||
pub const ERR_IO_REFUSED: zx_status_t = -41;
|
||||
|
||||
// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
|
||||
// check and is possibly corrupted.
|
||||
// Example: CRC or Parity error.
|
||||
#[allow(unused)] pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
|
||||
#[allow(unused)]
|
||||
pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
|
||||
|
||||
// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
|
||||
// and may be permanently lost.
|
||||
// Example: A disk block is irrecoverably damaged.
|
||||
#[allow(unused)] pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
|
||||
#[allow(unused)]
|
||||
pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
|
||||
|
||||
// Filesystem specific errors
|
||||
#[allow(unused)] pub const ERR_BAD_PATH: zx_status_t = -50;
|
||||
#[allow(unused)] pub const ERR_NOT_DIR: zx_status_t = -51;
|
||||
#[allow(unused)] pub const ERR_NOT_FILE: zx_status_t = -52;
|
||||
#[allow(unused)]
|
||||
pub const ERR_BAD_PATH: zx_status_t = -50;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NOT_DIR: zx_status_t = -51;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NOT_FILE: zx_status_t = -52;
|
||||
// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
|
||||
#[allow(unused)] pub const ERR_FILE_BIG: zx_status_t = -53;
|
||||
#[allow(unused)]
|
||||
pub const ERR_FILE_BIG: zx_status_t = -53;
|
||||
// ERR_NO_SPACE: Filesystem or device space is exhausted.
|
||||
#[allow(unused)] pub const ERR_NO_SPACE: zx_status_t = -54;
|
||||
#[allow(unused)]
|
||||
pub const ERR_NO_SPACE: zx_status_t = -54;
|
||||
|
|
|
@ -4,20 +4,21 @@ use crate::slice;
|
|||
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
let mut v = (0, 0);
|
||||
unsafe {
|
||||
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
|
||||
mem::size_of_val(&v));
|
||||
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, mem::size_of_val(&v));
|
||||
imp::fill_bytes(view);
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
#[cfg(all(unix,
|
||||
not(target_os = "ios"),
|
||||
not(target_os = "openbsd"),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "netbsd"),
|
||||
not(target_os = "fuchsia"),
|
||||
not(target_os = "redox")))]
|
||||
#[cfg(all(
|
||||
unix,
|
||||
not(target_os = "ios"),
|
||||
not(target_os = "openbsd"),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "netbsd"),
|
||||
not(target_os = "fuchsia"),
|
||||
not(target_os = "redox")
|
||||
))]
|
||||
mod imp {
|
||||
use crate::fs::File;
|
||||
use crate::io::Read;
|
||||
|
@ -30,7 +31,9 @@ mod imp {
|
|||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { false }
|
||||
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
|
||||
|
@ -96,9 +99,7 @@ mod imp {
|
|||
pub fn fill_bytes(v: &mut [u8]) {
|
||||
// getentropy(2) permits a maximum buffer size of 256 bytes
|
||||
for s in v.chunks_mut(256) {
|
||||
let ret = unsafe {
|
||||
libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len())
|
||||
};
|
||||
let ret = unsafe { libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len()) };
|
||||
if ret == -1 {
|
||||
panic!("unexpected getentropy error: {}", errno());
|
||||
}
|
||||
|
@ -124,21 +125,14 @@ mod imp {
|
|||
#[allow(non_upper_case_globals)]
|
||||
const kSecRandomDefault: *const SecRandom = ptr::null();
|
||||
|
||||
extern {
|
||||
fn SecRandomCopyBytes(rnd: *const SecRandom,
|
||||
count: size_t,
|
||||
bytes: *mut u8) -> c_int;
|
||||
extern "C" {
|
||||
fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int;
|
||||
}
|
||||
|
||||
pub fn fill_bytes(v: &mut [u8]) {
|
||||
let ret = unsafe {
|
||||
SecRandomCopyBytes(kSecRandomDefault,
|
||||
v.len(),
|
||||
v.as_mut_ptr())
|
||||
};
|
||||
let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) };
|
||||
if ret == -1 {
|
||||
panic!("couldn't generate random bytes: {}",
|
||||
io::Error::last_os_error());
|
||||
panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,13 +147,22 @@ mod imp {
|
|||
for s in v.chunks_mut(256) {
|
||||
let mut s_len = s.len();
|
||||
let ret = unsafe {
|
||||
libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
|
||||
s.as_mut_ptr() as *mut _, &mut s_len,
|
||||
ptr::null(), 0)
|
||||
libc::sysctl(
|
||||
mib.as_ptr(),
|
||||
mib.len() as libc::c_uint,
|
||||
s.as_mut_ptr() as *mut _,
|
||||
&mut s_len,
|
||||
ptr::null(),
|
||||
0,
|
||||
)
|
||||
};
|
||||
if ret == -1 || s_len != s.len() {
|
||||
panic!("kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
|
||||
ret, s.len(), s_len);
|
||||
panic!(
|
||||
"kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
|
||||
ret,
|
||||
s.len(),
|
||||
s_len
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +171,7 @@ mod imp {
|
|||
#[cfg(target_os = "fuchsia")]
|
||||
mod imp {
|
||||
#[link(name = "zircon")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn zx_cprng_draw(buffer: *mut u8, len: usize);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#![cfg_attr(test, allow(dead_code))]
|
||||
|
||||
use self::imp::{make_handler, drop_handler};
|
||||
use self::imp::{drop_handler, make_handler};
|
||||
|
||||
pub use self::imp::cleanup;
|
||||
pub use self::imp::init;
|
||||
|
||||
pub struct Handler {
|
||||
_data: *mut libc::c_void
|
||||
_data: *mut libc::c_void,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
|
@ -23,28 +23,28 @@ impl Drop for Handler {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "solaris",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "solaris",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
mod imp {
|
||||
use super::Handler;
|
||||
use crate::mem;
|
||||
use crate::ptr;
|
||||
|
||||
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
|
||||
use libc::{sigaction, SIGBUS, SIG_DFL,
|
||||
SA_SIGINFO, SA_ONSTACK, sighandler_t};
|
||||
use libc::{mmap, munmap};
|
||||
use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
|
||||
use libc::MAP_FAILED;
|
||||
use libc::{mmap, munmap};
|
||||
use libc::{sigaction, sighandler_t, SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_DFL};
|
||||
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
|
||||
use libc::{MAP_ANON, MAP_PRIVATE, PROT_READ, PROT_WRITE, SIGSEGV};
|
||||
|
||||
use crate::sys_common::thread_info;
|
||||
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
|
||||
#[repr(C)]
|
||||
|
@ -82,9 +82,11 @@ mod imp {
|
|||
// out many large systems and all implementations allow returning from a
|
||||
// signal handler to work. For a more detailed explanation see the
|
||||
// comments on #26458.
|
||||
unsafe extern fn signal_handler(signum: libc::c_int,
|
||||
info: *mut libc::siginfo_t,
|
||||
_data: *mut libc::c_void) {
|
||||
unsafe extern "C" fn signal_handler(
|
||||
signum: libc::c_int,
|
||||
info: *mut libc::siginfo_t,
|
||||
_data: *mut libc::c_void,
|
||||
) {
|
||||
use crate::sys_common::util::report_overflow;
|
||||
|
||||
let guard = thread_info::stack_guard().unwrap_or(0..0);
|
||||
|
@ -124,24 +126,22 @@ mod imp {
|
|||
}
|
||||
|
||||
unsafe fn get_stackp() -> *mut libc::c_void {
|
||||
let stackp = mmap(ptr::null_mut(),
|
||||
SIGSTKSZ,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON,
|
||||
-1,
|
||||
0);
|
||||
let stackp =
|
||||
mmap(ptr::null_mut(), SIGSTKSZ, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if stackp == MAP_FAILED {
|
||||
panic!("failed to allocate an alternative stack");
|
||||
}
|
||||
stackp
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris"))]
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris"
|
||||
))]
|
||||
unsafe fn get_stack() -> libc::stack_t {
|
||||
libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ mod imp {
|
|||
|
||||
pub unsafe fn drop_handler(handler: &mut Handler) {
|
||||
if !handler._data.is_null() {
|
||||
let stack = libc::stack_t {
|
||||
let stack = libc::stack_t {
|
||||
ss_sp: ptr::null_mut(),
|
||||
ss_flags: SS_DISABLE,
|
||||
// Workaround for bug in macOS implementation of sigaltstack
|
||||
|
@ -181,26 +181,25 @@ mod imp {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "solaris",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd")))]
|
||||
#[cfg(not(any(
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "solaris",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd"
|
||||
)))]
|
||||
mod imp {
|
||||
use crate::ptr;
|
||||
|
||||
pub unsafe fn init() {
|
||||
}
|
||||
pub unsafe fn init() {}
|
||||
|
||||
pub unsafe fn cleanup() {
|
||||
}
|
||||
pub unsafe fn cleanup() {}
|
||||
|
||||
pub unsafe fn make_handler() -> super::Handler {
|
||||
super::Handler { _data: ptr::null_mut() }
|
||||
}
|
||||
|
||||
pub unsafe fn drop_handler(_handler: &mut super::Handler) {
|
||||
}
|
||||
pub unsafe fn drop_handler(_handler: &mut super::Handler) {}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::mem::ManuallyDrop;
|
||||
use crate::sys::fd::FileDesc;
|
||||
|
||||
pub struct Stdin(());
|
||||
pub struct Stdout(());
|
||||
pub struct Stderr(());
|
||||
|
||||
impl Stdin {
|
||||
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
|
||||
pub fn new() -> io::Result<Stdin> {
|
||||
Ok(Stdin(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for Stdin {
|
||||
|
@ -21,7 +23,9 @@ impl io::Read for Stdin {
|
|||
}
|
||||
|
||||
impl Stdout {
|
||||
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
|
||||
pub fn new() -> io::Result<Stdout> {
|
||||
Ok(Stdout(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stdout {
|
||||
|
@ -39,7 +43,9 @@ impl io::Write for Stdout {
|
|||
}
|
||||
|
||||
impl Stderr {
|
||||
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
|
||||
pub fn new() -> io::Result<Stderr> {
|
||||
Ok(Stderr(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stderr {
|
||||
|
|
|
@ -25,21 +25,24 @@ unsafe impl Sync for Thread {}
|
|||
// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc,
|
||||
// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
|
||||
stack_size: libc::size_t) -> libc::c_int {
|
||||
unsafe fn pthread_attr_setstacksize(
|
||||
attr: *mut libc::pthread_attr_t,
|
||||
stack_size: libc::size_t,
|
||||
) -> libc::c_int {
|
||||
libc::pthread_attr_setstacksize(attr, stack_size)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "emscripten")]
|
||||
unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
|
||||
_stack_size: libc::size_t) -> libc::c_int {
|
||||
unsafe fn pthread_attr_setstacksize(
|
||||
_attr: *mut libc::pthread_attr_t,
|
||||
_stack_size: libc::size_t,
|
||||
) -> libc::c_int {
|
||||
panic!()
|
||||
}
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread> {
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
let p = box p;
|
||||
let mut native: libc::pthread_t = mem::zeroed();
|
||||
let mut attr: libc::pthread_attr_t = mem::zeroed();
|
||||
|
@ -47,8 +50,7 @@ impl Thread {
|
|||
|
||||
let stack_size = cmp::max(stack, min_stack_size(&attr));
|
||||
|
||||
match pthread_attr_setstacksize(&mut attr,
|
||||
stack_size) {
|
||||
match pthread_attr_setstacksize(&mut attr, stack_size) {
|
||||
0 => {}
|
||||
n => {
|
||||
assert_eq!(n, libc::EINVAL);
|
||||
|
@ -57,15 +59,13 @@ impl Thread {
|
|||
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
||||
// Round up to the nearest page and try again.
|
||||
let page_size = os::page_size();
|
||||
let stack_size = (stack_size + page_size - 1) &
|
||||
(-(page_size as isize - 1) as usize - 1);
|
||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
|
||||
stack_size), 0);
|
||||
let stack_size =
|
||||
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
|
||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
|
||||
}
|
||||
};
|
||||
|
||||
let ret = libc::pthread_create(&mut native, &attr, thread_start,
|
||||
&*p as *const _ as *mut _);
|
||||
let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
|
||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||
|
||||
return if ret != 0 {
|
||||
|
@ -75,8 +75,10 @@ impl Thread {
|
|||
Ok(Thread { id: native })
|
||||
};
|
||||
|
||||
extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
||||
unsafe { start_thread(main as *mut u8); }
|
||||
extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
||||
unsafe {
|
||||
start_thread(main as *mut u8);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
@ -86,8 +88,7 @@ impl Thread {
|
|||
debug_assert_eq!(ret, 0);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "android"))]
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub fn set_name(name: &CStr) {
|
||||
const PR_SET_NAME: libc::c_int = 15;
|
||||
// pthread wrapper only appeared in glibc 2.12, so we use syscall
|
||||
|
@ -97,9 +98,7 @@ impl Thread {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
|
||||
pub fn set_name(name: &CStr) {
|
||||
unsafe {
|
||||
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
|
||||
|
@ -118,8 +117,11 @@ impl Thread {
|
|||
use crate::ffi::CString;
|
||||
let cname = CString::new(&b"%s"[..]).unwrap();
|
||||
unsafe {
|
||||
libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(),
|
||||
name.as_ptr() as *mut libc::c_void);
|
||||
libc::pthread_setname_np(
|
||||
libc::pthread_self(),
|
||||
cname.as_ptr(),
|
||||
name.as_ptr() as *mut libc::c_void,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,15 +134,19 @@ impl Thread {
|
|||
}
|
||||
|
||||
if let Some(f) = pthread_setname_np.get() {
|
||||
unsafe { f(libc::pthread_self(), name.as_ptr()); }
|
||||
unsafe {
|
||||
f(libc::pthread_self(), name.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_env = "newlib",
|
||||
target_os = "haiku",
|
||||
target_os = "l4re",
|
||||
target_os = "emscripten",
|
||||
target_os = "redox"))]
|
||||
#[cfg(any(
|
||||
target_env = "newlib",
|
||||
target_os = "haiku",
|
||||
target_os = "l4re",
|
||||
target_os = "emscripten",
|
||||
target_os = "redox"
|
||||
))]
|
||||
pub fn set_name(_name: &CStr) {
|
||||
// Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
|
||||
}
|
||||
|
@ -177,12 +183,13 @@ impl Thread {
|
|||
unsafe {
|
||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||
mem::forget(self);
|
||||
assert!(ret == 0,
|
||||
"failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> libc::pthread_t { self.id }
|
||||
pub fn id(&self) -> libc::pthread_t {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn into_id(self) -> libc::pthread_t {
|
||||
let id = self.id;
|
||||
|
@ -198,31 +205,38 @@ impl Drop for Thread {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "macos"),
|
||||
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
|
||||
not(target_os = "openbsd"),
|
||||
not(target_os = "solaris")))]
|
||||
#[cfg(all(
|
||||
not(all(target_os = "linux", not(target_env = "musl"))),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "macos"),
|
||||
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
|
||||
not(target_os = "openbsd"),
|
||||
not(target_os = "solaris")
|
||||
))]
|
||||
#[cfg_attr(test, allow(dead_code))]
|
||||
pub mod guard {
|
||||
use crate::ops::Range;
|
||||
pub type Guard = Range<usize>;
|
||||
pub unsafe fn current() -> Option<Guard> { None }
|
||||
pub unsafe fn init() -> Option<Guard> { None }
|
||||
pub unsafe fn current() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
pub unsafe fn init() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(any(all(target_os = "linux", not(target_env = "musl")),
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "linux", not(target_env = "musl")),
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris"
|
||||
))]
|
||||
#[cfg_attr(test, allow(dead_code))]
|
||||
pub mod guard {
|
||||
use libc::{mmap, mprotect};
|
||||
use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
|
||||
use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
|
||||
|
||||
use crate::ops::Range;
|
||||
use crate::sys::os;
|
||||
|
@ -241,16 +255,15 @@ pub mod guard {
|
|||
|
||||
#[cfg(target_os = "macos")]
|
||||
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||
let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
|
||||
libc::pthread_get_stacksize_np(libc::pthread_self());
|
||||
let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize
|
||||
- libc::pthread_get_stacksize_np(libc::pthread_self());
|
||||
Some(stackaddr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||
let mut current_stack: libc::stack_t = crate::mem::zeroed();
|
||||
assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
|
||||
&mut current_stack), 0);
|
||||
assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(), &mut current_stack), 0);
|
||||
|
||||
let stackaddr = if libc::pthread_main_np() == 1 {
|
||||
// main thread
|
||||
|
@ -262,21 +275,25 @@ pub mod guard {
|
|||
Some(stackaddr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd",
|
||||
target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "l4re"
|
||||
))]
|
||||
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||
let mut ret = None;
|
||||
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
|
||||
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
|
||||
#[cfg(target_os = "freebsd")]
|
||||
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
|
||||
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
|
||||
let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
|
||||
if e == 0 {
|
||||
let mut stackaddr = crate::ptr::null_mut();
|
||||
let mut stacksize = 0;
|
||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
|
||||
&mut stacksize), 0);
|
||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
|
||||
ret = Some(stackaddr);
|
||||
}
|
||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||
|
@ -329,8 +346,14 @@ pub mod guard {
|
|||
// than the initial mmap() used, so we mmap() here with
|
||||
// read/write permissions and only then mprotect() it to
|
||||
// no permissions at all. See issue #50313.
|
||||
let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
|
||||
let result = mmap(
|
||||
stackaddr,
|
||||
PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON | MAP_FIXED,
|
||||
-1,
|
||||
0,
|
||||
);
|
||||
if result != stackaddr || result == MAP_FAILED {
|
||||
panic!("failed to allocate a guard page");
|
||||
}
|
||||
|
@ -341,34 +364,33 @@ pub mod guard {
|
|||
}
|
||||
|
||||
let guardaddr = stackaddr as usize;
|
||||
let offset = if cfg!(target_os = "freebsd") {
|
||||
2
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 };
|
||||
|
||||
Some(guardaddr..guardaddr + offset * PAGE_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris"))]
|
||||
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
|
||||
pub unsafe fn current() -> Option<Guard> {
|
||||
let stackaddr = get_stack_start()? as usize;
|
||||
Some(stackaddr - PAGE_SIZE..stackaddr)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd",
|
||||
target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "l4re"
|
||||
))]
|
||||
pub unsafe fn current() -> Option<Guard> {
|
||||
let mut ret = None;
|
||||
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
|
||||
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
|
||||
#[cfg(target_os = "freebsd")]
|
||||
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
|
||||
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
|
||||
let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
|
||||
if e == 0 {
|
||||
let mut guardsize = 0;
|
||||
assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
|
||||
|
@ -377,8 +399,7 @@ pub mod guard {
|
|||
}
|
||||
let mut stackaddr = crate::ptr::null_mut();
|
||||
let mut size = 0;
|
||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
|
||||
&mut size), 0);
|
||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
|
||||
|
||||
let stackaddr = stackaddr as usize;
|
||||
ret = if cfg!(target_os = "freebsd") {
|
||||
|
@ -422,8 +443,7 @@ fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
|
|||
|
||||
// No point in looking up __pthread_get_minstack() on non-glibc
|
||||
// platforms.
|
||||
#[cfg(all(not(target_os = "linux"),
|
||||
not(target_os = "netbsd")))]
|
||||
#[cfg(all(not(target_os = "linux"), not(target_os = "netbsd")))]
|
||||
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
||||
libc::PTHREAD_STACK_MIN
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::mem;
|
|||
pub type Key = libc::pthread_key_t;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||
let mut key = 0;
|
||||
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
||||
key
|
||||
|
|
|
@ -36,11 +36,7 @@ pub struct Weak<F> {
|
|||
|
||||
impl<F> Weak<F> {
|
||||
pub const fn new(name: &'static str) -> Weak<F> {
|
||||
Weak {
|
||||
name,
|
||||
addr: AtomicUsize::new(1),
|
||||
_marker: marker::PhantomData,
|
||||
}
|
||||
Weak { name, addr: AtomicUsize::new(1), _marker: marker::PhantomData }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Option<F> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ptr;
|
||||
use crate::sys_common::alloc::{MIN_ALIGN, realloc_fallback};
|
||||
use crate::alloc::{GlobalAlloc, Layout, System};
|
||||
use crate::ptr;
|
||||
use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
|
||||
|
||||
#[stable(feature = "alloc_system_type", since = "1.28.0")]
|
||||
unsafe impl GlobalAlloc for System {
|
||||
|
@ -45,9 +45,5 @@ unsafe impl GlobalAlloc for System {
|
|||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||
let mut out = ptr::null_mut();
|
||||
let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
|
||||
if ret != 0 {
|
||||
ptr::null_mut()
|
||||
} else {
|
||||
out as *mut u8
|
||||
}
|
||||
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
|
||||
}
|
||||
|
|
|
@ -4,10 +4,14 @@ 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) }
|
||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||
imp::init(argc, argv)
|
||||
}
|
||||
|
||||
/// One-time global cleanup.
|
||||
pub unsafe fn cleanup() { imp::cleanup() }
|
||||
pub unsafe fn cleanup() {
|
||||
imp::cleanup()
|
||||
}
|
||||
|
||||
/// Returns the command line arguments
|
||||
pub fn args() -> Args {
|
||||
|
@ -27,24 +31,32 @@ impl Args {
|
|||
|
||||
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() }
|
||||
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() }
|
||||
fn len(&self) -> usize {
|
||||
self.iter.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl DoubleEndedIterator for Args {
|
||||
fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
|
||||
fn next_back(&mut self) -> Option<OsString> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use crate::ptr;
|
||||
use super::Args;
|
||||
use crate::ffi::{CStr, OsString};
|
||||
use crate::marker::PhantomData;
|
||||
use crate::ptr;
|
||||
use libc;
|
||||
use super::Args;
|
||||
|
||||
use crate::sys_common::mutex::Mutex;
|
||||
|
||||
|
@ -65,21 +77,20 @@ mod imp {
|
|||
}
|
||||
|
||||
pub fn args() -> Args {
|
||||
Args {
|
||||
iter: clone().into_iter(),
|
||||
_dont_send_or_sync_me: PhantomData
|
||||
}
|
||||
Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData }
|
||||
}
|
||||
|
||||
fn clone() -> Vec<OsString> {
|
||||
unsafe {
|
||||
let _guard = LOCK.lock();
|
||||
let ret = (0..ARGC).map(|i| {
|
||||
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
|
||||
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||
}).collect();
|
||||
return ret
|
||||
let ret = (0..ARGC)
|
||||
.map(|i| {
|
||||
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
|
||||
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||
})
|
||||
.collect();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![cfg(not(test))]
|
||||
|
||||
use libc::{c_float, c_double};
|
||||
use libc::{c_double, c_float};
|
||||
|
||||
#[link_name = "m"]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn acos(n: c_double) -> c_double;
|
||||
pub fn acosf(n: c_float) -> c_float;
|
||||
pub fn asin(n: c_double) -> c_double;
|
||||
|
|
|
@ -2,15 +2,15 @@ use crate::cell::UnsafeCell;
|
|||
use crate::sys::mutex::{self, Mutex};
|
||||
use crate::time::Duration;
|
||||
|
||||
pub struct Condvar { inner: UnsafeCell<libc::pthread_cond_t> }
|
||||
pub struct Condvar {
|
||||
inner: UnsafeCell<libc::pthread_cond_t>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Condvar {}
|
||||
unsafe impl Sync for Condvar {}
|
||||
|
||||
const TIMESPEC_MAX: libc::timespec = libc::timespec {
|
||||
tv_sec: <libc::time_t>::max_value(),
|
||||
tv_nsec: 1_000_000_000 - 1,
|
||||
};
|
||||
const TIMESPEC_MAX: libc::timespec =
|
||||
libc::timespec { tv_sec: <libc::time_t>::max_value(), tv_nsec: 1_000_000_000 - 1 };
|
||||
|
||||
fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
|
||||
if value > <libc::time_t>::max_value() as u64 {
|
||||
|
@ -77,17 +77,14 @@ impl Condvar {
|
|||
.and_then(|s| s.checked_add(now.tv_sec));
|
||||
let nsec = nsec % 1_000_000_000;
|
||||
|
||||
let timeout = sec.map(|s| {
|
||||
libc::timespec { tv_sec: s, tv_nsec: nsec as _}
|
||||
}).unwrap_or(TIMESPEC_MAX);
|
||||
let timeout =
|
||||
sec.map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec as _ }).unwrap_or(TIMESPEC_MAX);
|
||||
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
|
||||
&timeout);
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), &timeout);
|
||||
assert!(r == libc::ETIMEDOUT || r == 0);
|
||||
r == 0
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = libc::pthread_cond_destroy(self.inner.get());
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
use crate::fs::{self, Permissions};
|
||||
use crate::io;
|
||||
use libc;
|
||||
use crate::path::Path;
|
||||
use crate::sys;
|
||||
use crate::sys_common::{FromInner, AsInner, AsInnerMut};
|
||||
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
|
||||
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
|
||||
use libc;
|
||||
|
||||
/// Unix-specific extensions to [`File`].
|
||||
///
|
||||
|
@ -112,8 +112,7 @@ pub trait FileExt {
|
|||
}
|
||||
}
|
||||
if !buf.is_empty() {
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
||||
"failed to fill whole buffer"))
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -196,8 +195,12 @@ pub trait FileExt {
|
|||
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
|
||||
while !buf.is_empty() {
|
||||
match self.write_at(buf, offset) {
|
||||
Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
|
||||
"failed to write whole buffer")),
|
||||
Ok(0) => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::WriteZero,
|
||||
"failed to write whole buffer",
|
||||
));
|
||||
}
|
||||
Ok(n) => {
|
||||
buf = &buf[n..];
|
||||
offset += n as u64
|
||||
|
@ -604,20 +607,48 @@ pub trait MetadataExt {
|
|||
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
impl MetadataExt for fs::Metadata {
|
||||
fn dev(&self) -> u64 { self.st_dev() }
|
||||
fn ino(&self) -> u64 { self.st_ino() }
|
||||
fn mode(&self) -> u32 { self.st_mode() }
|
||||
fn nlink(&self) -> u64 { self.st_nlink() }
|
||||
fn uid(&self) -> u32 { self.st_uid() }
|
||||
fn gid(&self) -> u32 { self.st_gid() }
|
||||
fn rdev(&self) -> u64 { self.st_rdev() }
|
||||
fn size(&self) -> u64 { self.st_size() }
|
||||
fn atime(&self) -> i64 { self.st_atime() }
|
||||
fn mtime(&self) -> i64 { self.st_mtime() }
|
||||
fn ctime(&self) -> i64 { self.st_ctime() }
|
||||
fn blksize(&self) -> u64 { self.st_blksize() }
|
||||
fn blocks(&self) -> u64 { self.st_blocks() }
|
||||
fn attrib(&self) -> u8 {self.st_attrib() }
|
||||
fn dev(&self) -> u64 {
|
||||
self.st_dev()
|
||||
}
|
||||
fn ino(&self) -> u64 {
|
||||
self.st_ino()
|
||||
}
|
||||
fn mode(&self) -> u32 {
|
||||
self.st_mode()
|
||||
}
|
||||
fn nlink(&self) -> u64 {
|
||||
self.st_nlink()
|
||||
}
|
||||
fn uid(&self) -> u32 {
|
||||
self.st_uid()
|
||||
}
|
||||
fn gid(&self) -> u32 {
|
||||
self.st_gid()
|
||||
}
|
||||
fn rdev(&self) -> u64 {
|
||||
self.st_rdev()
|
||||
}
|
||||
fn size(&self) -> u64 {
|
||||
self.st_size()
|
||||
}
|
||||
fn atime(&self) -> i64 {
|
||||
self.st_atime()
|
||||
}
|
||||
fn mtime(&self) -> i64 {
|
||||
self.st_mtime()
|
||||
}
|
||||
fn ctime(&self) -> i64 {
|
||||
self.st_ctime()
|
||||
}
|
||||
fn blksize(&self) -> u64 {
|
||||
self.st_blksize()
|
||||
}
|
||||
fn blocks(&self) -> u64 {
|
||||
self.st_blocks()
|
||||
}
|
||||
fn attrib(&self) -> u8 {
|
||||
self.st_attrib()
|
||||
}
|
||||
}
|
||||
|
||||
/// Unix-specific extensions for [`FileType`].
|
||||
|
@ -704,10 +735,18 @@ pub trait FileTypeExt {
|
|||
|
||||
#[stable(feature = "file_type_ext", since = "1.5.0")]
|
||||
impl FileTypeExt for fs::FileType {
|
||||
fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
|
||||
fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
|
||||
fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) }
|
||||
fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
|
||||
fn is_block_device(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFBLK)
|
||||
}
|
||||
fn is_char_device(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFCHR)
|
||||
}
|
||||
fn is_fifo(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFIFO)
|
||||
}
|
||||
fn is_socket(&self) -> bool {
|
||||
self.as_inner().is(libc::S_IFSOCK)
|
||||
}
|
||||
}
|
||||
|
||||
/// Unix-specific extension methods for [`fs::DirEntry`].
|
||||
|
@ -739,7 +778,9 @@ pub trait DirEntryExt {
|
|||
|
||||
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
|
||||
impl DirEntryExt for fs::DirEntry {
|
||||
fn ino(&self) -> u64 { self.as_inner().ino() }
|
||||
fn ino(&self) -> u64 {
|
||||
self.as_inner().ino()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new symbolic link on the filesystem.
|
||||
|
@ -766,8 +807,7 @@ impl DirEntryExt for fs::DirEntry {
|
|||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "symlink", since = "1.1.0")]
|
||||
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
|
||||
{
|
||||
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
|
||||
sys::fs::symlink(src.as_ref(), dst.as_ref())
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::fs;
|
||||
use crate::io;
|
||||
use crate::net;
|
||||
use crate::os::raw;
|
||||
use crate::sys;
|
||||
use crate::io;
|
||||
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
|
||||
use crate::net;
|
||||
|
||||
/// Raw file descriptors.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -84,47 +84,65 @@ impl IntoRawFd for fs::File {
|
|||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for io::Stdin {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDIN_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for io::Stdout {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDOUT_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for io::Stderr {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDERR_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||
impl<'a> AsRawFd for io::StdinLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDIN_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||
impl<'a> AsRawFd for io::StdoutLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDOUT_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||
impl<'a> AsRawFd for io::StderrLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
libc::STDERR_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRawFd for net::TcpStream {
|
||||
fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
*self.as_inner().socket().as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRawFd for net::TcpListener {
|
||||
fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
*self.as_inner().socket().as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRawFd for net::UdpSocket {
|
||||
fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
*self.as_inner().socket().as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "from_raw_os", since = "1.1.0")]
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
pub mod io;
|
||||
pub mod ffi;
|
||||
pub mod fs;
|
||||
pub mod raw;
|
||||
pub mod io;
|
||||
pub mod process;
|
||||
pub mod raw;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub mod prelude {
|
||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
|
||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(no_inline)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use super::ffi::{OsStrExt, OsStringExt};
|
||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt};
|
||||
#[doc(no_inline)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use super::fs::{FileTypeExt, MetadataExt, OpenOptionsExt, PermissionsExt};
|
||||
#[doc(no_inline)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use super::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::io;
|
||||
use crate::sys::vxworks::ext::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
|
||||
use crate::process;
|
||||
use crate::sys;
|
||||
use crate::sys_common::{AsInnerMut, AsInner, FromInner, IntoInner};
|
||||
use crate::sys::vxworks::ext::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
||||
|
||||
/// Unix-specific extensions to the [`process::Command`] builder.
|
||||
///
|
||||
|
@ -55,7 +55,8 @@ pub trait CommandExt {
|
|||
/// locations may not appear where intended.
|
||||
#[stable(feature = "process_pre_exec", since = "1.34.0")]
|
||||
unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
|
||||
where F: FnMut() -> io::Result<()> + Send + Sync + 'static;
|
||||
where
|
||||
F: FnMut() -> io::Result<()> + Send + Sync + 'static;
|
||||
|
||||
/// Schedules a closure to be run just before the `exec` function is
|
||||
/// invoked.
|
||||
|
@ -67,7 +68,8 @@ pub trait CommandExt {
|
|||
#[stable(feature = "process_exec", since = "1.15.0")]
|
||||
#[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
|
||||
fn before_exec<F>(&mut self, f: F) -> &mut process::Command
|
||||
where F: FnMut() -> io::Result<()> + Send + Sync + 'static
|
||||
where
|
||||
F: FnMut() -> io::Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
unsafe { self.pre_exec(f) }
|
||||
}
|
||||
|
@ -118,7 +120,8 @@ impl CommandExt for process::Command {
|
|||
}
|
||||
|
||||
unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
|
||||
where F: FnMut() -> io::Result<()> + Send + Sync + 'static
|
||||
where
|
||||
F: FnMut() -> io::Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
self.as_inner_mut().pre_exec(Box::new(f));
|
||||
self
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![cfg(target_thread_local)]
|
||||
#![unstable(feature = "thread_local_internals", issue = "0")]
|
||||
|
||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
||||
use crate::sys_common::thread_local::register_dtor_fallback;
|
||||
register_dtor_fallback(t, dtor);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
||||
|
||||
use crate::cmp;
|
||||
use crate::io::{self, Read, Initializer, IoSlice, IoSliceMut};
|
||||
use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
|
||||
use crate::mem;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys_common::AsInner;
|
||||
|
@ -25,7 +25,9 @@ impl FileDesc {
|
|||
FileDesc { fd: fd }
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> c_int { self.fd }
|
||||
pub fn raw(&self) -> c_int {
|
||||
self.fd
|
||||
}
|
||||
|
||||
/// Extracts the actual filedescriptor without closing it.
|
||||
pub fn into_raw(self) -> c_int {
|
||||
|
@ -36,18 +38,18 @@ impl FileDesc {
|
|||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::read(self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
cmp::min(buf.len(), max_len()))
|
||||
libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::readv(self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
||||
libc::readv(
|
||||
self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
@ -58,61 +60,69 @@ impl FileDesc {
|
|||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
unsafe fn cvt_pread(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
|
||||
-> io::Result<isize>
|
||||
{
|
||||
unsafe fn cvt_pread(
|
||||
fd: c_int,
|
||||
buf: *mut c_void,
|
||||
count: usize,
|
||||
offset: i64,
|
||||
) -> io::Result<isize> {
|
||||
use libc::pread;
|
||||
cvt(pread(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cvt_pread(self.fd,
|
||||
cvt_pread(
|
||||
self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
cmp::min(buf.len(), max_len()),
|
||||
offset as i64)
|
||||
offset as i64,
|
||||
)
|
||||
.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::write(self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
cmp::min(buf.len(), max_len()))
|
||||
libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::writev(self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
||||
libc::writev(
|
||||
self.fd,
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
unsafe fn cvt_pwrite(fd: c_int, buf: *const c_void, count: usize, offset: i64)
|
||||
-> io::Result<isize>
|
||||
{
|
||||
unsafe fn cvt_pwrite(
|
||||
fd: c_int,
|
||||
buf: *const c_void,
|
||||
count: usize,
|
||||
offset: i64,
|
||||
) -> io::Result<isize> {
|
||||
use libc::pwrite;
|
||||
cvt(pwrite(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cvt_pwrite(self.fd,
|
||||
cvt_pwrite(
|
||||
self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
cmp::min(buf.len(), max_len()),
|
||||
offset as i64)
|
||||
.map(|n| n as usize)
|
||||
offset as i64,
|
||||
)
|
||||
.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cloexec(&self) -> io::Result<bool> {
|
||||
unsafe {
|
||||
Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
|
||||
}
|
||||
unsafe { Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
|
||||
}
|
||||
|
||||
pub fn set_cloexec(&self) -> io::Result<()> {
|
||||
|
@ -139,23 +149,16 @@ impl FileDesc {
|
|||
pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> {
|
||||
unsafe {
|
||||
let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?;
|
||||
flags = if nonblocking {
|
||||
flags | libc::O_NONBLOCK
|
||||
} else {
|
||||
flags & !libc::O_NONBLOCK
|
||||
};
|
||||
flags = if nonblocking { flags | libc::O_NONBLOCK } else { flags & !libc::O_NONBLOCK };
|
||||
cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<FileDesc> {
|
||||
let fd = self.raw();
|
||||
match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) {
|
||||
Ok(newfd) => {
|
||||
Ok(FileDesc::new(newfd))
|
||||
}
|
||||
Ok(newfd) => Ok(FileDesc::new(newfd)),
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +176,9 @@ impl<'a> Read for &'a FileDesc {
|
|||
}
|
||||
|
||||
impl AsInner<c_int> for FileDesc {
|
||||
fn as_inner(&self) -> &c_int { &self.fd }
|
||||
fn as_inner(&self) -> &c_int {
|
||||
&self.fd
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FileDesc {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
// copies from linuxx
|
||||
use crate::ffi::{CString, CStr, OsString, OsStr};
|
||||
use crate::sys::vxworks::ext::ffi::OsStrExt;
|
||||
use crate::ffi::{CStr, CString, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, ErrorKind, SeekFrom, IoSlice, IoSliceMut};
|
||||
use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::mem;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::ptr;
|
||||
use crate::sync::Arc;
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::vxworks::ext::ffi::OsStrExt;
|
||||
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
||||
use crate::sys::{cvt, cvt_r};
|
||||
use crate::sys_common::{AsInner, FromInner};
|
||||
use libc::{self, c_int, mode_t, stat64, off_t};
|
||||
use libc::{ftruncate, lseek, dirent, readdir_r as readdir64_r, open};
|
||||
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
||||
use libc::{self, c_int, mode_t, off_t, stat64};
|
||||
use libc::{dirent, ftruncate, lseek, open, readdir_r as readdir64_r};
|
||||
pub struct File(FileDesc);
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -58,16 +58,24 @@ pub struct OpenOptions {
|
|||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct FilePermissions { mode: mode_t }
|
||||
pub struct FilePermissions {
|
||||
mode: mode_t,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct FileType { mode: mode_t }
|
||||
pub struct FileType {
|
||||
mode: mode_t,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DirBuilder { mode: mode_t }
|
||||
pub struct DirBuilder {
|
||||
mode: mode_t,
|
||||
}
|
||||
|
||||
impl FileAttr {
|
||||
pub fn size(&self) -> u64 { self.stat.st_size as u64 }
|
||||
pub fn size(&self) -> u64 {
|
||||
self.stat.st_size as u64
|
||||
}
|
||||
pub fn perm(&self) -> FilePermissions {
|
||||
FilePermissions { mode: (self.stat.st_mode as mode_t) }
|
||||
}
|
||||
|
@ -85,20 +93,23 @@ impl FileAttr {
|
|||
|
||||
pub fn accessed(&self) -> io::Result<SystemTime> {
|
||||
Ok(SystemTime::from(libc::timespec {
|
||||
tv_sec: self.stat.st_atime as libc::time_t,
|
||||
tv_nsec: 0, // hack - a proper fix would be better
|
||||
tv_sec: self.stat.st_atime as libc::time_t,
|
||||
tv_nsec: 0, // hack - a proper fix would be better
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn created(&self) -> io::Result<SystemTime> {
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
"creation time is not available on this platform currently"))
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"creation time is not available on this platform currently",
|
||||
))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl AsInner<stat64> for FileAttr {
|
||||
fn as_inner(&self) -> &stat64 { &self.stat }
|
||||
fn as_inner(&self) -> &stat64 {
|
||||
&self.stat
|
||||
}
|
||||
}
|
||||
|
||||
impl FilePermissions {
|
||||
|
@ -116,15 +127,25 @@ impl FilePermissions {
|
|||
self.mode |= 0o222;
|
||||
}
|
||||
}
|
||||
pub fn mode(&self) -> u32 { self.mode as u32 }
|
||||
pub fn mode(&self) -> u32 {
|
||||
self.mode as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl FileType {
|
||||
pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) }
|
||||
pub fn is_file(&self) -> bool { self.is(libc::S_IFREG) }
|
||||
pub fn is_symlink(&self) -> bool { self.is(libc::S_IFLNK) }
|
||||
pub fn is_dir(&self) -> bool {
|
||||
self.is(libc::S_IFDIR)
|
||||
}
|
||||
pub fn is_file(&self) -> bool {
|
||||
self.is(libc::S_IFREG)
|
||||
}
|
||||
pub fn is_symlink(&self) -> bool {
|
||||
self.is(libc::S_IFLNK)
|
||||
}
|
||||
|
||||
pub fn is(&self, mode: mode_t) -> bool { self.mode & libc::S_IFMT == mode }
|
||||
pub fn is(&self, mode: mode_t) -> bool {
|
||||
self.mode & libc::S_IFMT == mode
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<u32> for FilePermissions {
|
||||
|
@ -149,10 +170,7 @@ impl Iterator for ReadDir {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
let mut ret = DirEntry {
|
||||
entry: mem::zeroed(),
|
||||
dir: self.clone(),
|
||||
};
|
||||
let mut ret = DirEntry { entry: mem::zeroed(), dir: self.clone() };
|
||||
let mut entry_ptr = ptr::null_mut();
|
||||
loop {
|
||||
if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
|
||||
|
@ -163,13 +181,13 @@ impl Iterator for ReadDir {
|
|||
// (instead of looping forever)
|
||||
self.end_of_stream = true;
|
||||
}
|
||||
return Some(Err(Error::last_os_error()))
|
||||
return Some(Err(Error::last_os_error()));
|
||||
}
|
||||
if entry_ptr.is_null() {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
|
||||
return Some(Ok(ret))
|
||||
return Some(Ok(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,22 +203,20 @@ impl Drop for Dir {
|
|||
|
||||
impl DirEntry {
|
||||
pub fn path(&self) -> PathBuf {
|
||||
use crate::sys::vxworks::ext::ffi::OsStrExt;
|
||||
self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
|
||||
use crate::sys::vxworks::ext::ffi::OsStrExt;
|
||||
self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
|
||||
}
|
||||
|
||||
pub fn file_name(&self) -> OsString {
|
||||
OsStr::from_bytes(self.name_bytes()).to_os_string()
|
||||
}
|
||||
|
||||
|
||||
pub fn metadata(&self) -> io::Result<FileAttr> {
|
||||
lstat(&self.path())
|
||||
}
|
||||
|
||||
pub fn file_type(&self) -> io::Result<FileType> {
|
||||
lstat(&self.path()).map(|m| m.file_type())
|
||||
|
||||
}
|
||||
|
||||
pub fn ino(&self) -> u64 {
|
||||
|
@ -231,21 +247,35 @@ impl OpenOptions {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read(&mut self, read: bool) { self.read = read; }
|
||||
pub fn write(&mut self, write: bool) { self.write = write; }
|
||||
pub fn append(&mut self, append: bool) { self.append = append; }
|
||||
pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
|
||||
pub fn create(&mut self, create: bool) { self.create = create; }
|
||||
pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
|
||||
pub fn mode(&mut self, mode: u32) { self.mode = mode as mode_t; }
|
||||
pub fn read(&mut self, read: bool) {
|
||||
self.read = read;
|
||||
}
|
||||
pub fn write(&mut self, write: bool) {
|
||||
self.write = write;
|
||||
}
|
||||
pub fn append(&mut self, append: bool) {
|
||||
self.append = append;
|
||||
}
|
||||
pub fn truncate(&mut self, truncate: bool) {
|
||||
self.truncate = truncate;
|
||||
}
|
||||
pub fn create(&mut self, create: bool) {
|
||||
self.create = create;
|
||||
}
|
||||
pub fn create_new(&mut self, create_new: bool) {
|
||||
self.create_new = create_new;
|
||||
}
|
||||
pub fn mode(&mut self, mode: u32) {
|
||||
self.mode = mode as mode_t;
|
||||
}
|
||||
|
||||
fn get_access_mode(&self) -> io::Result<c_int> {
|
||||
match (self.read, self.write, self.append) {
|
||||
(true, false, false) => Ok(libc::O_RDONLY),
|
||||
(false, true, false) => Ok(libc::O_WRONLY),
|
||||
(true, true, false) => Ok(libc::O_RDWR),
|
||||
(false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND),
|
||||
(true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND),
|
||||
(true, false, false) => Ok(libc::O_RDONLY),
|
||||
(false, true, false) => Ok(libc::O_WRONLY),
|
||||
(true, true, false) => Ok(libc::O_RDWR),
|
||||
(false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND),
|
||||
(true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND),
|
||||
(false, false, false) => Err(Error::from_raw_os_error(libc::EINVAL)),
|
||||
}
|
||||
}
|
||||
|
@ -253,23 +283,25 @@ impl OpenOptions {
|
|||
fn get_creation_mode(&self) -> io::Result<c_int> {
|
||||
match (self.write, self.append) {
|
||||
(true, false) => {}
|
||||
(false, false) =>
|
||||
(false, false) => {
|
||||
if self.truncate || self.create || self.create_new {
|
||||
return Err(Error::from_raw_os_error(libc::EINVAL));
|
||||
},
|
||||
(_, true) =>
|
||||
}
|
||||
}
|
||||
(_, true) => {
|
||||
if self.truncate && !self.create_new {
|
||||
return Err(Error::from_raw_os_error(libc::EINVAL));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(match (self.create, self.truncate, self.create_new) {
|
||||
(false, false, false) => 0,
|
||||
(true, false, false) => libc::O_CREAT,
|
||||
(false, true, false) => libc::O_TRUNC,
|
||||
(true, true, false) => libc::O_CREAT | libc::O_TRUNC,
|
||||
(_, _, true) => libc::O_CREAT | libc::O_EXCL,
|
||||
})
|
||||
(false, false, false) => 0,
|
||||
(true, false, false) => libc::O_CREAT,
|
||||
(false, true, false) => libc::O_TRUNC,
|
||||
(true, true, false) => libc::O_CREAT | libc::O_TRUNC,
|
||||
(_, _, true) => libc::O_CREAT | libc::O_EXCL,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,21 +312,17 @@ impl File {
|
|||
}
|
||||
|
||||
pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
|
||||
let flags = libc::O_CLOEXEC |
|
||||
opts.get_access_mode()? |
|
||||
opts.get_creation_mode()? |
|
||||
(opts.custom_flags as c_int & !libc::O_ACCMODE);
|
||||
let fd = cvt_r(|| unsafe {
|
||||
open(path.as_ptr(), flags, opts.mode as c_int)
|
||||
})?;
|
||||
let flags = libc::O_CLOEXEC
|
||||
| opts.get_access_mode()?
|
||||
| opts.get_creation_mode()?
|
||||
| (opts.custom_flags as c_int & !libc::O_ACCMODE);
|
||||
let fd = cvt_r(|| unsafe { open(path.as_ptr(), flags, opts.mode as c_int) })?;
|
||||
Ok(File(FileDesc::new(fd)))
|
||||
}
|
||||
|
||||
pub fn file_attr(&self) -> io::Result<FileAttr> {
|
||||
let mut stat: stat64 = unsafe { mem::zeroed() };
|
||||
cvt(unsafe {
|
||||
::libc::fstat(self.0.raw(), &mut stat)
|
||||
})?;
|
||||
cvt(unsafe { ::libc::fstat(self.0.raw(), &mut stat) })?;
|
||||
Ok(FileAttr { stat: stat })
|
||||
}
|
||||
|
||||
|
@ -306,13 +334,13 @@ impl File {
|
|||
pub fn datasync(&self) -> io::Result<()> {
|
||||
cvt_r(|| unsafe { os_datasync(self.0.raw()) })?;
|
||||
return Ok(());
|
||||
unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) } //not supported
|
||||
unsafe fn os_datasync(fd: c_int) -> c_int {
|
||||
libc::fsync(fd)
|
||||
} //not supported
|
||||
}
|
||||
|
||||
pub fn truncate(&self, size: u64) -> io::Result<()> {
|
||||
return cvt_r(|| unsafe {
|
||||
ftruncate(self.0.raw(), size as off_t)
|
||||
}).map(|_| ());
|
||||
return cvt_r(|| unsafe { ftruncate(self.0.raw(), size as off_t) }).map(|_| ());
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
|
@ -339,7 +367,9 @@ impl File {
|
|||
self.0.write_at(buf, offset)
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> { Ok(()) }
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
|
||||
let (whence, pos) = match pos {
|
||||
|
@ -357,9 +387,13 @@ impl File {
|
|||
self.0.duplicate().map(File)
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
||||
pub fn fd(&self) -> &FileDesc {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
||||
pub fn into_fd(self) -> FileDesc {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
|
||||
cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
|
||||
|
@ -401,7 +435,7 @@ impl FromInner<c_int> for File {
|
|||
impl fmt::Debug for File {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fn get_path(fd: c_int) -> Option<PathBuf> {
|
||||
let mut buf = vec![0;libc::PATH_MAX as usize];
|
||||
let mut buf = vec![0; libc::PATH_MAX as usize];
|
||||
let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) };
|
||||
if n == -1 {
|
||||
return None;
|
||||
|
@ -419,7 +453,7 @@ impl fmt::Debug for File {
|
|||
libc::O_RDONLY => Some((true, false)),
|
||||
libc::O_RDWR => Some((true, true)),
|
||||
libc::O_WRONLY => Some((false, true)),
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,10 +479,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
|
|||
Err(Error::last_os_error())
|
||||
} else {
|
||||
let inner = InnerReadDir { dirp: Dir(ptr), root };
|
||||
Ok(ReadDir{
|
||||
inner: Arc::new(inner),
|
||||
end_of_stream: false,
|
||||
})
|
||||
Ok(ReadDir { inner: Arc::new(inner), end_of_stream: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -480,11 +511,7 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
|
|||
|
||||
pub fn remove_dir_all(path: &Path) -> io::Result<()> {
|
||||
let filetype = lstat(path)?.file_type();
|
||||
if filetype.is_symlink() {
|
||||
unlink(path)
|
||||
} else {
|
||||
remove_dir_all_recursive(path)
|
||||
}
|
||||
if filetype.is_symlink() { unlink(path) } else { remove_dir_all_recursive(path) }
|
||||
}
|
||||
|
||||
fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
|
||||
|
@ -506,11 +533,12 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
|
|||
let mut buf = Vec::with_capacity(256);
|
||||
|
||||
loop {
|
||||
let buf_read = cvt(unsafe {
|
||||
libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity())
|
||||
})? as usize;
|
||||
let buf_read =
|
||||
cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize;
|
||||
|
||||
unsafe { buf.set_len(buf_read); }
|
||||
unsafe {
|
||||
buf.set_len(buf_read);
|
||||
}
|
||||
|
||||
if buf_read != buf.capacity() {
|
||||
buf.shrink_to_fit();
|
||||
|
@ -542,18 +570,14 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
|
|||
pub fn stat(p: &Path) -> io::Result<FileAttr> {
|
||||
let p = cstr(p)?;
|
||||
let mut stat: stat64 = unsafe { mem::zeroed() };
|
||||
cvt(unsafe {
|
||||
libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _)
|
||||
})?;
|
||||
cvt(unsafe { libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?;
|
||||
Ok(FileAttr { stat })
|
||||
}
|
||||
|
||||
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
|
||||
let p = cstr(p)?;
|
||||
let mut stat: stat64 = unsafe { mem::zeroed() };
|
||||
cvt(unsafe {
|
||||
::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
|
||||
})?;
|
||||
cvt(unsafe { ::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?;
|
||||
Ok(FileAttr { stat })
|
||||
}
|
||||
|
||||
|
@ -564,7 +588,7 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
|||
unsafe {
|
||||
let r = libc::realpath(path.as_ptr(), ptr::null_mut());
|
||||
if r.is_null() {
|
||||
return Err(io::Error::last_os_error())
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
buf = CStr::from_ptr(r).to_bytes().to_vec();
|
||||
libc::free(r as *mut _);
|
||||
|
@ -575,8 +599,10 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
|||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
use crate::fs::File;
|
||||
if !from.is_file() {
|
||||
return Err(Error::new(ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file"))
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file",
|
||||
));
|
||||
}
|
||||
|
||||
let mut reader = File::open(from)?;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::marker::PhantomData;
|
||||
use crate::slice;
|
||||
|
||||
use libc::{iovec, c_void};
|
||||
use libc::{c_void, iovec};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct IoSlice<'a> {
|
||||
|
@ -13,10 +13,7 @@ impl<'a> IoSlice<'a> {
|
|||
#[inline]
|
||||
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||
IoSlice {
|
||||
vec: iovec {
|
||||
iov_base: buf.as_ptr() as *mut u8 as *mut c_void,
|
||||
iov_len: buf.len()
|
||||
},
|
||||
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +32,7 @@ impl<'a> IoSlice<'a> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
||||
}
|
||||
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,10 +45,7 @@ impl<'a> IoSliceMut<'a> {
|
|||
#[inline]
|
||||
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||
IoSliceMut {
|
||||
vec: iovec {
|
||||
iov_base: buf.as_mut_ptr() as *mut c_void,
|
||||
iov_len: buf.len()
|
||||
},
|
||||
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -72,15 +64,11 @@ impl<'a> IoSliceMut<'a> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
||||
}
|
||||
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
||||
}
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,10 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
|||
libc::memchr(
|
||||
haystack.as_ptr() as *const libc::c_void,
|
||||
needle as libc::c_int,
|
||||
haystack.len())
|
||||
haystack.len(),
|
||||
)
|
||||
};
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(p as usize - (haystack.as_ptr() as usize))
|
||||
}
|
||||
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
|
||||
}
|
||||
|
||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
use crate::io::ErrorKind;
|
||||
|
||||
pub use crate::os::vxworks as platform;
|
||||
pub use self::rand::hashmap_random_keys;
|
||||
pub use crate::os::vxworks as platform;
|
||||
pub use libc::strlen;
|
||||
|
||||
pub mod alloc;
|
||||
|
@ -16,8 +16,8 @@ pub mod ext;
|
|||
pub mod fast_thread_local;
|
||||
pub mod fd;
|
||||
pub mod fs;
|
||||
pub mod memchr;
|
||||
pub mod io;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
|
@ -27,10 +27,10 @@ pub mod process;
|
|||
pub mod rand;
|
||||
pub mod rwlock;
|
||||
pub mod stack_overflow;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
pub mod thread_local;
|
||||
pub mod time;
|
||||
pub mod stdio;
|
||||
|
||||
pub use crate::sys_common::os_str_bytes as os_str;
|
||||
|
||||
|
@ -47,7 +47,7 @@ pub fn init() {
|
|||
reset_sigpipe();
|
||||
}
|
||||
|
||||
unsafe fn reset_sigpipe() { }
|
||||
unsafe fn reset_sigpipe() {}
|
||||
}
|
||||
|
||||
pub use libc::signal;
|
||||
|
@ -71,8 +71,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
|||
// These two constants can have the same value on some systems,
|
||||
// but different values on others, so we can't use a match
|
||||
// clause
|
||||
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
|
||||
ErrorKind::WouldBlock,
|
||||
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => ErrorKind::WouldBlock,
|
||||
|
||||
_ => ErrorKind::Other,
|
||||
}
|
||||
|
@ -94,16 +93,13 @@ macro_rules! impl_is_minus_one {
|
|||
impl_is_minus_one! { i8 i16 i32 i64 isize }
|
||||
|
||||
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
|
||||
if t.is_minus_one() {
|
||||
Err(crate::io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(t)
|
||||
}
|
||||
if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) }
|
||||
}
|
||||
|
||||
pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
|
||||
where T: IsMinusOne,
|
||||
F: FnMut() -> T
|
||||
where
|
||||
T: IsMinusOne,
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
loop {
|
||||
match cvt(f()) {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use crate::cell::UnsafeCell;
|
||||
use crate::mem::MaybeUninit;
|
||||
|
||||
pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
|
||||
pub struct Mutex {
|
||||
inner: UnsafeCell<libc::pthread_mutex_t>,
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t {
|
||||
|
@ -82,7 +84,9 @@ impl Mutex {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ReentrantMutex { inner: UnsafeCell<libc::pthread_mutex_t> }
|
||||
pub struct ReentrantMutex {
|
||||
inner: UnsafeCell<libc::pthread_mutex_t>,
|
||||
}
|
||||
|
||||
unsafe impl Send for ReentrantMutex {}
|
||||
unsafe impl Sync for ReentrantMutex {}
|
||||
|
@ -96,8 +100,8 @@ impl ReentrantMutex {
|
|||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||
let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
|
||||
libc::PTHREAD_MUTEX_RECURSIVE);
|
||||
let result =
|
||||
libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_RECURSIVE);
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
|
||||
debug_assert_eq!(result, 0);
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use crate::cmp;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
use crate::io::{IoSlice, IoSliceMut};
|
||||
use libc::{self, c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
|
||||
use crate::mem;
|
||||
use crate::net::{SocketAddr, Shutdown};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::str;
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::{Duration, Instant};
|
||||
use crate::cmp;
|
||||
use libc::{self, c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
|
||||
|
||||
pub use crate::sys::{cvt, cvt_r};
|
||||
|
||||
|
@ -18,7 +18,6 @@ pub extern crate libc as netc;
|
|||
|
||||
pub type wrlen_t = size_t;
|
||||
|
||||
|
||||
const SOCK_CLOEXEC: c_int = 0;
|
||||
const SO_NOSIGPIPE: c_int = 0;
|
||||
|
||||
|
@ -28,23 +27,23 @@ pub fn init() {}
|
|||
|
||||
pub fn cvt_gai(err: c_int) -> io::Result<()> {
|
||||
if err == 0 {
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
|
||||
on_resolver_failure();
|
||||
|
||||
if err == EAI_SYSTEM {
|
||||
return Err(io::Error::last_os_error())
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let detail = unsafe {
|
||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
|
||||
.to_owned()
|
||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap().to_owned()
|
||||
};
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
&format!("failed to lookup address information: {}",
|
||||
detail)[..]))
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
&format!("failed to lookup address information: {}", detail)[..],
|
||||
))
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
|
@ -67,7 +66,7 @@ impl Socket {
|
|||
}
|
||||
|
||||
pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> {
|
||||
unimplemented!();
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
|
||||
|
@ -85,15 +84,13 @@ impl Socket {
|
|||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
let mut pollfd = libc::pollfd {
|
||||
fd: self.0.raw(),
|
||||
events: libc::POLLOUT,
|
||||
revents: 0,
|
||||
};
|
||||
let mut pollfd = libc::pollfd { fd: self.0.raw(), events: libc::POLLOUT, revents: 0 };
|
||||
|
||||
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
|
||||
let start = Instant::now();
|
||||
|
@ -105,7 +102,8 @@ impl Socket {
|
|||
}
|
||||
|
||||
let timeout = timeout - elapsed;
|
||||
let mut timeout = timeout.as_secs()
|
||||
let mut timeout = timeout
|
||||
.as_secs()
|
||||
.saturating_mul(1_000)
|
||||
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
||||
if timeout == 0 {
|
||||
|
@ -126,10 +124,9 @@ impl Socket {
|
|||
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
||||
// for POLLHUP rather than read readiness
|
||||
if pollfd.revents & libc::POLLHUP != 0 {
|
||||
let e = self.take_error()?
|
||||
.unwrap_or_else(|| {
|
||||
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
||||
});
|
||||
let e = self.take_error()?.unwrap_or_else(|| {
|
||||
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
||||
});
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
|
@ -139,11 +136,8 @@ impl Socket {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
|
||||
-> io::Result<Socket> {
|
||||
let fd = cvt_r(|| unsafe {
|
||||
libc::accept(self.0.raw(), storage, len)
|
||||
})?;
|
||||
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
|
||||
let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?;
|
||||
let fd = FileDesc::new(fd);
|
||||
fd.set_cloexec()?;
|
||||
Ok(Socket(fd))
|
||||
|
@ -155,10 +149,7 @@ impl Socket {
|
|||
|
||||
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::recv(self.0.raw(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
flags)
|
||||
libc::recv(self.0.raw(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
@ -175,18 +166,23 @@ impl Socket {
|
|||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
|
||||
-> io::Result<(usize, SocketAddr)> {
|
||||
fn recv_from_with_flags(
|
||||
&self,
|
||||
buf: &mut [u8],
|
||||
flags: c_int,
|
||||
) -> io::Result<(usize, SocketAddr)> {
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
|
||||
|
||||
let n = cvt(unsafe {
|
||||
libc::recvfrom(self.0.raw(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
flags,
|
||||
&mut storage as *mut _ as *mut _,
|
||||
&mut addrlen)
|
||||
libc::recvfrom(
|
||||
self.0.raw(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
flags,
|
||||
&mut storage as *mut _ as *mut _,
|
||||
&mut addrlen,
|
||||
)
|
||||
})?;
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
}
|
||||
|
@ -211,8 +207,10 @@ impl Socket {
|
|||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout"));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
|
||||
let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
|
||||
|
@ -229,12 +227,7 @@ impl Socket {
|
|||
}
|
||||
timeout
|
||||
}
|
||||
None => {
|
||||
libc::timeval {
|
||||
tv_sec: 0,
|
||||
tv_usec: 0,
|
||||
}
|
||||
}
|
||||
None => libc::timeval { tv_sec: 0, tv_usec: 0 },
|
||||
};
|
||||
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
||||
}
|
||||
|
@ -276,24 +269,26 @@ impl Socket {
|
|||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
|
||||
if raw == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(io::Error::from_raw_os_error(raw as i32)))
|
||||
}
|
||||
if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<c_int> for Socket {
|
||||
fn as_inner(&self) -> &c_int { self.0.as_inner() }
|
||||
fn as_inner(&self) -> &c_int {
|
||||
self.0.as_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<c_int> for Socket {
|
||||
fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
|
||||
fn from_inner(fd: c_int) -> Socket {
|
||||
Socket(FileDesc::new(fd))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<c_int> for Socket {
|
||||
fn into_inner(self) -> c_int { self.0.into_raw() }
|
||||
fn into_inner(self) -> c_int {
|
||||
self.0.into_raw()
|
||||
}
|
||||
}
|
||||
|
||||
// In versions of glibc prior to 2.26, there's a bug where the DNS resolver
|
||||
|
@ -314,7 +309,7 @@ impl IntoInner<c_int> for Socket {
|
|||
// believe it's thread-safe).
|
||||
#[cfg(target_env = "gnu")]
|
||||
fn on_resolver_failure() {
|
||||
/*
|
||||
/*
|
||||
use crate::sys;
|
||||
|
||||
// If the version fails to parse, we treat it the same as "not glibc".
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::path::Prefix;
|
||||
use crate::ffi::OsStr;
|
||||
use crate::path::Prefix;
|
||||
|
||||
#[inline]
|
||||
pub fn is_sep_byte(b: u8) -> bool {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use libc::{self /*, c_int apparently not used? */};
|
||||
use crate::mem;
|
||||
use crate::sync::atomic::{AtomicBool};
|
||||
use crate::sync::atomic::AtomicBool;
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys::{cvt, cvt_r};
|
||||
use libc::{self /*, c_int apparently not used? */};
|
||||
|
||||
pub struct AnonPipe(FileDesc);
|
||||
|
||||
|
@ -25,29 +25,29 @@ impl AnonPipe {
|
|||
self.0.read(buf)
|
||||
}
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
||||
pub fn fd(&self) -> &FileDesc {
|
||||
&self.0
|
||||
}
|
||||
pub fn into_fd(self) -> FileDesc {
|
||||
self.0
|
||||
}
|
||||
pub fn diverge(&self) -> ! {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe,
|
||||
v1: &mut Vec<u8>,
|
||||
p2: AnonPipe,
|
||||
v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
|
||||
pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
// Set both pipes into nonblocking mode as we're gonna be reading from both
|
||||
// in the `select` loop below, and we wouldn't want one to block the other!
|
||||
let p1 = p1.into_fd();
|
||||
|
@ -83,8 +83,9 @@ pub fn read2(p1: AnonPipe,
|
|||
match fd.read_to_end(dst) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) => {
|
||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
|
||||
e.raw_os_error() == Some(libc::EAGAIN) {
|
||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK)
|
||||
|| e.raw_os_error() == Some(libc::EAGAIN)
|
||||
{
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(e)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
|
||||
pub use self::process_common::{Command, ExitCode, ExitStatus, Stdio, StdioPipes};
|
||||
pub use self::process_inner::Process;
|
||||
pub use crate::ffi::OsString as EnvKey;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::os::unix::prelude::*;
|
||||
|
||||
use crate::ffi::{OsString, OsStr, CString, CStr};
|
||||
use crate::collections::BTreeMap;
|
||||
use crate::ffi::{CStr, CString, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::ptr;
|
||||
|
@ -8,9 +9,8 @@ use crate::sys::fd::FileDesc;
|
|||
use crate::sys::fs::{File, OpenOptions};
|
||||
use crate::sys::pipe::{self, AnonPipe};
|
||||
use crate::sys_common::process::CommandEnv;
|
||||
use crate::collections::BTreeMap;
|
||||
|
||||
use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
|
||||
use libc::{c_char, c_int, gid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Command
|
||||
|
@ -150,10 +150,7 @@ impl Command {
|
|||
&mut self.closures
|
||||
}
|
||||
|
||||
pub unsafe fn pre_exec(
|
||||
&mut self,
|
||||
_f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>,
|
||||
) {
|
||||
pub unsafe fn pre_exec(&mut self, _f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
|
||||
// Fork() is not supported in vxWorks so no way to run the closure in the new procecss.
|
||||
unimplemented!();
|
||||
}
|
||||
|
@ -183,26 +180,21 @@ impl Command {
|
|||
self.env.have_changed_path()
|
||||
}
|
||||
|
||||
pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
|
||||
-> io::Result<(StdioPipes, ChildPipes)> {
|
||||
pub fn setup_io(
|
||||
&self,
|
||||
default: Stdio,
|
||||
needs_stdin: bool,
|
||||
) -> io::Result<(StdioPipes, ChildPipes)> {
|
||||
let null = Stdio::Null;
|
||||
let default_stdin = if needs_stdin {&default} else {&null};
|
||||
let default_stdin = if needs_stdin { &default } else { &null };
|
||||
let stdin = self.stdin.as_ref().unwrap_or(default_stdin);
|
||||
let stdout = self.stdout.as_ref().unwrap_or(&default);
|
||||
let stderr = self.stderr.as_ref().unwrap_or(&default);
|
||||
let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;
|
||||
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
|
||||
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
|
||||
let ours = StdioPipes {
|
||||
stdin: our_stdin,
|
||||
stdout: our_stdout,
|
||||
stderr: our_stderr,
|
||||
};
|
||||
let theirs = ChildPipes {
|
||||
stdin: their_stdin,
|
||||
stdout: their_stdout,
|
||||
stderr: their_stderr,
|
||||
};
|
||||
let ours = StdioPipes { stdin: our_stdin, stdout: our_stdout, stderr: our_stderr };
|
||||
let theirs = ChildPipes { stdin: their_stdin, stdout: their_stdout, stderr: their_stderr };
|
||||
Ok((ours, theirs))
|
||||
}
|
||||
}
|
||||
|
@ -217,21 +209,21 @@ fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString {
|
|||
// Helper type to manage ownership of the strings within a C-style array.
|
||||
pub struct CStringArray {
|
||||
items: Vec<CString>,
|
||||
ptrs: Vec<*const c_char>
|
||||
ptrs: Vec<*const c_char>,
|
||||
}
|
||||
|
||||
impl CStringArray {
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
let mut result = CStringArray {
|
||||
items: Vec::with_capacity(capacity),
|
||||
ptrs: Vec::with_capacity(capacity+1)
|
||||
ptrs: Vec::with_capacity(capacity + 1),
|
||||
};
|
||||
result.ptrs.push(ptr::null());
|
||||
result
|
||||
}
|
||||
pub fn push(&mut self, item: CString) {
|
||||
let l = self.ptrs.len();
|
||||
self.ptrs[l-1] = item.as_ptr();
|
||||
self.ptrs[l - 1] = item.as_ptr();
|
||||
self.ptrs.push(ptr::null());
|
||||
self.items.push(item);
|
||||
}
|
||||
|
@ -262,12 +254,9 @@ fn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStr
|
|||
}
|
||||
|
||||
impl Stdio {
|
||||
pub fn to_child_stdio(&self, readable: bool)
|
||||
-> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
||||
pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
||||
match *self {
|
||||
Stdio::Inherit => {
|
||||
Ok((ChildStdio::Inherit, None))
|
||||
},
|
||||
Stdio::Inherit => Ok((ChildStdio::Inherit, None)),
|
||||
|
||||
// Make sure that the source descriptors are not an stdio
|
||||
// descriptor, otherwise the order which we set the child's
|
||||
|
@ -286,11 +275,7 @@ impl Stdio {
|
|||
|
||||
Stdio::MakePipe => {
|
||||
let (reader, writer) = pipe::anon_pipe()?;
|
||||
let (ours, theirs) = if readable {
|
||||
(writer, reader)
|
||||
} else {
|
||||
(reader, writer)
|
||||
};
|
||||
let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) };
|
||||
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
|
||||
}
|
||||
|
||||
|
@ -298,9 +283,7 @@ impl Stdio {
|
|||
let mut opts = OpenOptions::new();
|
||||
opts.read(readable);
|
||||
opts.write(!readable);
|
||||
let path = unsafe {
|
||||
CStr::from_ptr("/null\0".as_ptr() as *const _)
|
||||
};
|
||||
let path = unsafe { CStr::from_ptr("/null\0".as_ptr() as *const _) };
|
||||
let fd = File::open_c(&path, &opts)?;
|
||||
Ok((ChildStdio::Owned(fd.into_fd()), None))
|
||||
}
|
||||
|
@ -350,7 +333,8 @@ impl ExitStatus {
|
|||
}
|
||||
|
||||
fn exited(&self) -> bool {
|
||||
/*unsafe*/ { libc::WIFEXITED(self.0) }
|
||||
/*unsafe*/
|
||||
{ libc::WIFEXITED(self.0) }
|
||||
}
|
||||
|
||||
pub fn success(&self) -> bool {
|
||||
|
|
|
@ -4,17 +4,16 @@ use crate::slice;
|
|||
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
let mut v = (0, 0);
|
||||
unsafe {
|
||||
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
|
||||
mem::size_of_val(&v));
|
||||
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, mem::size_of_val(&v));
|
||||
imp::fill_bytes(view);
|
||||
}
|
||||
return v
|
||||
return v;
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use libc;
|
||||
use crate::io;
|
||||
use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
|
||||
use libc;
|
||||
|
||||
pub fn fill_bytes(v: &mut [u8]) {
|
||||
static RNG_INIT: AtomicBool = AtomicBool::new(false);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use libc;
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use libc;
|
||||
|
||||
pub struct RWLock {
|
||||
inner: UnsafeCell<libc::pthread_rwlock_t>,
|
||||
|
@ -29,7 +29,7 @@ impl RWLock {
|
|||
if r == 0 {
|
||||
self.raw_unlock();
|
||||
}
|
||||
panic!("rwlock read lock would result in deadlock");
|
||||
panic!("rwlock read lock would result in deadlock");
|
||||
} else {
|
||||
debug_assert_eq!(r, 0);
|
||||
self.num_readers.fetch_add(1, Ordering::Relaxed);
|
||||
|
@ -57,12 +57,14 @@ impl RWLock {
|
|||
let r = libc::pthread_rwlock_wrlock(self.inner.get());
|
||||
// See comments above for why we check for EDEADLK and write_locked. We
|
||||
// also need to check that num_readers is 0.
|
||||
if r == libc::EDEADLK || *self.write_locked.get() ||
|
||||
self.num_readers.load(Ordering::Relaxed) != 0 {
|
||||
if r == libc::EDEADLK
|
||||
|| *self.write_locked.get()
|
||||
|| self.num_readers.load(Ordering::Relaxed) != 0
|
||||
{
|
||||
if r == 0 {
|
||||
self.raw_unlock();
|
||||
}
|
||||
panic!("rwlock write lock would result in deadlock");
|
||||
panic!("rwlock write lock would result in deadlock");
|
||||
} else {
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
@ -80,8 +82,8 @@ impl RWLock {
|
|||
*self.write_locked.get() = true;
|
||||
true
|
||||
}
|
||||
} else {
|
||||
false
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +100,7 @@ impl RWLock {
|
|||
self.raw_unlock();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) {
|
||||
debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0);
|
||||
debug_assert!(*self.write_locked.get());
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#![cfg_attr(test, allow(dead_code))]
|
||||
|
||||
use self::imp::{make_handler, drop_handler};
|
||||
use self::imp::{drop_handler, make_handler};
|
||||
|
||||
pub use self::imp::cleanup;
|
||||
pub use self::imp::init;
|
||||
|
||||
pub struct Handler {
|
||||
_data: *mut libc::c_void
|
||||
_data: *mut libc::c_void,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
|
@ -26,16 +26,13 @@ impl Drop for Handler {
|
|||
mod imp {
|
||||
use crate::ptr;
|
||||
|
||||
pub unsafe fn init() {
|
||||
}
|
||||
pub unsafe fn init() {}
|
||||
|
||||
pub unsafe fn cleanup() {
|
||||
}
|
||||
pub unsafe fn cleanup() {}
|
||||
|
||||
pub unsafe fn make_handler() -> super::Handler {
|
||||
super::Handler { _data: ptr::null_mut() }
|
||||
}
|
||||
|
||||
pub unsafe fn drop_handler(_handler: &mut super::Handler) {
|
||||
}
|
||||
pub unsafe fn drop_handler(_handler: &mut super::Handler) {}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ pub struct Stdout(());
|
|||
pub struct Stderr(());
|
||||
|
||||
impl Stdin {
|
||||
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
|
||||
pub fn new() -> io::Result<Stdin> {
|
||||
Ok(Stdin(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for Stdin {
|
||||
|
@ -19,7 +21,9 @@ impl io::Read for Stdin {
|
|||
}
|
||||
|
||||
impl Stdout {
|
||||
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
|
||||
pub fn new() -> io::Result<Stdout> {
|
||||
Ok(Stdout(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stdout {
|
||||
|
@ -36,7 +40,9 @@ impl io::Write for Stdout {
|
|||
}
|
||||
|
||||
impl Stderr {
|
||||
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
|
||||
pub fn new() -> io::Result<Stderr> {
|
||||
Ok(Stderr(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stderr {
|
||||
|
|
|
@ -21,15 +21,16 @@ unsafe impl Sync for Thread {}
|
|||
|
||||
// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc,
|
||||
// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
|
||||
unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
|
||||
stack_size: libc::size_t) -> libc::c_int {
|
||||
unsafe fn pthread_attr_setstacksize(
|
||||
attr: *mut libc::pthread_attr_t,
|
||||
stack_size: libc::size_t,
|
||||
) -> libc::c_int {
|
||||
libc::pthread_attr_setstacksize(attr, stack_size)
|
||||
}
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread> {
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
let p = box p;
|
||||
let mut native: libc::pthread_t = mem::zeroed();
|
||||
let mut attr: libc::pthread_attr_t = mem::zeroed();
|
||||
|
@ -37,8 +38,7 @@ impl Thread {
|
|||
|
||||
let stack_size = cmp::max(stack, min_stack_size(&attr));
|
||||
|
||||
match pthread_attr_setstacksize(&mut attr,
|
||||
stack_size) {
|
||||
match pthread_attr_setstacksize(&mut attr, stack_size) {
|
||||
0 => {}
|
||||
n => {
|
||||
assert_eq!(n, libc::EINVAL);
|
||||
|
@ -47,15 +47,13 @@ impl Thread {
|
|||
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
||||
// Round up to the nearest page and try again.
|
||||
let page_size = os::page_size();
|
||||
let stack_size = (stack_size + page_size - 1) &
|
||||
(-(page_size as isize - 1) as usize - 1);
|
||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
|
||||
stack_size), 0);
|
||||
let stack_size =
|
||||
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
|
||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
|
||||
}
|
||||
};
|
||||
|
||||
let ret = libc::pthread_create(&mut native, &attr, thread_start,
|
||||
&*p as *const _ as *mut _);
|
||||
let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
|
||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||
|
||||
return if ret != 0 {
|
||||
|
@ -65,8 +63,10 @@ impl Thread {
|
|||
Ok(Thread { id: native })
|
||||
};
|
||||
|
||||
extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
||||
unsafe { start_thread(main as *mut u8); }
|
||||
extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
||||
unsafe {
|
||||
start_thread(main as *mut u8);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
@ -108,12 +108,13 @@ impl Thread {
|
|||
unsafe {
|
||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||
mem::forget(self);
|
||||
assert!(ret == 0,
|
||||
"failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> libc::pthread_t { self.id }
|
||||
pub fn id(&self) -> libc::pthread_t {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn into_id(self) -> libc::pthread_t {
|
||||
let id = self.id;
|
||||
|
@ -133,8 +134,12 @@ impl Drop for Thread {
|
|||
pub mod guard {
|
||||
use crate::ops::Range;
|
||||
pub type Guard = Range<usize>;
|
||||
pub unsafe fn current() -> Option<Guard> { None }
|
||||
pub unsafe fn init() -> Option<Guard> { None }
|
||||
pub unsafe fn current() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
pub unsafe fn init() -> Option<Guard> {
|
||||
None
|
||||
}
|
||||
pub unsafe fn deinit() {}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::mem;
|
|||
pub type Key = libc::pthread_key_t;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||
let mut key = 0;
|
||||
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
||||
key
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::cmp::Ordering;
|
||||
use libc;
|
||||
use crate::time::Duration;
|
||||
use ::core::hash::{Hash, Hasher};
|
||||
use libc;
|
||||
|
||||
pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
|
||||
use crate::convert::TryInto;
|
||||
|
@ -15,20 +15,21 @@ struct Timespec {
|
|||
|
||||
impl Timespec {
|
||||
const fn zero() -> Timespec {
|
||||
Timespec {
|
||||
t: libc::timespec { tv_sec: 0, tv_nsec: 0 },
|
||||
}
|
||||
Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
|
||||
}
|
||||
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
||||
if self >= other {
|
||||
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
||||
Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
|
||||
(self.t.tv_nsec - other.t.tv_nsec) as u32)
|
||||
} else {
|
||||
Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
|
||||
other.t.tv_nsec as u32)
|
||||
})
|
||||
Duration::new(
|
||||
(self.t.tv_sec - other.t.tv_sec) as u64,
|
||||
(self.t.tv_nsec - other.t.tv_nsec) as u32,
|
||||
)
|
||||
} else {
|
||||
Duration::new(
|
||||
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
||||
)
|
||||
})
|
||||
} else {
|
||||
match other.sub_timespec(self) {
|
||||
Ok(d) => Err(d),
|
||||
|
@ -51,12 +52,7 @@ impl Timespec {
|
|||
nsec -= NSEC_PER_SEC as u32;
|
||||
secs = secs.checked_add(1)?;
|
||||
}
|
||||
Some(Timespec {
|
||||
t: libc::timespec {
|
||||
tv_sec: secs,
|
||||
tv_nsec: nsec as _,
|
||||
},
|
||||
})
|
||||
Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||
}
|
||||
|
||||
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
|
||||
|
@ -72,12 +68,7 @@ impl Timespec {
|
|||
nsec += NSEC_PER_SEC as i32;
|
||||
secs = secs.checked_sub(1)?;
|
||||
}
|
||||
Some(Timespec {
|
||||
t: libc::timespec {
|
||||
tv_sec: secs,
|
||||
tv_nsec: nsec as _,
|
||||
},
|
||||
})
|
||||
Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,16 +95,16 @@ impl Ord for Timespec {
|
|||
}
|
||||
|
||||
impl Hash for Timespec {
|
||||
fn hash<H : Hasher>(&self, state: &mut H) {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.t.tv_sec.hash(state);
|
||||
self.t.tv_nsec.hash(state);
|
||||
}
|
||||
}
|
||||
mod inner {
|
||||
use crate::fmt;
|
||||
use libc;
|
||||
use crate::sys::cvt;
|
||||
use crate::time::Duration;
|
||||
use libc;
|
||||
|
||||
use super::Timespec;
|
||||
|
||||
|
@ -127,14 +118,8 @@ mod inner {
|
|||
t: Timespec,
|
||||
}
|
||||
|
||||
pub const UNIX_EPOCH: SystemTime = SystemTime {
|
||||
t: Timespec {
|
||||
t: libc::timespec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
pub const UNIX_EPOCH: SystemTime =
|
||||
SystemTime { t: Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } } };
|
||||
|
||||
impl Instant {
|
||||
pub fn now() -> Instant {
|
||||
|
@ -142,9 +127,7 @@ mod inner {
|
|||
}
|
||||
|
||||
pub const fn zero() -> Instant {
|
||||
Instant {
|
||||
t: Timespec::zero(),
|
||||
}
|
||||
Instant { t: Timespec::zero() }
|
||||
}
|
||||
|
||||
pub fn actually_monotonic() -> bool {
|
||||
|
@ -167,9 +150,9 @@ mod inner {
|
|||
impl fmt::Debug for Instant {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Instant")
|
||||
.field("tv_sec", &self.t.t.tv_sec)
|
||||
.field("tv_nsec", &self.t.t.tv_nsec)
|
||||
.finish()
|
||||
.field("tv_sec", &self.t.t.tv_sec)
|
||||
.field("tv_nsec", &self.t.t.tv_nsec)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,8 +161,7 @@ mod inner {
|
|||
SystemTime { t: now(libc::CLOCK_REALTIME) }
|
||||
}
|
||||
|
||||
pub fn sub_time(&self, other: &SystemTime)
|
||||
-> Result<Duration, Duration> {
|
||||
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||
self.t.sub_timespec(&other.t)
|
||||
}
|
||||
|
||||
|
@ -201,24 +183,17 @@ mod inner {
|
|||
impl fmt::Debug for SystemTime {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("SystemTime")
|
||||
.field("tv_sec", &self.t.t.tv_sec)
|
||||
.field("tv_nsec", &self.t.t.tv_nsec)
|
||||
.finish()
|
||||
.field("tv_sec", &self.t.t.tv_sec)
|
||||
.field("tv_nsec", &self.t.t.tv_nsec)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub type clock_t = libc::c_int;
|
||||
|
||||
fn now(clock: clock_t) -> Timespec {
|
||||
let mut t = Timespec {
|
||||
t: libc::timespec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
}
|
||||
};
|
||||
cvt(unsafe {
|
||||
libc::clock_gettime(clock, &mut t.t)
|
||||
}).unwrap();
|
||||
let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
|
||||
cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
|
||||
t
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue