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:
@@ -18,9 +18,7 @@ pub fn errno() -> i32 {
|
|||||||
pub fn error_string(errno: i32) -> String {
|
pub fn error_string(errno: i32) -> String {
|
||||||
// cloudlibc's strerror() is guaranteed to be thread-safe. There is
|
// cloudlibc's strerror() is guaranteed to be thread-safe. There is
|
||||||
// thus no need to use strerror_r().
|
// thus no need to use strerror_r().
|
||||||
str::from_utf8(unsafe { CStr::from_ptr(libc::strerror(errno)) }.to_bytes())
|
str::from_utf8(unsafe { CStr::from_ptr(libc::strerror(errno)) }.to_bytes()).unwrap().to_owned()
|
||||||
.unwrap()
|
|
||||||
.to_owned()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(code: i32) -> ! {
|
pub fn exit(code: i32) -> ! {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::ffi::OsString;
|
use crate::ffi::OsString;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::hash::{Hash, Hasher};
|
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::path::{Path, PathBuf};
|
||||||
use crate::sys::time::SystemTime;
|
use crate::sys::time::SystemTime;
|
||||||
use crate::sys::{unsupported, Void};
|
use crate::sys::{unsupported, Void};
|
||||||
|
|||||||
@@ -4,19 +4,16 @@ pub mod args;
|
|||||||
pub mod env;
|
pub mod env;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
pub mod os;
|
||||||
#[path = "../../unix/path.rs"]
|
#[path = "../../unix/path.rs"]
|
||||||
pub mod path;
|
pub mod path;
|
||||||
pub mod pipe;
|
pub mod pipe;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
pub mod os;
|
|
||||||
|
|
||||||
// This enum is used as the storage for a bunch of types which can't actually exist.
|
// 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)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||||
pub enum Void {}
|
pub enum Void {}
|
||||||
|
|
||||||
pub fn unsupported<T>() -> io::Result<T> {
|
pub fn unsupported<T>() -> io::Result<T> {
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "This function is not available on CloudABI."))
|
||||||
io::ErrorKind::Other,
|
|
||||||
"This function is not available on CloudABI.",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
use crate::convert::TryFrom;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io::{self, IoSlice, IoSliceMut};
|
use crate::io::{self, IoSlice, IoSliceMut};
|
||||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||||
use crate::time::Duration;
|
|
||||||
use crate::sys::{unsupported, Void};
|
use crate::sys::{unsupported, Void};
|
||||||
use crate::convert::TryFrom;
|
use crate::time::Duration;
|
||||||
|
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
pub extern crate libc as netc;
|
pub extern crate libc as netc;
|
||||||
|
|||||||
@@ -32,9 +32,7 @@ pub enum Stdio {
|
|||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn new(_program: &OsStr) -> Command {
|
pub fn new(_program: &OsStr) -> Command {
|
||||||
Command {
|
Command { env: Default::default() }
|
||||||
env: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arg(&mut self, _arg: &OsStr) {}
|
pub fn arg(&mut self, _arg: &OsStr) {}
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(dur: Duration) {
|
pub fn sleep(dur: Duration) {
|
||||||
let timeout = checked_dur2intervals(&dur)
|
let timeout =
|
||||||
.expect("overflow converting duration to nanoseconds");
|
checked_dur2intervals(&dur).expect("overflow converting duration to nanoseconds");
|
||||||
unsafe {
|
unsafe {
|
||||||
let subscription = abi::subscription {
|
let subscription = abi::subscription {
|
||||||
type_: abi::eventtype::CLOCK,
|
type_: abi::eventtype::CLOCK,
|
||||||
@@ -85,11 +85,7 @@ impl Thread {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
assert!(
|
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||||
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> {
|
pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
|
||||||
dur.as_secs()
|
dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as abi::timestamp)
|
||||||
.checked_mul(NSEC_PER_SEC)?
|
|
||||||
.checked_add(dur.subsec_nanos() as abi::timestamp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instant {
|
impl Instant {
|
||||||
@@ -39,15 +37,11 @@ impl Instant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
|
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
|
||||||
Some(Instant {
|
Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
|
||||||
t: self.t.checked_add(checked_dur2intervals(other)?)?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
|
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
|
||||||
Some(Instant {
|
Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
|
||||||
t: self.t.checked_sub(checked_dur2intervals(other)?)?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,29 +63,19 @@ impl SystemTime {
|
|||||||
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||||
if self.t >= other.t {
|
if self.t >= other.t {
|
||||||
let diff = self.t - other.t;
|
let diff = self.t - other.t;
|
||||||
Ok(Duration::new(
|
Ok(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
|
||||||
diff / NSEC_PER_SEC,
|
|
||||||
(diff % NSEC_PER_SEC) as u32,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
let diff = other.t - self.t;
|
let diff = other.t - self.t;
|
||||||
Err(Duration::new(
|
Err(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
|
||||||
diff / NSEC_PER_SEC,
|
|
||||||
(diff % NSEC_PER_SEC) as u32,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
|
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
|
||||||
Some(SystemTime {
|
Some(SystemTime { t: self.t.checked_add(checked_dur2intervals(other)?)? })
|
||||||
t: self.t.checked_add(checked_dur2intervals(other)?)?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
|
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
|
||||||
Some(SystemTime {
|
Some(SystemTime { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
|
||||||
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());
|
let addr = abi::malloc(layout.size(), layout.align());
|
||||||
|
|
||||||
if !addr.is_null() {
|
if !addr.is_null() {
|
||||||
ptr::write_bytes(
|
ptr::write_bytes(addr, 0x00, layout.size());
|
||||||
addr,
|
|
||||||
0x00,
|
|
||||||
layout.size()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr
|
addr
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ use crate::marker::PhantomData;
|
|||||||
use crate::vec;
|
use crate::vec;
|
||||||
|
|
||||||
/// One-time global initialization.
|
/// 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.
|
/// One-time global cleanup.
|
||||||
pub unsafe fn cleanup() { imp::cleanup() }
|
pub unsafe fn cleanup() {
|
||||||
|
imp::cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the command line arguments
|
/// Returns the command line arguments
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
@@ -26,24 +30,32 @@ impl Args {
|
|||||||
|
|
||||||
impl Iterator for Args {
|
impl Iterator for Args {
|
||||||
type Item = OsString;
|
type Item = OsString;
|
||||||
fn next(&mut self) -> Option<OsString> { self.iter.next() }
|
fn next(&mut self) -> Option<OsString> {
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
self.iter.next()
|
||||||
|
}
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExactSizeIterator for Args {
|
impl ExactSizeIterator for Args {
|
||||||
fn len(&self) -> usize { self.iter.len() }
|
fn len(&self) -> usize {
|
||||||
|
self.iter.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DoubleEndedIterator for Args {
|
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 {
|
mod imp {
|
||||||
use crate::sys_common::os_str_bytes::*;
|
use super::Args;
|
||||||
use crate::ptr;
|
|
||||||
use crate::ffi::{CStr, OsString};
|
use crate::ffi::{CStr, OsString};
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use super::Args;
|
use crate::ptr;
|
||||||
|
use crate::sys_common::os_str_bytes::*;
|
||||||
|
|
||||||
use crate::sys_common::mutex::Mutex;
|
use crate::sys_common::mutex::Mutex;
|
||||||
|
|
||||||
@@ -64,19 +76,18 @@ mod imp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
Args {
|
Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData }
|
||||||
iter: clone().into_iter(),
|
|
||||||
_dont_send_or_sync_me: PhantomData
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone() -> Vec<OsString> {
|
fn clone() -> Vec<OsString> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _guard = LOCK.lock();
|
let _guard = LOCK.lock();
|
||||||
(0..ARGC).map(|i| {
|
(0..ARGC)
|
||||||
|
.map(|i| {
|
||||||
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
|
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
|
||||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||||
}).collect()
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// These symbols are all defined in `compiler-builtins`
|
// These symbols are all defined in `compiler-builtins`
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn acos(n: f64) -> f64;
|
pub fn acos(n: f64) -> f64;
|
||||||
pub fn acosf(n: f32) -> f32;
|
pub fn acosf(n: f32) -> f32;
|
||||||
pub fn asin(n: f64) -> f64;
|
pub fn asin(n: f64) -> f64;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
#![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::mem;
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
use crate::sys::hermit::abi;
|
use crate::sys::hermit::abi;
|
||||||
@@ -16,7 +16,9 @@ impl FileDesc {
|
|||||||
FileDesc { fd }
|
FileDesc { fd }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw(&self) -> i32 { self.fd }
|
pub fn raw(&self) -> i32 {
|
||||||
|
self.fd
|
||||||
|
}
|
||||||
|
|
||||||
/// Extracts the actual file descriptor without closing it.
|
/// Extracts the actual file descriptor without closing it.
|
||||||
pub fn into_raw(self) -> i32 {
|
pub fn into_raw(self) -> i32 {
|
||||||
@@ -67,7 +69,9 @@ impl<'a> Read for &'a FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<i32> for FileDesc {
|
impl AsInner<i32> for FileDesc {
|
||||||
fn as_inner(&self) -> &i32 { &self.fd }
|
fn as_inner(&self) -> &i32 {
|
||||||
|
&self.fd
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for FileDesc {
|
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::fmt;
|
||||||
use crate::io::{self, Error, ErrorKind};
|
|
||||||
use crate::hash::{Hash, Hasher};
|
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::path::{Path, PathBuf};
|
||||||
use crate::sys::time::SystemTime;
|
use crate::sys::cvt;
|
||||||
use crate::sys::{unsupported, Void};
|
|
||||||
use crate::sys::hermit::abi;
|
use crate::sys::hermit::abi;
|
||||||
use crate::sys::hermit::fd::FileDesc;
|
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;
|
use crate::sys_common::os_str_bytes::OsStrExt;
|
||||||
|
|
||||||
pub use crate::sys_common::fs::copy;
|
pub use crate::sys_common::fs::copy;
|
||||||
@@ -45,7 +45,7 @@ pub struct OpenOptions {
|
|||||||
create: bool,
|
create: bool,
|
||||||
create_new: bool,
|
create_new: bool,
|
||||||
// system-specific
|
// system-specific
|
||||||
mode: i32
|
mode: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilePermissions(Void);
|
pub struct FilePermissions(Void);
|
||||||
@@ -53,7 +53,7 @@ pub struct FilePermissions(Void);
|
|||||||
pub struct FileType(Void);
|
pub struct FileType(Void);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DirBuilder { }
|
pub struct DirBuilder {}
|
||||||
|
|
||||||
impl FileAttr {
|
impl FileAttr {
|
||||||
pub fn size(&self) -> u64 {
|
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 {
|
impl fmt::Debug for FilePermissions {
|
||||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
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 {
|
impl Hash for FileType {
|
||||||
fn hash<H: Hasher>(&self, _h: &mut H) {
|
fn hash<H: Hasher>(&self, _h: &mut H) {
|
||||||
@@ -204,16 +202,28 @@ impl OpenOptions {
|
|||||||
create: false,
|
create: false,
|
||||||
create_new: false,
|
create_new: false,
|
||||||
// system-specific
|
// system-specific
|
||||||
mode: 0x777
|
mode: 0x777,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self, read: bool) { self.read = read; }
|
pub fn read(&mut self, read: bool) {
|
||||||
pub fn write(&mut self, write: bool) { self.write = write; }
|
self.read = read;
|
||||||
pub fn append(&mut self, append: bool) { self.append = append; }
|
}
|
||||||
pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
|
pub fn write(&mut self, write: bool) {
|
||||||
pub fn create(&mut self, create: bool) { self.create = create; }
|
self.write = write;
|
||||||
pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
|
}
|
||||||
|
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> {
|
fn get_access_mode(&self) -> io::Result<i32> {
|
||||||
match (self.read, self.write, self.append) {
|
match (self.read, self.write, self.append) {
|
||||||
@@ -224,21 +234,23 @@ impl OpenOptions {
|
|||||||
(true, _, true) => Ok(O_RDWR | O_APPEND),
|
(true, _, true) => Ok(O_RDWR | O_APPEND),
|
||||||
(false, false, false) => {
|
(false, false, false) => {
|
||||||
Err(io::Error::new(ErrorKind::InvalidInput, "invalid access mode"))
|
Err(io::Error::new(ErrorKind::InvalidInput, "invalid access mode"))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_creation_mode(&self) -> io::Result<i32> {
|
fn get_creation_mode(&self) -> io::Result<i32> {
|
||||||
match (self.write, self.append) {
|
match (self.write, self.append) {
|
||||||
(true, false) => {}
|
(true, false) => {}
|
||||||
(false, false) =>
|
(false, false) => {
|
||||||
if self.truncate || self.create || self.create_new {
|
if self.truncate || self.create || self.create_new {
|
||||||
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode"));
|
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode"));
|
||||||
},
|
}
|
||||||
(_, true) =>
|
}
|
||||||
|
(_, true) => {
|
||||||
if self.truncate && !self.create_new {
|
if self.truncate && !self.create_new {
|
||||||
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode"));
|
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode"));
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(match (self.create, self.truncate, self.create_new) {
|
Ok(match (self.create, self.truncate, self.create_new) {
|
||||||
@@ -327,7 +339,7 @@ impl File {
|
|||||||
|
|
||||||
impl DirBuilder {
|
impl DirBuilder {
|
||||||
pub fn new() -> DirBuilder {
|
pub fn new() -> DirBuilder {
|
||||||
DirBuilder { }
|
DirBuilder {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
|
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
|
//! compiling for wasm. That way it's a compile time error for something that's
|
||||||
//! guaranteed to be a runtime error!
|
//! guaranteed to be a runtime error!
|
||||||
|
|
||||||
use crate::os::raw::c_char;
|
|
||||||
use crate::intrinsics;
|
use crate::intrinsics;
|
||||||
|
use crate::os::raw::c_char;
|
||||||
|
|
||||||
pub mod alloc;
|
pub mod alloc;
|
||||||
pub mod args;
|
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 cmath;
|
||||||
pub mod thread;
|
pub mod condvar;
|
||||||
pub mod env;
|
pub mod env;
|
||||||
pub mod fs;
|
pub mod fast_thread_local;
|
||||||
pub mod fd;
|
pub mod fd;
|
||||||
|
pub mod fs;
|
||||||
|
pub mod io;
|
||||||
|
pub mod memchr;
|
||||||
|
pub mod mutex;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
pub mod os;
|
||||||
pub mod path;
|
pub mod path;
|
||||||
pub mod pipe;
|
pub mod pipe;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
pub mod rwlock;
|
||||||
pub mod stack_overflow;
|
pub mod stack_overflow;
|
||||||
pub mod time;
|
pub mod stdio;
|
||||||
|
pub mod thread;
|
||||||
pub mod thread_local;
|
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;
|
use crate::io::ErrorKind;
|
||||||
|
pub use crate::sys_common::os_str_bytes as os_str;
|
||||||
|
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
pub extern crate hermit_abi as abi;
|
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 {
|
pub fn unsupported_err() -> crate::io::Error {
|
||||||
crate::io::Error::new(crate::io::ErrorKind::Other,
|
crate::io::Error::new(crate::io::ErrorKind::Other, "operation not supported on HermitCore yet")
|
||||||
"operation not supported on HermitCore yet")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This enum is used as the storage for a bunch of types which can't actually
|
// 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]
|
#[no_mangle]
|
||||||
pub extern "C" fn floor(x: f64) -> f64 {
|
pub extern "C" fn floor(x: f64) -> f64 {
|
||||||
unsafe {
|
unsafe { intrinsics::floorf64(x) }
|
||||||
intrinsics::floorf64(x)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn abort_internal() -> ! {
|
pub unsafe fn abort_internal() -> ! {
|
||||||
@@ -103,8 +100,11 @@ pub fn init() {
|
|||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn runtime_entry(argc: i32, argv: *const *const c_char,
|
pub unsafe extern "C" fn runtime_entry(
|
||||||
env: *const *const c_char) -> ! {
|
argc: i32,
|
||||||
|
argv: *const *const c_char,
|
||||||
|
env: *const *const c_char,
|
||||||
|
) -> ! {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn main(argc: isize, argv: *const *const c_char) -> i32;
|
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> {
|
pub fn cvt(result: i32) -> crate::io::Result<usize> {
|
||||||
if result < 0 {
|
if result < 0 { Err(crate::io::Error::from_raw_os_error(-result)) } else { Ok(result as usize) }
|
||||||
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::ffi::c_void;
|
||||||
|
use crate::ptr;
|
||||||
use crate::sys::hermit::abi;
|
use crate::sys::hermit::abi;
|
||||||
|
|
||||||
pub struct Mutex {
|
pub struct Mutex {
|
||||||
inner: *const c_void
|
inner: *const c_void,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Mutex {}
|
unsafe impl Send for Mutex {}
|
||||||
@@ -42,7 +42,7 @@ impl Mutex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReentrantMutex {
|
pub struct ReentrantMutex {
|
||||||
inner: *const c_void
|
inner: *const c_void,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReentrantMutex {
|
impl ReentrantMutex {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::fmt;
|
|
||||||
use crate::convert::TryFrom;
|
use crate::convert::TryFrom;
|
||||||
|
use crate::fmt;
|
||||||
use crate::io::{self, IoSlice, IoSliceMut};
|
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::str;
|
||||||
use crate::sys::{unsupported, Void};
|
use crate::sys::{unsupported, Void};
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
@@ -234,23 +234,19 @@ impl UdpSocket {
|
|||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,8 +353,7 @@ pub mod netc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct sockaddr {
|
pub struct sockaddr {}
|
||||||
}
|
|
||||||
|
|
||||||
pub type socklen_t = usize;
|
pub type socklen_t = usize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
use crate::collections::HashMap;
|
||||||
use crate::error::Error as StdError;
|
use crate::error::Error as StdError;
|
||||||
use crate::ffi::{CStr, OsString, OsStr};
|
use crate::ffi::{CStr, OsStr, OsString};
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
@@ -7,12 +8,11 @@ use crate::memchr;
|
|||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::str;
|
use crate::str;
|
||||||
use crate::sys::{unsupported, Void};
|
|
||||||
use crate::collections::HashMap;
|
|
||||||
use crate::vec;
|
|
||||||
use crate::sync::Mutex;
|
use crate::sync::Mutex;
|
||||||
use crate::sys_common::os_str_bytes::*;
|
|
||||||
use crate::sys::hermit::abi;
|
use crate::sys::hermit::abi;
|
||||||
|
use crate::sys::{unsupported, Void};
|
||||||
|
use crate::sys_common::os_str_bytes::*;
|
||||||
|
use crate::vec;
|
||||||
|
|
||||||
pub fn errno() -> i32 {
|
pub fn errno() -> i32 {
|
||||||
0
|
0
|
||||||
@@ -47,7 +47,9 @@ impl<'a> Iterator for SplitPaths<'a> {
|
|||||||
pub struct JoinPathsError;
|
pub struct JoinPathsError;
|
||||||
|
|
||||||
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, 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)
|
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 guard = ENV.as_ref().unwrap().lock().unwrap();
|
||||||
let mut environ = env;
|
let mut environ = env;
|
||||||
while environ != ptr::null() && *environ != ptr::null() {
|
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);
|
guard.insert(key, value);
|
||||||
}
|
}
|
||||||
environ = environ.offset(1);
|
environ = environ.offset(1);
|
||||||
@@ -93,10 +95,12 @@ pub fn init_environment(env: *const *const i8) {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
|
let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
|
||||||
pos.map(|p| (
|
pos.map(|p| {
|
||||||
|
(
|
||||||
OsStringExt::from_vec(input[..p].to_vec()),
|
OsStringExt::from_vec(input[..p].to_vec()),
|
||||||
OsStringExt::from_vec(input[p+1..].to_vec()),
|
OsStringExt::from_vec(input[p + 1..].to_vec()),
|
||||||
))
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,8 +111,12 @@ pub struct Env {
|
|||||||
|
|
||||||
impl Iterator for Env {
|
impl Iterator for Env {
|
||||||
type Item = (OsString, OsString);
|
type Item = (OsString, OsString);
|
||||||
fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
|
fn next(&mut self) -> Option<(OsString, OsString)> {
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
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
|
/// Returns a vector of (variable, value) byte-vector pairs for all the
|
||||||
@@ -122,18 +130,15 @@ pub fn env() -> Env {
|
|||||||
result.push((key.clone(), value.clone()));
|
result.push((key.clone(), value.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Env {
|
return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData };
|
||||||
iter: result.into_iter(),
|
|
||||||
_dont_send_or_sync_me: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match ENV.as_ref().unwrap().lock().unwrap().get_mut(k) {
|
match ENV.as_ref().unwrap().lock().unwrap().get_mut(k) {
|
||||||
Some(value) => { Ok(Some(value.clone())) },
|
Some(value) => Ok(Some(value.clone())),
|
||||||
None => { Ok(None) },
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +173,5 @@ pub fn exit(code: i32) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getpid() -> u32 {
|
pub fn getpid() -> u32 {
|
||||||
unsafe {
|
unsafe { abi::getpid() }
|
||||||
abi::getpid()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::path::Prefix;
|
|
||||||
use crate::ffi::OsStr;
|
use crate::ffi::OsStr;
|
||||||
|
use crate::path::Prefix;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_sep_byte(b: u8) -> bool {
|
pub fn is_sep_byte(b: u8) -> bool {
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ impl AnonPipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read2(p1: AnonPipe,
|
pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
|
||||||
_v1: &mut Vec<u8>,
|
|
||||||
_p2: AnonPipe,
|
|
||||||
_v2: &mut Vec<u8>) -> io::Result<()> {
|
|
||||||
match p1.0 {}
|
match p1.0 {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,32 +32,28 @@ pub enum Stdio {
|
|||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn new(_program: &OsStr) -> Command {
|
pub fn new(_program: &OsStr) -> Command {
|
||||||
Command {
|
Command { env: Default::default() }
|
||||||
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 {
|
pub fn env_mut(&mut self) -> &mut CommandEnv {
|
||||||
&mut self.env
|
&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)
|
pub fn spawn(
|
||||||
-> io::Result<(Process, StdioPipes)> {
|
&mut self,
|
||||||
|
_default: Stdio,
|
||||||
|
_needs_stdin: bool,
|
||||||
|
) -> io::Result<(Process, StdioPipes)> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,8 +102,7 @@ impl PartialEq for ExitStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for ExitStatus {
|
impl Eq for ExitStatus {}
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for ExitStatus {
|
impl fmt::Debug for ExitStatus {
|
||||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::mutex::Mutex;
|
use super::mutex::Mutex;
|
||||||
|
|
||||||
pub struct RWLock {
|
pub struct RWLock {
|
||||||
mutex: Mutex
|
mutex: Mutex,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for RWLock {}
|
unsafe impl Send for RWLock {}
|
||||||
@@ -9,9 +9,7 @@ unsafe impl Sync for RWLock {}
|
|||||||
|
|
||||||
impl RWLock {
|
impl RWLock {
|
||||||
pub const fn new() -> RWLock {
|
pub const fn new() -> RWLock {
|
||||||
RWLock {
|
RWLock { mutex: Mutex::new() }
|
||||||
mutex: Mutex::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn init() {
|
pub unsafe fn init() {}
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn cleanup() {
|
pub unsafe fn cleanup() {}
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ impl Stdin {
|
|||||||
// .read(data)
|
// .read(data)
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stdout {
|
impl Stdout {
|
||||||
@@ -31,9 +30,7 @@ impl Stdout {
|
|||||||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||||
let len;
|
let len;
|
||||||
|
|
||||||
unsafe {
|
unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
||||||
len = abi::write(1, data.as_ptr() as *const u8, data.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len < 0 {
|
if len < 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
|
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> {
|
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
let len;
|
let len;
|
||||||
|
|
||||||
unsafe {
|
unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
||||||
len = abi::write(1, data.as_ptr() as *const u8, data.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len < 0 {
|
if len < 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
|
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> {
|
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||||
let len;
|
let len;
|
||||||
|
|
||||||
unsafe {
|
unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
||||||
len = abi::write(2, data.as_ptr() as *const u8, data.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len < 0 {
|
if len < 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
|
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> {
|
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
let len;
|
let len;
|
||||||
|
|
||||||
unsafe {
|
unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
||||||
len = abi::write(2, data.as_ptr() as *const u8, data.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len < 0 {
|
if len < 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
|
Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::ffi::CStr;
|
use crate::ffi::CStr;
|
||||||
|
use crate::fmt;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
|
use crate::mem;
|
||||||
use crate::sys::hermit::abi;
|
use crate::sys::hermit::abi;
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
use crate::mem;
|
|
||||||
use crate::fmt;
|
|
||||||
use core::u32;
|
use core::u32;
|
||||||
|
|
||||||
use crate::sys_common::thread::*;
|
use crate::sys_common::thread::*;
|
||||||
@@ -35,7 +35,7 @@ impl fmt::Display for Priority {
|
|||||||
pub const NORMAL_PRIO: Priority = Priority::from(2);
|
pub const NORMAL_PRIO: Priority = Priority::from(2);
|
||||||
|
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
tid: Tid
|
tid: Tid,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Thread {}
|
unsafe impl Send for Thread {}
|
||||||
@@ -44,14 +44,20 @@ unsafe impl Sync for Thread {}
|
|||||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 262144;
|
pub const DEFAULT_MIN_STACK_SIZE: usize = 262144;
|
||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
pub unsafe fn new_with_coreid(_stack: usize, p: Box<dyn FnOnce()>, core_id: isize)
|
pub unsafe fn new_with_coreid(
|
||||||
-> io::Result<Thread>
|
_stack: usize,
|
||||||
{
|
p: Box<dyn FnOnce()>,
|
||||||
|
core_id: isize,
|
||||||
|
) -> io::Result<Thread> {
|
||||||
let p = box p;
|
let p = box p;
|
||||||
let mut tid: Tid = u32::MAX;
|
let mut tid: Tid = u32::MAX;
|
||||||
let ret = abi::spawn(&mut tid as *mut Tid, thread_start,
|
let ret = abi::spawn(
|
||||||
|
&mut tid as *mut Tid,
|
||||||
|
thread_start,
|
||||||
&*p as *const _ as *const u8 as usize,
|
&*p as *const _ as *const u8 as usize,
|
||||||
Priority::into(NORMAL_PRIO), core_id);
|
Priority::into(NORMAL_PRIO),
|
||||||
|
core_id,
|
||||||
|
);
|
||||||
|
|
||||||
return if ret == 0 {
|
return if ret == 0 {
|
||||||
mem::forget(p); // ownership passed to pthread_create
|
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!"))
|
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 {
|
unsafe {
|
||||||
start_thread(main as *mut u8);
|
start_thread(main as *mut u8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||||
-> io::Result<Thread>
|
|
||||||
{
|
|
||||||
Thread::new_with_coreid(stack, p, -1 /* = no specific core */)
|
Thread::new_with_coreid(stack, p, -1 /* = no specific core */)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +103,9 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn id(&self) -> Tid { self.tid }
|
pub fn id(&self) -> Tid {
|
||||||
|
self.tid
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_id(self) -> Tid {
|
pub fn into_id(self) -> Tid {
|
||||||
@@ -111,6 +117,10 @@ impl Thread {
|
|||||||
|
|
||||||
pub mod guard {
|
pub mod guard {
|
||||||
pub type Guard = !;
|
pub type Guard = !;
|
||||||
pub unsafe fn current() -> Option<Guard> { None }
|
pub unsafe fn current() -> Option<Guard> {
|
||||||
pub unsafe fn init() -> Option<Guard> { None }
|
None
|
||||||
|
}
|
||||||
|
pub unsafe fn init() -> Option<Guard> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::sys_common::mutex::Mutex;
|
|||||||
|
|
||||||
pub type Key = usize;
|
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);
|
static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
@@ -41,11 +41,7 @@ pub unsafe fn create(dtor: Option<Dtor>) -> Key {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn get(key: Key) -> *mut u8 {
|
pub unsafe fn get(key: Key) -> *mut u8 {
|
||||||
if let Some(&entry) = locals().get(&key) {
|
if let Some(&entry) = locals().get(&key) { entry } else { ptr::null_mut() }
|
||||||
entry
|
|
||||||
} else {
|
|
||||||
ptr::null_mut()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -1,34 +1,35 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::time::Duration;
|
|
||||||
use crate::cmp::Ordering;
|
use crate::cmp::Ordering;
|
||||||
use crate::convert::TryInto;
|
use crate::convert::TryInto;
|
||||||
use core::hash::{Hash, Hasher};
|
|
||||||
use crate::sys::hermit::abi;
|
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::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)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct Timespec {
|
struct Timespec {
|
||||||
t: timespec
|
t: timespec,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Timespec {
|
impl Timespec {
|
||||||
const fn zero() -> Timespec {
|
const fn zero() -> Timespec {
|
||||||
Timespec {
|
Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
|
||||||
t: timespec { tv_sec: 0, tv_nsec: 0 },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
||||||
if self >= other {
|
if self >= other {
|
||||||
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
||||||
Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
|
Duration::new(
|
||||||
(self.t.tv_nsec - other.t.tv_nsec) as u32)
|
(self.t.tv_sec - other.t.tv_sec) as u64,
|
||||||
|
(self.t.tv_nsec - other.t.tv_nsec) as u32,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
Duration::new(
|
||||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
|
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||||
other.t.tv_nsec as u32)
|
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
match other.sub_timespec(self) {
|
match other.sub_timespec(self) {
|
||||||
@@ -52,12 +53,7 @@ impl Timespec {
|
|||||||
nsec -= NSEC_PER_SEC as u32;
|
nsec -= NSEC_PER_SEC as u32;
|
||||||
secs = secs.checked_add(1)?;
|
secs = secs.checked_add(1)?;
|
||||||
}
|
}
|
||||||
Some(Timespec {
|
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||||
t: timespec {
|
|
||||||
tv_sec: secs,
|
|
||||||
tv_nsec: nsec as _,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
|
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
|
||||||
@@ -73,12 +69,7 @@ impl Timespec {
|
|||||||
nsec += NSEC_PER_SEC as i32;
|
nsec += NSEC_PER_SEC as i32;
|
||||||
secs = secs.checked_sub(1)?;
|
secs = secs.checked_sub(1)?;
|
||||||
}
|
}
|
||||||
Some(Timespec {
|
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||||
t: timespec {
|
|
||||||
tv_sec: secs,
|
|
||||||
tv_nsec: nsec as _,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +96,7 @@ impl Ord for Timespec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Hash 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_sec.hash(state);
|
||||||
self.t.tv_nsec.hash(state);
|
self.t.tv_nsec.hash(state);
|
||||||
}
|
}
|
||||||
@@ -150,9 +141,7 @@ pub struct SystemTime {
|
|||||||
t: Timespec,
|
t: Timespec,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const UNIX_EPOCH: SystemTime = SystemTime {
|
pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
|
||||||
t: Timespec::zero(),
|
|
||||||
};
|
|
||||||
|
|
||||||
impl SystemTime {
|
impl SystemTime {
|
||||||
pub fn now() -> SystemTime {
|
pub fn now() -> SystemTime {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
|
#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
|
||||||
use crate::io::Write;
|
use crate::io::Write;
|
||||||
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
// runtime features
|
// runtime features
|
||||||
mod reloc;
|
|
||||||
pub(super) mod panic;
|
pub(super) mod panic;
|
||||||
|
mod reloc;
|
||||||
|
|
||||||
// library features
|
// library features
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
@@ -38,14 +38,16 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
|
|||||||
UNINIT => {
|
UNINIT => {
|
||||||
reloc::relocate_elf_rela();
|
reloc::relocate_elf_rela();
|
||||||
RELOC_STATE.store(DONE, Ordering::Release);
|
RELOC_STATE.store(DONE, Ordering::Release);
|
||||||
},
|
}
|
||||||
// We need to wait until the initialization is done.
|
// We need to wait until the initialization is done.
|
||||||
BUSY => while RELOC_STATE.load(Ordering::Acquire) == BUSY {
|
BUSY => {
|
||||||
|
while RELOC_STATE.load(Ordering::Acquire) == BUSY {
|
||||||
core::arch::x86_64::_mm_pause()
|
core::arch::x86_64::_mm_pause()
|
||||||
},
|
}
|
||||||
|
}
|
||||||
// Initialization is done.
|
// Initialization is done.
|
||||||
DONE => {},
|
DONE => {}
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,21 +16,13 @@ fn empty_user_slice() -> &'static mut UserRef<[u8]> {
|
|||||||
|
|
||||||
impl SgxPanicOutput {
|
impl SgxPanicOutput {
|
||||||
pub(crate) fn new() -> Option<Self> {
|
pub(crate) fn new() -> Option<Self> {
|
||||||
if unsafe { DEBUG == 0 } {
|
if unsafe { DEBUG == 0 } { None } else { Some(SgxPanicOutput(None)) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(SgxPanicOutput(None))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self) -> &mut &'static mut UserRef<[u8]> {
|
fn init(&mut self) -> &mut &'static mut UserRef<[u8]> {
|
||||||
self.0.get_or_insert_with(|| unsafe {
|
self.0.get_or_insert_with(|| unsafe {
|
||||||
let ptr = take_debug_panic_buf_ptr();
|
let ptr = take_debug_panic_buf_ptr();
|
||||||
if ptr.is_null() {
|
if ptr.is_null() { empty_user_slice() } else { UserRef::from_raw_parts_mut(ptr, 1024) }
|
||||||
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 super::mem;
|
||||||
|
use crate::slice::from_raw_parts;
|
||||||
|
|
||||||
const R_X86_64_RELATIVE: u32 = 8;
|
const R_X86_64_RELATIVE: u32 = 8;
|
||||||
|
|
||||||
@@ -11,18 +11,20 @@ struct Rela<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn relocate_elf_rela() {
|
pub fn relocate_elf_rela() {
|
||||||
extern {
|
extern "C" {
|
||||||
static RELA: u64;
|
static RELA: u64;
|
||||||
static RELACOUNT: usize;
|
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 {
|
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 {
|
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");
|
rtabort!("Invalid relocation");
|
||||||
}
|
}
|
||||||
unsafe { *mem::rel_ptr_mut::<*const ()>(rela.offset) = mem::rel_ptr(rela.addend) };
|
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.
|
/// is a one-to-one correspondence of the ID to the address of the TCS.
|
||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||||
pub fn current() -> Tcs {
|
pub fn current() -> Tcs {
|
||||||
extern "C" { fn get_tcs_addr() -> Tcs; }
|
extern "C" {
|
||||||
|
fn get_tcs_addr() -> Tcs;
|
||||||
|
}
|
||||||
unsafe { get_tcs_addr() }
|
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 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 USIZE_BITS: usize = 64;
|
||||||
const TLS_KEYS: usize = 128; // Same as POSIX minimum
|
const TLS_KEYS: usize = 128; // Same as POSIX minimum
|
||||||
const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
|
const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
|
||||||
@@ -50,18 +50,18 @@ impl Key {
|
|||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Tls {
|
pub struct Tls {
|
||||||
data: [Cell<*mut u8>; TLS_KEYS]
|
data: [Cell<*mut u8>; TLS_KEYS],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ActiveTls<'a> {
|
pub struct ActiveTls<'a> {
|
||||||
tls: &'a Tls
|
tls: &'a Tls,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for ActiveTls<'a> {
|
impl<'a> Drop for ActiveTls<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let value_with_destructor = |key: usize| {
|
let value_with_destructor = |key: usize| {
|
||||||
let ptr = TLS_DESTRUCTOR[key].load(Ordering::Relaxed);
|
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))
|
.map(|dtor| (&self.tls.data[key], dtor))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ impl Tls {
|
|||||||
&*(get_tls_ptr() as *const 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() {
|
let index = if let Some(index) = TLS_KEY_IN_USE.set() {
|
||||||
index
|
index
|
||||||
} else {
|
} else {
|
||||||
@@ -127,10 +127,10 @@ impl Tls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod sync_bitset {
|
mod sync_bitset {
|
||||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
|
||||||
use crate::iter::{Enumerate, Peekable};
|
use crate::iter::{Enumerate, Peekable};
|
||||||
use crate::slice::Iter;
|
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.
|
/// A bitset that can be used synchronously.
|
||||||
pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
|
pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
|
||||||
@@ -146,10 +146,7 @@ mod sync_bitset {
|
|||||||
|
|
||||||
/// Not atomic.
|
/// Not atomic.
|
||||||
pub fn iter(&self) -> SyncBitsetIter<'_> {
|
pub fn iter(&self) -> SyncBitsetIter<'_> {
|
||||||
SyncBitsetIter {
|
SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 }
|
||||||
iter: self.0.iter().enumerate().peekable(),
|
|
||||||
elem_idx: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&self, index: usize) {
|
pub fn clear(&self, index: usize) {
|
||||||
@@ -171,7 +168,7 @@ mod sync_bitset {
|
|||||||
current,
|
current,
|
||||||
current | (1 << trailing_ones),
|
current | (1 << trailing_ones),
|
||||||
Ordering::AcqRel,
|
Ordering::AcqRel,
|
||||||
Ordering::Relaxed
|
Ordering::Relaxed,
|
||||||
) {
|
) {
|
||||||
Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
|
Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
|
||||||
Err(previous) => current = previous,
|
Err(previous) => current = previous,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use crate::ptr::{self, NonNull};
|
|
||||||
use crate::mem;
|
|
||||||
use crate::cell::UnsafeCell;
|
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::slice;
|
||||||
use crate::ops::{Deref, DerefMut, Index, IndexMut, CoerceUnsized};
|
|
||||||
use crate::slice::SliceIndex;
|
use crate::slice::SliceIndex;
|
||||||
|
|
||||||
use fortanix_sgx_abi::*;
|
|
||||||
use super::super::mem::is_user_range;
|
use super::super::mem::is_user_range;
|
||||||
|
use fortanix_sgx_abi::*;
|
||||||
|
|
||||||
/// A type that can be safely read from or written to userspace.
|
/// 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 pointer is null.
|
||||||
/// * the pointed-to range is not in user memory.
|
/// * the pointed-to range is not in user memory.
|
||||||
unsafe fn check_ptr(ptr: *const Self) {
|
unsafe fn check_ptr(ptr: *const Self) {
|
||||||
let is_aligned = |p| -> bool {
|
let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
|
||||||
0 == (p as usize) & (Self::align_of() - 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(is_aligned(ptr as *const u8));
|
assert!(is_aligned(ptr as *const u8));
|
||||||
assert!(is_user_range(ptr as _, mem::size_of_val(&*ptr)));
|
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")]
|
#[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
|
// This function returns memory that is practically uninitialized, but is
|
||||||
// not considered "unspecified" or "undefined" for purposes of an
|
// not considered "unspecified" or "undefined" for purposes of an
|
||||||
// optimizing compiler. This is achieved by returning a pointer from
|
// optimizing compiler. This is achieved by returning a pointer from
|
||||||
@@ -211,7 +212,7 @@ impl<T: ?Sized> User<T> where T: UserSafe {
|
|||||||
ptr::copy(
|
ptr::copy(
|
||||||
val as *const T as *const u8,
|
val as *const T as *const u8,
|
||||||
ret.0.as_ptr() as *mut u8,
|
ret.0.as_ptr() as *mut u8,
|
||||||
mem::size_of_val(val)
|
mem::size_of_val(val),
|
||||||
);
|
);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@@ -244,7 +245,10 @@ impl<T: ?Sized> User<T> where T: UserSafe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[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.
|
/// Allocate space for `T` in user memory.
|
||||||
pub fn uninitialized() -> Self {
|
pub fn uninitialized() -> Self {
|
||||||
Self::new_uninit_bytes(mem::size_of::<T>())
|
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")]
|
#[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.
|
/// Allocate space for a `[T]` of `n` elements in user memory.
|
||||||
pub fn uninitialized(n: usize) -> Self {
|
pub fn uninitialized(n: usize) -> Self {
|
||||||
Self::new_uninit_bytes(n * mem::size_of::<T>())
|
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")]
|
#[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.
|
/// Creates a `&UserRef<[T]>` from a raw pointer.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -309,7 +319,7 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe {
|
|||||||
/// * The pointed-to range is not in user memory
|
/// * The pointed-to range is not in user memory
|
||||||
pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self {
|
pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self {
|
||||||
T::check_ptr(ptr);
|
T::check_ptr(ptr);
|
||||||
&mut*(ptr as *mut Self)
|
&mut *(ptr as *mut Self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies `val` into user memory.
|
/// 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.
|
/// the source. This can happen for dynamically-sized types such as slices.
|
||||||
pub fn copy_from_enclave(&mut self, val: &T) {
|
pub fn copy_from_enclave(&mut self, val: &T) {
|
||||||
unsafe {
|
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(
|
ptr::copy(
|
||||||
val as *const T as *const u8,
|
val as *const T as *const u8,
|
||||||
self.0.get() as *mut T as *mut 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.
|
/// the source. This can happen for dynamically-sized types such as slices.
|
||||||
pub fn copy_to_enclave(&self, dest: &mut T) {
|
pub fn copy_to_enclave(&self, dest: &mut T) {
|
||||||
unsafe {
|
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(
|
ptr::copy(
|
||||||
self.0.get() as *const T as *const u8,
|
self.0.get() as *const T as *const u8,
|
||||||
dest as *mut T as *mut 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")]
|
#[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.
|
/// Copies the value from user memory into enclave memory.
|
||||||
pub fn to_enclave(&self) -> T {
|
pub fn to_enclave(&self) -> T {
|
||||||
unsafe { ptr::read(self.0.get()) }
|
unsafe { ptr::read(self.0.get()) }
|
||||||
@@ -364,7 +377,10 @@ impl<T> UserRef<T> where T: UserSafe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[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.
|
/// Creates a `&UserRef<[T]>` from a raw thin pointer and a slice length.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # 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 does not fit in the address space
|
||||||
/// * The pointed-to range is not in user memory
|
/// * 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 {
|
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.
|
/// 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.
|
/// Returns an iterator over the slice.
|
||||||
pub fn iter(&self) -> Iter<'_, T>
|
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 {
|
unsafe { Iter((&*self.as_raw_ptr()).iter()) }
|
||||||
Iter((&*self.as_raw_ptr()).iter())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that allows modifying each value.
|
/// Returns an iterator that allows modifying each value.
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, T>
|
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 {
|
unsafe { IterMut((&mut *self.as_raw_mut_ptr()).iter_mut()) }
|
||||||
IterMut((&mut*self.as_raw_mut_ptr()).iter_mut())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,9 +482,7 @@ impl<'a, T: UserSafe> Iterator for Iter<'a, T> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
unsafe {
|
unsafe { self.0.next().map(|e| UserRef::from_ptr(e)) }
|
||||||
self.0.next().map(|e| UserRef::from_ptr(e))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,14 +498,15 @@ impl<'a, T: UserSafe> Iterator for IterMut<'a, T> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
unsafe {
|
unsafe { self.0.next().map(|e| UserRef::from_mut_ptr(e)) }
|
||||||
self.0.next().map(|e| UserRef::from_mut_ptr(e))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[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>;
|
type Target = UserRef<T>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
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")]
|
#[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 {
|
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")]
|
#[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) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = (*self.0.as_ptr()).0.get();
|
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]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
|
fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
|
||||||
unsafe {
|
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)
|
UserRef::from_mut_ptr(slice)
|
||||||
} else {
|
} else {
|
||||||
rtabort!("index out of range for user slice");
|
rtabort!("index out of range for user slice");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::cmp;
|
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;
|
use crate::time::Duration;
|
||||||
|
|
||||||
pub(crate) mod alloc;
|
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]);
|
userbuf[index..end].copy_to_enclave(&mut buf[..buflen]);
|
||||||
index += buf.len();
|
index += buf.len();
|
||||||
} else {
|
} else {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(userbuf.len())
|
Ok(userbuf.len())
|
||||||
@@ -60,7 +60,7 @@ pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> IoResult<usize> {
|
|||||||
userbuf[index..end].copy_from_enclave(&buf[..buflen]);
|
userbuf[index..end].copy_from_enclave(&buf[..buflen]);
|
||||||
index += buf.len();
|
index += buf.len();
|
||||||
} else {
|
} else {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
|
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 {
|
unsafe {
|
||||||
let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
|
let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
|
||||||
let mut local = alloc::User::<ByteBuffer>::uninitialized();
|
let mut local = alloc::User::<ByteBuffer>::uninitialized();
|
||||||
let fd = raw::bind_stream(
|
let fd = raw::bind_stream(addr_user.as_ptr(), addr_user.len(), local.as_raw_mut_ptr())
|
||||||
addr_user.as_ptr(),
|
.from_sgx_result()?;
|
||||||
addr_user.len(),
|
|
||||||
local.as_raw_mut_ptr()
|
|
||||||
).from_sgx_result()?;
|
|
||||||
let local = string_from_bytebuffer(&local, "bind_stream", "local_addr");
|
let local = string_from_bytebuffer(&local, "bind_stream", "local_addr");
|
||||||
Ok((fd, local))
|
Ok((fd, local))
|
||||||
}
|
}
|
||||||
@@ -108,11 +105,8 @@ pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> {
|
|||||||
let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
|
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 (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
|
||||||
let fd = raw::accept_stream(
|
let fd = raw::accept_stream(fd, local.as_raw_mut_ptr(), peer.as_raw_mut_ptr())
|
||||||
fd,
|
.from_sgx_result()?;
|
||||||
local.as_raw_mut_ptr(),
|
|
||||||
peer.as_raw_mut_ptr()
|
|
||||||
).from_sgx_result()?;
|
|
||||||
let local = string_from_bytebuffer(&local, "accept_stream", "local_addr");
|
let local = string_from_bytebuffer(&local, "accept_stream", "local_addr");
|
||||||
let peer = string_from_bytebuffer(&peer, "accept_stream", "peer_addr");
|
let peer = string_from_bytebuffer(&peer, "accept_stream", "peer_addr");
|
||||||
Ok((fd, local, peer))
|
Ok((fd, local, peer))
|
||||||
@@ -132,8 +126,9 @@ pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> {
|
|||||||
addr_user.as_ptr(),
|
addr_user.as_ptr(),
|
||||||
addr_user.len(),
|
addr_user.len(),
|
||||||
local.as_raw_mut_ptr(),
|
local.as_raw_mut_ptr(),
|
||||||
peer.as_raw_mut_ptr()
|
peer.as_raw_mut_ptr(),
|
||||||
).from_sgx_result()?;
|
)
|
||||||
|
.from_sgx_result()?;
|
||||||
let local = string_from_bytebuffer(&local, "connect_stream", "local_addr");
|
let local = string_from_bytebuffer(&local, "connect_stream", "local_addr");
|
||||||
let peer = string_from_bytebuffer(&peer, "connect_stream", "peer_addr");
|
let peer = string_from_bytebuffer(&peer, "connect_stream", "peer_addr");
|
||||||
Ok((fd, local, peer))
|
Ok((fd, local, peer))
|
||||||
@@ -183,25 +178,25 @@ pub use self::raw::free;
|
|||||||
|
|
||||||
fn check_os_error(err: Result) -> i32 {
|
fn check_os_error(err: Result) -> i32 {
|
||||||
// FIXME: not sure how to make sure all variants of Error are covered
|
// FIXME: not sure how to make sure all variants of Error are covered
|
||||||
if err == Error::NotFound as _ ||
|
if err == Error::NotFound as _
|
||||||
err == Error::PermissionDenied as _ ||
|
|| err == Error::PermissionDenied as _
|
||||||
err == Error::ConnectionRefused as _ ||
|
|| err == Error::ConnectionRefused as _
|
||||||
err == Error::ConnectionReset as _ ||
|
|| err == Error::ConnectionReset as _
|
||||||
err == Error::ConnectionAborted as _ ||
|
|| err == Error::ConnectionAborted as _
|
||||||
err == Error::NotConnected as _ ||
|
|| err == Error::NotConnected as _
|
||||||
err == Error::AddrInUse as _ ||
|
|| err == Error::AddrInUse as _
|
||||||
err == Error::AddrNotAvailable as _ ||
|
|| err == Error::AddrNotAvailable as _
|
||||||
err == Error::BrokenPipe as _ ||
|
|| err == Error::BrokenPipe as _
|
||||||
err == Error::AlreadyExists as _ ||
|
|| err == Error::AlreadyExists as _
|
||||||
err == Error::WouldBlock as _ ||
|
|| err == Error::WouldBlock as _
|
||||||
err == Error::InvalidInput as _ ||
|
|| err == Error::InvalidInput as _
|
||||||
err == Error::InvalidData as _ ||
|
|| err == Error::InvalidData as _
|
||||||
err == Error::TimedOut as _ ||
|
|| err == Error::TimedOut as _
|
||||||
err == Error::WriteZero as _ ||
|
|| err == Error::WriteZero as _
|
||||||
err == Error::Interrupted as _ ||
|
|| err == Error::Interrupted as _
|
||||||
err == Error::Other as _ ||
|
|| err == Error::Other as _
|
||||||
err == Error::UnexpectedEof as _ ||
|
|| err == Error::UnexpectedEof as _
|
||||||
((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
|
|| ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
|
||||||
{
|
{
|
||||||
err
|
err
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||||
pub use fortanix_sgx_abi::*;
|
pub use fortanix_sgx_abi::*;
|
||||||
|
|
||||||
use crate::ptr::NonNull;
|
|
||||||
use crate::num::NonZeroU64;
|
use crate::num::NonZeroU64;
|
||||||
|
use crate::ptr::NonNull;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct UsercallReturn(u64, u64);
|
struct UsercallReturn(u64, u64);
|
||||||
@@ -25,9 +25,14 @@ extern "C" {
|
|||||||
/// Panics if `nr` is `0`.
|
/// Panics if `nr` is `0`.
|
||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn do_usercall(nr: NonZeroU64, p1: u64, p2: u64, p3: u64, p4: u64, abort: bool)
|
pub unsafe fn do_usercall(
|
||||||
-> (u64, u64)
|
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);
|
let UsercallReturn(a, b) = usercall(nr, p1, p2, abort as _, p3, p4);
|
||||||
(a, b)
|
(a, b)
|
||||||
}
|
}
|
||||||
@@ -109,11 +114,7 @@ define_ra!(<T> *mut T);
|
|||||||
|
|
||||||
impl RegisterArgument for bool {
|
impl RegisterArgument for bool {
|
||||||
fn from_register(a: Register) -> bool {
|
fn from_register(a: Register) -> bool {
|
||||||
if a != 0 {
|
if a != 0 { true } else { false }
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn into_register(self) -> Register {
|
fn into_register(self) -> Register {
|
||||||
self as _
|
self as _
|
||||||
@@ -152,16 +153,17 @@ impl<T: RegisterArgument> ReturnValue for T {
|
|||||||
|
|
||||||
impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
|
impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
|
||||||
fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self {
|
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 {
|
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`
|
// 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 super::abi::usercalls::{alloc, raw::ByteBuffer};
|
||||||
use crate::ffi::OsString;
|
use crate::ffi::OsString;
|
||||||
|
use crate::slice;
|
||||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use crate::sys::os_str::Buf;
|
use crate::sys::os_str::Buf;
|
||||||
use crate::sys_common::FromInner;
|
use crate::sys_common::FromInner;
|
||||||
use crate::slice;
|
|
||||||
|
|
||||||
#[cfg_attr(test, linkage = "available_externally")]
|
#[cfg_attr(test, linkage = "available_externally")]
|
||||||
#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
|
#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
|
||||||
@@ -14,8 +14,9 @@ type ArgsStore = Vec<OsString>;
|
|||||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||||
if argc != 0 {
|
if argc != 0 {
|
||||||
let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
|
let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
|
||||||
let args = args.iter()
|
let args = args
|
||||||
.map( |a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }) )
|
.iter()
|
||||||
|
.map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))
|
||||||
.collect::<ArgsStore>();
|
.collect::<ArgsStore>();
|
||||||
ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed);
|
ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
@@ -30,11 +31,7 @@ pub unsafe fn cleanup() {
|
|||||||
|
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
|
let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
|
||||||
if let Some(args) = args {
|
if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
|
||||||
Args(args.iter())
|
|
||||||
} else {
|
|
||||||
Args([].iter())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Args(slice::Iter<'static, OsString>);
|
pub struct Args(slice::Iter<'static, OsString>);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![cfg(not(test))]
|
#![cfg(not(test))]
|
||||||
|
|
||||||
// These symbols are all defined in `compiler-builtins`
|
// These symbols are all defined in `compiler-builtins`
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn acos(n: f64) -> f64;
|
pub fn acos(n: f64) -> f64;
|
||||||
pub fn acosf(n: f32) -> f32;
|
pub fn acosf(n: f32) -> f32;
|
||||||
pub fn asin(n: f64) -> f64;
|
pub fn asin(n: f64) -> f64;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details.
|
//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details.
|
||||||
#![unstable(feature = "sgx_platform", issue = "56975")]
|
#![unstable(feature = "sgx_platform", issue = "56975")]
|
||||||
|
|
||||||
pub use crate::sys::abi::usercalls::raw::Fd as RawFd;
|
|
||||||
use crate::net;
|
use crate::net;
|
||||||
|
pub use crate::sys::abi::usercalls::raw::Fd as RawFd;
|
||||||
use crate::sys::{self, AsInner, FromInner, IntoInner, TryIntoInner};
|
use crate::sys::{self, AsInner, FromInner, IntoInner, TryIntoInner};
|
||||||
|
|
||||||
/// A trait to extract the raw SGX file descriptor from an underlying
|
/// 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 {
|
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 {
|
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 {
|
impl FromRawFd for net::TcpStream {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![unstable(feature = "sgx_platform", issue = "56975")]
|
#![unstable(feature = "sgx_platform", issue = "56975")]
|
||||||
|
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
pub mod io;
|
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
|
pub mod io;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use fortanix_sgx_abi::Fd;
|
use fortanix_sgx_abi::Fd;
|
||||||
|
|
||||||
|
use super::abi::usercalls;
|
||||||
use crate::io::{self, IoSlice, IoSliceMut};
|
use crate::io::{self, IoSlice, IoSliceMut};
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::sys::{AsInner, FromInner, IntoInner};
|
use crate::sys::{AsInner, FromInner, IntoInner};
|
||||||
use super::abi::usercalls;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FileDesc {
|
pub struct FileDesc {
|
||||||
@@ -15,7 +15,9 @@ impl FileDesc {
|
|||||||
FileDesc { fd: fd }
|
FileDesc { fd: fd }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw(&self) -> Fd { self.fd }
|
pub fn raw(&self) -> Fd {
|
||||||
|
self.fd
|
||||||
|
}
|
||||||
|
|
||||||
/// Extracts the actual filedescriptor without closing it.
|
/// Extracts the actual filedescriptor without closing it.
|
||||||
pub fn into_raw(self) -> Fd {
|
pub fn into_raw(self) -> Fd {
|
||||||
@@ -46,7 +48,9 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<Fd> for 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 {
|
impl IntoInner<Fd> for FileDesc {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::ffi::OsString;
|
use crate::ffi::OsString;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::hash::{Hash, Hasher};
|
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::path::{Path, PathBuf};
|
||||||
use crate::sys::time::SystemTime;
|
use crate::sys::time::SystemTime;
|
||||||
use crate::sys::{unsupported, Void};
|
use crate::sys::{unsupported, Void};
|
||||||
@@ -15,14 +15,14 @@ pub struct ReadDir(Void);
|
|||||||
pub struct DirEntry(Void);
|
pub struct DirEntry(Void);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct OpenOptions { }
|
pub struct OpenOptions {}
|
||||||
|
|
||||||
pub struct FilePermissions(Void);
|
pub struct FilePermissions(Void);
|
||||||
|
|
||||||
pub struct FileType(Void);
|
pub struct FileType(Void);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DirBuilder { }
|
pub struct DirBuilder {}
|
||||||
|
|
||||||
impl FileAttr {
|
impl FileAttr {
|
||||||
pub fn size(&self) -> u64 {
|
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 {
|
impl fmt::Debug for FilePermissions {
|
||||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
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 {
|
impl Hash for FileType {
|
||||||
fn hash<H: Hasher>(&self, _h: &mut H) {
|
fn hash<H: Hasher>(&self, _h: &mut H) {
|
||||||
@@ -164,15 +162,15 @@ impl DirEntry {
|
|||||||
|
|
||||||
impl OpenOptions {
|
impl OpenOptions {
|
||||||
pub fn new() -> OpenOptions {
|
pub fn new() -> OpenOptions {
|
||||||
OpenOptions { }
|
OpenOptions {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self, _read: bool) { }
|
pub fn read(&mut self, _read: bool) {}
|
||||||
pub fn write(&mut self, _write: bool) { }
|
pub fn write(&mut self, _write: bool) {}
|
||||||
pub fn append(&mut self, _append: bool) { }
|
pub fn append(&mut self, _append: bool) {}
|
||||||
pub fn truncate(&mut self, _truncate: bool) { }
|
pub fn truncate(&mut self, _truncate: bool) {}
|
||||||
pub fn create(&mut self, _create: bool) { }
|
pub fn create(&mut self, _create: bool) {}
|
||||||
pub fn create_new(&mut self, _create_new: bool) { }
|
pub fn create_new(&mut self, _create_new: bool) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
@@ -235,7 +233,7 @@ impl File {
|
|||||||
|
|
||||||
impl DirBuilder {
|
impl DirBuilder {
|
||||||
pub fn new() -> DirBuilder {
|
pub fn new() -> DirBuilder {
|
||||||
DirBuilder { }
|
DirBuilder {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
|
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::convert::TryFrom;
|
||||||
use crate::error;
|
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::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;
|
use super::abi::usercalls;
|
||||||
|
|
||||||
@@ -25,13 +25,15 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<FileDesc> for 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 {
|
impl TryIntoInner<FileDesc> for Socket {
|
||||||
fn try_into_inner(self) -> Result<FileDesc, Socket> {
|
fn try_into_inner(self) -> Result<FileDesc, Socket> {
|
||||||
let Socket { inner, local_addr } = self;
|
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("peer", peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.field("fd", &self.inner.inner.as_inner())
|
res.field("fd", &self.inner.inner.as_inner()).finish()
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,12 +70,14 @@ fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
|
|||||||
Ok(saddr) => Ok(saddr.to_string()),
|
Ok(saddr) => Ok(saddr.to_string()),
|
||||||
// need to downcast twice because io::Error::into_inner doesn't return the original
|
// need to downcast twice because io::Error::into_inner doesn't return the original
|
||||||
// value if the conversion fails
|
// value if the conversion fails
|
||||||
Err(e) => if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
|
Err(e) => {
|
||||||
|
if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
|
||||||
Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
|
Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
|
fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
|
||||||
@@ -94,8 +97,10 @@ impl TcpStream {
|
|||||||
|
|
||||||
pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
|
pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
|
||||||
if dur == Duration::default() {
|
if dur == Duration::default() {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Self::connect(Ok(addr)) // FIXME: ignoring 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<()> {
|
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||||
match dur {
|
match dur {
|
||||||
Some(dur) if dur == Duration::default() => {
|
Some(dur) if dur == Duration::default() => {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
_ => sgx_ineffective(())
|
_ => sgx_ineffective(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||||
match dur {
|
match dur {
|
||||||
Some(dur) if dur == Duration::default() => {
|
Some(dur) if dur == Duration::default() => {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
_ => sgx_ineffective(())
|
_ => sgx_ineffective(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +199,9 @@ impl TcpStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<Socket> for 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
|
// `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("addr", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.field("fd", &self.inner.inner.as_inner())
|
res.field("fd", &self.inner.inner.as_inner()).finish()
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +283,9 @@ impl TcpListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<Socket> for 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 {
|
impl IntoInner<Socket> for TcpListener {
|
||||||
@@ -367,23 +379,19 @@ impl UdpSocket {
|
|||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
match self.0 {}
|
match self.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +436,7 @@ impl fmt::Debug for UdpSocket {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NonIpSockAddr {
|
pub struct NonIpSockAddr {
|
||||||
host: String
|
host: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for NonIpSockAddr {
|
impl error::Error for NonIpSockAddr {
|
||||||
@@ -511,8 +519,7 @@ pub mod netc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct sockaddr {
|
pub struct sockaddr {}
|
||||||
}
|
|
||||||
|
|
||||||
pub type socklen_t = usize;
|
pub type socklen_t = usize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
|
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
|
||||||
|
|
||||||
|
use crate::collections::HashMap;
|
||||||
use crate::error::Error as StdError;
|
use crate::error::Error as StdError;
|
||||||
use crate::ffi::{OsString, OsStr};
|
use crate::ffi::{OsStr, OsString};
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::str;
|
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::atomic::{AtomicUsize, Ordering};
|
||||||
|
use crate::sync::Mutex;
|
||||||
use crate::sync::Once;
|
use crate::sync::Once;
|
||||||
|
use crate::sys::{decode_error_kind, sgx_ineffective, unsupported, Void};
|
||||||
|
use crate::vec;
|
||||||
|
|
||||||
pub fn errno() -> i32 {
|
pub fn errno() -> i32 {
|
||||||
RESULT_SUCCESS
|
RESULT_SUCCESS
|
||||||
@@ -52,7 +52,9 @@ impl<'a> Iterator for SplitPaths<'a> {
|
|||||||
pub struct JoinPathsError;
|
pub struct JoinPathsError;
|
||||||
|
|
||||||
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, 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)
|
Err(JoinPathsError)
|
||||||
}
|
}
|
||||||
@@ -89,26 +91,21 @@ fn create_env_store() -> &'static EnvStore {
|
|||||||
ENV_INIT.call_once(|| {
|
ENV_INIT.call_once(|| {
|
||||||
ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed)
|
ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed)
|
||||||
});
|
});
|
||||||
unsafe {
|
unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) }
|
||||||
&*(ENV.load(Ordering::Relaxed) as *const EnvStore)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Env = vec::IntoIter<(OsString, OsString)>;
|
pub type Env = vec::IntoIter<(OsString, OsString)>;
|
||||||
|
|
||||||
pub fn env() -> Env {
|
pub fn env() -> Env {
|
||||||
let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
|
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()
|
get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default().into_iter()
|
||||||
.map(|env| clone_to_vec(&env.lock().unwrap()) )
|
|
||||||
.unwrap_or_default()
|
|
||||||
.into_iter()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
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<()> {
|
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::path::Prefix;
|
|
||||||
use crate::ffi::OsStr;
|
use crate::ffi::OsStr;
|
||||||
|
use crate::path::Prefix;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_sep_byte(b: u8) -> bool {
|
pub fn is_sep_byte(b: u8) -> bool {
|
||||||
|
|||||||
@@ -32,32 +32,28 @@ pub enum Stdio {
|
|||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn new(_program: &OsStr) -> Command {
|
pub fn new(_program: &OsStr) -> Command {
|
||||||
Command {
|
Command { env: Default::default() }
|
||||||
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 {
|
pub fn env_mut(&mut self) -> &mut CommandEnv {
|
||||||
&mut self.env
|
&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)
|
pub fn spawn(
|
||||||
-> io::Result<(Process, StdioPipes)> {
|
&mut self,
|
||||||
|
_default: Stdio,
|
||||||
|
_needs_stdin: bool,
|
||||||
|
) -> io::Result<(Process, StdioPipes)> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,8 +102,7 @@ impl PartialEq for ExitStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for ExitStatus {
|
impl Eq for ExitStatus {}
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for ExitStatus {
|
impl fmt::Debug for ExitStatus {
|
||||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, allow(dead_code))]
|
#[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 fortanix_sgx_abi as abi;
|
||||||
|
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::sys::fd::FileDesc;
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use crate::slice;
|
use crate::slice;
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use crate::str;
|
use crate::str;
|
||||||
|
use crate::sys::fd::FileDesc;
|
||||||
|
|
||||||
pub struct Stdin(());
|
pub struct Stdin(());
|
||||||
pub struct Stdout(());
|
pub struct Stdout(());
|
||||||
@@ -19,7 +19,9 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stdin {
|
impl Stdin {
|
||||||
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
|
pub fn new() -> io::Result<Stdin> {
|
||||||
|
Ok(Stdin(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Read for Stdin {
|
impl io::Read for Stdin {
|
||||||
@@ -29,7 +31,9 @@ impl io::Read for Stdin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stdout {
|
impl Stdout {
|
||||||
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
|
pub fn new() -> io::Result<Stdout> {
|
||||||
|
Ok(Stdout(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for Stdout {
|
impl io::Write for Stdout {
|
||||||
@@ -43,7 +47,9 @@ impl io::Write for Stdout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stderr {
|
impl Stderr {
|
||||||
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
|
pub fn new() -> io::Result<Stderr> {
|
||||||
|
Ok(Stderr(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for Stderr {
|
impl io::Write for Stderr {
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ pub struct Thread(task_queue::JoinHandle);
|
|||||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
||||||
|
|
||||||
mod task_queue {
|
mod task_queue {
|
||||||
use crate::sync::{Mutex, MutexGuard, Once};
|
|
||||||
use crate::sync::mpsc;
|
use crate::sync::mpsc;
|
||||||
|
use crate::sync::{Mutex, MutexGuard, Once};
|
||||||
|
|
||||||
pub type JoinHandle = mpsc::Receiver<()>;
|
pub type JoinHandle = mpsc::Receiver<()>;
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ mod task_queue {
|
|||||||
|
|
||||||
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
|
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
|
||||||
unsafe {
|
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()
|
TASK_QUEUE.as_ref().unwrap().lock().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,9 +49,7 @@ mod task_queue {
|
|||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>)
|
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||||
-> io::Result<Thread>
|
|
||||||
{
|
|
||||||
let mut queue_lock = task_queue::lock();
|
let mut queue_lock = task_queue::lock();
|
||||||
usercalls::launch_thread()?;
|
usercalls::launch_thread()?;
|
||||||
let (task, handle) = task_queue::Task::new(p);
|
let (task, handle) = task_queue::Task::new(p);
|
||||||
@@ -86,6 +84,10 @@ impl Thread {
|
|||||||
|
|
||||||
pub mod guard {
|
pub mod guard {
|
||||||
pub type Guard = !;
|
pub type Guard = !;
|
||||||
pub unsafe fn current() -> Option<Guard> { None }
|
pub unsafe fn current() -> Option<Guard> {
|
||||||
pub unsafe fn init() -> Option<Guard> { None }
|
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;
|
pub type Key = usize;
|
||||||
|
|
||||||
#[inline]
|
#[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()
|
Tls::create(dtor).as_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::time::Duration;
|
|
||||||
use super::abi::usercalls;
|
use super::abi::usercalls;
|
||||||
|
use crate::time::Duration;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||||
pub struct Instant(Duration);
|
pub struct Instant(Duration);
|
||||||
@@ -40,8 +40,7 @@ impl SystemTime {
|
|||||||
SystemTime(usercalls::insecure_time())
|
SystemTime(usercalls::insecure_time())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub_time(&self, other: &SystemTime)
|
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||||
-> Result<Duration, Duration> {
|
|
||||||
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
|
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::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")]
|
#[stable(feature = "alloc_system_type", since = "1.28.0")]
|
||||||
unsafe impl GlobalAlloc for System {
|
unsafe impl GlobalAlloc for System {
|
||||||
@@ -16,7 +16,7 @@ unsafe impl GlobalAlloc for System {
|
|||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
if layout.align() > (1 << 31) {
|
if layout.align() > (1 << 31) {
|
||||||
return ptr::null_mut()
|
return ptr::null_mut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aligned_malloc(&layout)
|
aligned_malloc(&layout)
|
||||||
@@ -52,9 +52,7 @@ unsafe impl GlobalAlloc for System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android",
|
#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
|
||||||
target_os = "redox",
|
|
||||||
target_os = "solaris"))]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||||
// On android we currently target API level 9 which unfortunately
|
// 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
|
libc::memalign(layout.align(), layout.size()) as *mut u8
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android",
|
#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
|
||||||
target_os = "redox",
|
|
||||||
target_os = "solaris")))]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||||
let mut out = ptr::null_mut();
|
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.
|
// Since these are all powers of 2, we can just use max.
|
||||||
let align = layout.align().max(crate::mem::size_of::<usize>());
|
let align = layout.align().max(crate::mem::size_of::<usize>());
|
||||||
let ret = libc::posix_memalign(&mut out, align, layout.size());
|
let ret = libc::posix_memalign(&mut out, align, layout.size());
|
||||||
if ret != 0 {
|
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
|
||||||
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::{c_int, c_void, sighandler_t, size_t, ssize_t};
|
||||||
use libc::{ftruncate, pread, pwrite};
|
use libc::{ftruncate, pread, pwrite};
|
||||||
|
|
||||||
use crate::io;
|
|
||||||
use super::{cvt, cvt_r};
|
use super::{cvt, cvt_r};
|
||||||
|
use crate::io;
|
||||||
|
|
||||||
// The `log2` and `log2f` functions apparently appeared in android-18, or at
|
// 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
|
// 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(|_| ()),
|
Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()),
|
||||||
None => {
|
None => {
|
||||||
if size > i32::max_value() as u64 {
|
if size > i32::max_value() as u64 {
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot truncate >2GB"))
|
||||||
"cannot truncate >2GB"))
|
|
||||||
} else {
|
} else {
|
||||||
cvt_r(|| ftruncate(fd, size as i32)).map(|_| ())
|
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")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
||||||
unsafe {
|
unsafe { cvt_r(|| ftruncate(fd, size as i64)).map(|_| ()) }
|
||||||
cvt_r(|| ftruncate(fd, size as i64)).map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
pub unsafe fn cvt_pread64(
|
||||||
-> io::Result<ssize_t>
|
fd: c_int,
|
||||||
{
|
buf: *mut c_void,
|
||||||
|
count: size_t,
|
||||||
|
offset: i64,
|
||||||
|
) -> io::Result<ssize_t> {
|
||||||
use crate::convert::TryInto;
|
use crate::convert::TryInto;
|
||||||
weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
|
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(|| {
|
pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||||
if let Ok(o) = offset.try_into() {
|
if let Ok(o) = offset.try_into() {
|
||||||
cvt(pread(fd, buf, count, o))
|
cvt(pread(fd, buf, count, o))
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot pread >2GB"))
|
||||||
"cannot pread >2GB"))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
pub unsafe fn cvt_pwrite64(
|
||||||
-> io::Result<ssize_t>
|
fd: c_int,
|
||||||
{
|
buf: *const c_void,
|
||||||
|
count: size_t,
|
||||||
|
offset: i64,
|
||||||
|
) -> io::Result<ssize_t> {
|
||||||
use crate::convert::TryInto;
|
use crate::convert::TryInto;
|
||||||
weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
|
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(|| {
|
pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||||
if let Ok(o) = offset.try_into() {
|
if let Ok(o) = offset.try_into() {
|
||||||
cvt(pwrite(fd, buf, count, o))
|
cvt(pwrite(fd, buf, count, o))
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot pwrite >2GB"))
|
||||||
"cannot pwrite >2GB"))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
pub unsafe fn cvt_pread64(
|
||||||
-> io::Result<ssize_t>
|
fd: c_int,
|
||||||
{
|
buf: *mut c_void,
|
||||||
|
count: size_t,
|
||||||
|
offset: i64,
|
||||||
|
) -> io::Result<ssize_t> {
|
||||||
cvt(pread(fd, buf, count, offset))
|
cvt(pread(fd, buf, count, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
pub unsafe fn cvt_pwrite64(
|
||||||
-> io::Result<ssize_t>
|
fd: c_int,
|
||||||
{
|
buf: *const c_void,
|
||||||
|
count: size_t,
|
||||||
|
offset: i64,
|
||||||
|
) -> io::Result<ssize_t> {
|
||||||
cvt(pwrite(fd, buf, count, offset))
|
cvt(pwrite(fd, buf, count, offset))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#![cfg(not(test))]
|
#![cfg(not(test))]
|
||||||
|
|
||||||
use libc::{c_float, c_double};
|
use libc::{c_double, c_float};
|
||||||
|
|
||||||
#[link_name = "m"]
|
#[link_name = "m"]
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn acos(n: c_double) -> c_double;
|
pub fn acos(n: c_double) -> c_double;
|
||||||
pub fn acosf(n: c_float) -> c_float;
|
pub fn acosf(n: c_float) -> c_float;
|
||||||
pub fn asin(n: c_double) -> c_double;
|
pub fn asin(n: c_double) -> c_double;
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use crate::fs::{self, Permissions, OpenOptions};
|
use crate::fs::{self, OpenOptions, Permissions};
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::path::Path;
|
use crate::path::Path;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::sys_common::{FromInner, AsInner, AsInnerMut};
|
|
||||||
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
|
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
|
||||||
|
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
|
||||||
|
|
||||||
/// Unix-specific extensions to [`File`].
|
/// Unix-specific extensions to [`File`].
|
||||||
///
|
///
|
||||||
@@ -112,8 +112,7 @@ pub trait FileExt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !buf.is_empty() {
|
if !buf.is_empty() {
|
||||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
|
||||||
"failed to fill whole buffer"))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -195,8 +194,12 @@ pub trait FileExt {
|
|||||||
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
|
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
|
||||||
while !buf.is_empty() {
|
while !buf.is_empty() {
|
||||||
match self.write_at(buf, offset) {
|
match self.write_at(buf, offset) {
|
||||||
Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
|
Ok(0) => {
|
||||||
"failed to write whole buffer")),
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::WriteZero,
|
||||||
|
"failed to write whole buffer",
|
||||||
|
));
|
||||||
|
}
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
buf = &buf[n..];
|
buf = &buf[n..];
|
||||||
offset += n as u64
|
offset += n as u64
|
||||||
@@ -356,11 +359,13 @@ pub trait OpenOptionsExt {
|
|||||||
#[stable(feature = "fs_ext", since = "1.1.0")]
|
#[stable(feature = "fs_ext", since = "1.1.0")]
|
||||||
impl OpenOptionsExt for OpenOptions {
|
impl OpenOptionsExt for OpenOptions {
|
||||||
fn mode(&mut self, mode: u32) -> &mut 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 {
|
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")]
|
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||||
impl MetadataExt for fs::Metadata {
|
impl MetadataExt for fs::Metadata {
|
||||||
fn dev(&self) -> u64 { self.st_dev() }
|
fn dev(&self) -> u64 {
|
||||||
fn ino(&self) -> u64 { self.st_ino() }
|
self.st_dev()
|
||||||
fn mode(&self) -> u32 { self.st_mode() }
|
}
|
||||||
fn nlink(&self) -> u64 { self.st_nlink() }
|
fn ino(&self) -> u64 {
|
||||||
fn uid(&self) -> u32 { self.st_uid() }
|
self.st_ino()
|
||||||
fn gid(&self) -> u32 { self.st_gid() }
|
}
|
||||||
fn rdev(&self) -> u64 { self.st_rdev() }
|
fn mode(&self) -> u32 {
|
||||||
fn size(&self) -> u64 { self.st_size() }
|
self.st_mode()
|
||||||
fn atime(&self) -> i64 { self.st_atime() }
|
}
|
||||||
fn atime_nsec(&self) -> i64 { self.st_atime_nsec() }
|
fn nlink(&self) -> u64 {
|
||||||
fn mtime(&self) -> i64 { self.st_mtime() }
|
self.st_nlink()
|
||||||
fn mtime_nsec(&self) -> i64 { self.st_mtime_nsec() }
|
}
|
||||||
fn ctime(&self) -> i64 { self.st_ctime() }
|
fn uid(&self) -> u32 {
|
||||||
fn ctime_nsec(&self) -> i64 { self.st_ctime_nsec() }
|
self.st_uid()
|
||||||
fn blksize(&self) -> u64 { self.st_blksize() }
|
}
|
||||||
fn blocks(&self) -> u64 { self.st_blocks() }
|
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`].
|
/// Unix-specific extensions for [`FileType`].
|
||||||
@@ -759,10 +796,18 @@ pub trait FileTypeExt {
|
|||||||
|
|
||||||
#[stable(feature = "file_type_ext", since = "1.5.0")]
|
#[stable(feature = "file_type_ext", since = "1.5.0")]
|
||||||
impl FileTypeExt for fs::FileType {
|
impl FileTypeExt for fs::FileType {
|
||||||
fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
|
fn is_block_device(&self) -> bool {
|
||||||
fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
|
self.as_inner().is(libc::S_IFBLK)
|
||||||
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_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`].
|
/// Unix-specific extension methods for [`fs::DirEntry`].
|
||||||
@@ -794,7 +839,9 @@ pub trait DirEntryExt {
|
|||||||
|
|
||||||
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
|
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
|
||||||
impl DirEntryExt for fs::DirEntry {
|
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.
|
/// Creates a new symbolic link on the filesystem.
|
||||||
@@ -821,8 +868,7 @@ impl DirEntryExt for fs::DirEntry {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "symlink", since = "1.1.0")]
|
#[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())
|
sys::fs::symlink(src.as_ref(), dst.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use crate::fs;
|
use crate::fs;
|
||||||
|
use crate::io;
|
||||||
use crate::os::raw;
|
use crate::os::raw;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::io;
|
|
||||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||||
|
|
||||||
/// Raw file descriptors.
|
/// Raw file descriptors.
|
||||||
@@ -83,30 +83,42 @@ impl IntoRawFd for fs::File {
|
|||||||
|
|
||||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
impl AsRawFd for io::Stdin {
|
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")]
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
impl AsRawFd for io::Stdout {
|
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")]
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
impl AsRawFd for io::Stderr {
|
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")]
|
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||||
impl<'a> AsRawFd for io::StdinLock<'a> {
|
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")]
|
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||||
impl<'a> AsRawFd for io::StdoutLock<'a> {
|
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")]
|
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||||
impl<'a> AsRawFd for io::StderrLock<'a> {
|
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::ffi::OsStr;
|
||||||
use crate::io;
|
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::process;
|
||||||
use crate::sys;
|
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.
|
/// Unix-specific extensions to the [`process::Command`] builder.
|
||||||
///
|
///
|
||||||
@@ -56,7 +56,8 @@ pub trait CommandExt {
|
|||||||
/// locations may not appear where intended.
|
/// locations may not appear where intended.
|
||||||
#[stable(feature = "process_pre_exec", since = "1.34.0")]
|
#[stable(feature = "process_pre_exec", since = "1.34.0")]
|
||||||
unsafe fn pre_exec<F>(&mut self, f: F) -> &mut 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;
|
||||||
|
|
||||||
/// Schedules a closure to be run just before the `exec` function is
|
/// Schedules a closure to be run just before the `exec` function is
|
||||||
/// invoked.
|
/// invoked.
|
||||||
@@ -68,7 +69,8 @@ pub trait CommandExt {
|
|||||||
#[stable(feature = "process_exec", since = "1.15.0")]
|
#[stable(feature = "process_exec", since = "1.15.0")]
|
||||||
#[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
|
#[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
|
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) }
|
unsafe { self.pre_exec(f) }
|
||||||
}
|
}
|
||||||
@@ -111,7 +113,8 @@ pub trait CommandExt {
|
|||||||
/// default executable path.
|
/// default executable path.
|
||||||
#[unstable(feature = "process_set_argv0", issue = "66510")]
|
#[unstable(feature = "process_set_argv0", issue = "66510")]
|
||||||
fn arg0<S>(&mut self, arg: S) -> &mut process::Command
|
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")]
|
#[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
|
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.as_inner_mut().pre_exec(Box::new(f));
|
||||||
self
|
self
|
||||||
@@ -138,7 +142,8 @@ impl CommandExt for process::Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn arg0<S>(&mut self, arg: S) -> &mut 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.as_inner_mut().set_arg_0(arg.as_ref());
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -1,23 +1,28 @@
|
|||||||
//! Unix-specific primitives available on all unix platforms
|
//! Unix-specific primitives available on all unix platforms
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")]
|
#![stable(feature = "raw_ext", since = "1.1.0")]
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
#![rustc_deprecated(
|
||||||
|
since = "1.8.0",
|
||||||
reason = "these type aliases are no longer supported by \
|
reason = "these type aliases are no longer supported by \
|
||||||
the standard library, the `libc` crate on \
|
the standard library, the `libc` crate on \
|
||||||
crates.io should be used instead for the correct \
|
crates.io should be used instead for the correct \
|
||||||
definitions")]
|
definitions"
|
||||||
|
)]
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type uid_t = u32;
|
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type gid_t = u32;
|
pub type uid_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 gid_t = u32;
|
||||||
|
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||||
|
pub type pid_t = i32;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")]
|
#[stable(feature = "pthread_t", since = "1.8.0")]
|
||||||
pub use crate::sys::platform::raw::pthread_t;
|
pub use crate::sys::platform::raw::pthread_t;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
#[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)]
|
#[doc(inline)]
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")]
|
#[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.
|
// fallback implementation to use as well.
|
||||||
//
|
//
|
||||||
// Due to rust-lang/rust#18804, make sure this is not generic!
|
// Due to rust-lang/rust#18804, make sure this is not generic!
|
||||||
#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox",
|
#[cfg(any(
|
||||||
target_os = "emscripten"))]
|
target_os = "linux",
|
||||||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
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::mem;
|
||||||
use crate::sys_common::thread_local::register_dtor_fallback;
|
use crate::sys_common::thread_local::register_dtor_fallback;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
#[linkage = "extern_weak"]
|
#[linkage = "extern_weak"]
|
||||||
static __dso_handle: *mut u8;
|
static __dso_handle: *mut u8;
|
||||||
#[linkage = "extern_weak"]
|
#[linkage = "extern_weak"]
|
||||||
static __cxa_thread_atexit_impl: *const libc::c_void;
|
static __cxa_thread_atexit_impl: *const libc::c_void;
|
||||||
}
|
}
|
||||||
if !__cxa_thread_atexit_impl.is_null() {
|
if !__cxa_thread_atexit_impl.is_null() {
|
||||||
type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
|
type F = unsafe extern "C" fn(
|
||||||
|
dtor: unsafe extern "C" fn(*mut u8),
|
||||||
arg: *mut u8,
|
arg: *mut u8,
|
||||||
dso_handle: *mut u8) -> libc::c_int;
|
dso_handle: *mut u8,
|
||||||
mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
|
) -> libc::c_int;
|
||||||
(dtor, t, &__dso_handle as *const _ as *mut _);
|
mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)(
|
||||||
return
|
dtor,
|
||||||
|
t,
|
||||||
|
&__dso_handle as *const _ as *mut _,
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
register_dtor_fallback(t, dtor);
|
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
|
// thread. thread_local dtors are pushed to the DTOR list without calling
|
||||||
// _tlv_atexit.
|
// _tlv_atexit.
|
||||||
#[cfg(target_os = "macos")]
|
#[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::cell::Cell;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
||||||
@@ -55,7 +64,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
|
|||||||
REGISTERED.set(true);
|
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]
|
#[thread_local]
|
||||||
static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut());
|
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));
|
DTORS.set(Box::into_raw(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
|
fn _tlv_atexit(dtor: unsafe extern "C" fn(*mut u8), arg: *mut u8);
|
||||||
arg: *mut u8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let list: &mut List = &mut *DTORS.get();
|
let list: &mut List = &mut *DTORS.get();
|
||||||
list.push((t, dtor));
|
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());
|
let mut ptr = DTORS.replace(ptr::null_mut());
|
||||||
while !ptr.is_null() {
|
while !ptr.is_null() {
|
||||||
let list = Box::from_raw(ptr);
|
let list = Box::from_raw(ptr);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
||||||
|
|
||||||
use crate::cmp;
|
use crate::cmp;
|
||||||
use crate::io::{self, Read, Initializer, IoSlice, IoSliceMut};
|
use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
@@ -35,7 +35,9 @@ impl FileDesc {
|
|||||||
FileDesc { fd }
|
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.
|
/// Extracts the actual file descriptor without closing it.
|
||||||
pub fn into_raw(self) -> c_int {
|
pub fn into_raw(self) -> c_int {
|
||||||
@@ -46,18 +48,18 @@ impl FileDesc {
|
|||||||
|
|
||||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::read(self.fd,
|
libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
|
||||||
cmp::min(buf.len(), max_len()))
|
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::readv(self.fd,
|
libc::readv(
|
||||||
|
self.fd,
|
||||||
bufs.as_ptr() as *const libc::iovec,
|
bufs.as_ptr() as *const libc::iovec,
|
||||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
@@ -72,39 +74,44 @@ impl FileDesc {
|
|||||||
use super::android::cvt_pread64;
|
use super::android::cvt_pread64;
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
|
unsafe fn cvt_pread64(
|
||||||
-> io::Result<isize>
|
fd: c_int,
|
||||||
{
|
buf: *mut c_void,
|
||||||
#[cfg(target_os = "linux")]
|
count: usize,
|
||||||
use libc::pread64;
|
offset: i64,
|
||||||
|
) -> io::Result<isize> {
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
use libc::pread as pread64;
|
use libc::pread as pread64;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use libc::pread64;
|
||||||
cvt(pread64(fd, buf, count, offset))
|
cvt(pread64(fd, buf, count, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt_pread64(self.fd,
|
cvt_pread64(
|
||||||
|
self.fd,
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
buf.as_mut_ptr() as *mut c_void,
|
||||||
cmp::min(buf.len(), max_len()),
|
cmp::min(buf.len(), max_len()),
|
||||||
offset as i64)
|
offset as i64,
|
||||||
|
)
|
||||||
.map(|n| n as usize)
|
.map(|n| n as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::write(self.fd,
|
libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
|
||||||
buf.as_ptr() as *const c_void,
|
|
||||||
cmp::min(buf.len(), max_len()))
|
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::writev(self.fd,
|
libc::writev(
|
||||||
|
self.fd,
|
||||||
bufs.as_ptr() as *const libc::iovec,
|
bufs.as_ptr() as *const libc::iovec,
|
||||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
@@ -114,54 +121,61 @@ impl FileDesc {
|
|||||||
use super::android::cvt_pwrite64;
|
use super::android::cvt_pwrite64;
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
|
unsafe fn cvt_pwrite64(
|
||||||
-> io::Result<isize>
|
fd: c_int,
|
||||||
{
|
buf: *const c_void,
|
||||||
#[cfg(target_os = "linux")]
|
count: usize,
|
||||||
use libc::pwrite64;
|
offset: i64,
|
||||||
|
) -> io::Result<isize> {
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
use libc::pwrite as pwrite64;
|
use libc::pwrite as pwrite64;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use libc::pwrite64;
|
||||||
cvt(pwrite64(fd, buf, count, offset))
|
cvt(pwrite64(fd, buf, count, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt_pwrite64(self.fd,
|
cvt_pwrite64(
|
||||||
|
self.fd,
|
||||||
buf.as_ptr() as *const c_void,
|
buf.as_ptr() as *const c_void,
|
||||||
cmp::min(buf.len(), max_len()),
|
cmp::min(buf.len(), max_len()),
|
||||||
offset as i64)
|
offset as i64,
|
||||||
|
)
|
||||||
.map(|n| n as usize)
|
.map(|n| n as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn get_cloexec(&self) -> io::Result<bool> {
|
pub fn get_cloexec(&self) -> io::Result<bool> {
|
||||||
unsafe {
|
unsafe { Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
|
||||||
Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_env = "newlib",
|
#[cfg(not(any(
|
||||||
|
target_env = "newlib",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
target_os = "l4re",
|
target_os = "l4re",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "redox")))]
|
target_os = "redox"
|
||||||
|
)))]
|
||||||
pub fn set_cloexec(&self) -> io::Result<()> {
|
pub fn set_cloexec(&self) -> io::Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt(libc::ioctl(self.fd, libc::FIOCLEX))?;
|
cvt(libc::ioctl(self.fd, libc::FIOCLEX))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(any(target_env = "newlib",
|
#[cfg(any(
|
||||||
|
target_env = "newlib",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
target_os = "l4re",
|
target_os = "l4re",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "redox"))]
|
target_os = "redox"
|
||||||
|
))]
|
||||||
pub fn set_cloexec(&self) -> io::Result<()> {
|
pub fn set_cloexec(&self) -> io::Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
|
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
|
// [1]: http://comments.gmane.org/gmane.linux.lib.musl.general/2963
|
||||||
#[cfg(any(target_os = "android", target_os = "haiku"))]
|
#[cfg(any(target_os = "android", target_os = "haiku"))]
|
||||||
use libc::F_DUPFD as F_DUPFD_CLOEXEC;
|
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;
|
use libc::F_DUPFD_CLOEXEC;
|
||||||
|
|
||||||
let make_filedesc = |fd| {
|
let make_filedesc = |fd| {
|
||||||
@@ -224,8 +238,7 @@ impl FileDesc {
|
|||||||
fd.set_cloexec()?;
|
fd.set_cloexec()?;
|
||||||
Ok(fd)
|
Ok(fd)
|
||||||
};
|
};
|
||||||
static TRY_CLOEXEC: AtomicBool =
|
static TRY_CLOEXEC: AtomicBool = AtomicBool::new(!cfg!(target_os = "android"));
|
||||||
AtomicBool::new(!cfg!(target_os = "android"));
|
|
||||||
let fd = self.raw();
|
let fd = self.raw();
|
||||||
if TRY_CLOEXEC.load(Ordering::Relaxed) {
|
if TRY_CLOEXEC.load(Ordering::Relaxed) {
|
||||||
match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) {
|
match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) {
|
||||||
@@ -237,7 +250,7 @@ impl FileDesc {
|
|||||||
make_filedesc(fd)?
|
make_filedesc(fd)?
|
||||||
} else {
|
} else {
|
||||||
FileDesc::new(fd)
|
FileDesc::new(fd)
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
|
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
|
||||||
TRY_CLOEXEC.store(false, Ordering::Relaxed);
|
TRY_CLOEXEC.store(false, Ordering::Relaxed);
|
||||||
@@ -261,7 +274,9 @@ impl<'a> Read for &'a FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<c_int> for 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 {
|
impl Drop for FileDesc {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use crate::slice;
|
use crate::slice;
|
||||||
|
|
||||||
use libc::{iovec, c_void};
|
use libc::{c_void, iovec};
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct IoSlice<'a> {
|
pub struct IoSlice<'a> {
|
||||||
@@ -13,10 +13,7 @@ impl<'a> IoSlice<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||||
IoSlice {
|
IoSlice {
|
||||||
vec: iovec {
|
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
|
||||||
iov_base: buf.as_ptr() as *mut u8 as *mut c_void,
|
|
||||||
iov_len: buf.len()
|
|
||||||
},
|
|
||||||
_p: PhantomData,
|
_p: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,9 +32,7 @@ impl<'a> IoSlice<'a> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe {
|
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +46,7 @@ impl<'a> IoSliceMut<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||||
IoSliceMut {
|
IoSliceMut {
|
||||||
vec: iovec {
|
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
|
||||||
iov_base: buf.as_mut_ptr() as *mut c_void,
|
|
||||||
iov_len: buf.len()
|
|
||||||
},
|
|
||||||
_p: PhantomData,
|
_p: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,15 +65,11 @@ impl<'a> IoSliceMut<'a> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe {
|
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
unsafe {
|
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
macro_rules! unimpl {
|
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 {
|
pub mod net {
|
||||||
#![allow(warnings)]
|
#![allow(warnings)]
|
||||||
|
use crate::convert::TryFrom;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io::{self, IoSlice, IoSliceMut};
|
use crate::io::{self, IoSlice, IoSliceMut};
|
||||||
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
|
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
|
||||||
use crate::sys::fd::FileDesc;
|
use crate::sys::fd::FileDesc;
|
||||||
|
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
use crate::convert::TryFrom;
|
|
||||||
|
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
pub extern crate libc as netc;
|
pub extern crate libc as netc;
|
||||||
@@ -33,8 +35,11 @@ pub mod net {
|
|||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t)
|
pub fn accept(
|
||||||
-> io::Result<Socket> {
|
&self,
|
||||||
|
_: *mut libc::sockaddr,
|
||||||
|
_: *mut libc::socklen_t,
|
||||||
|
) -> io::Result<Socket> {
|
||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,15 +105,21 @@ pub mod net {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<libc::c_int> for Socket {
|
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 {
|
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 {
|
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 {
|
pub struct TcpStream {
|
||||||
@@ -124,9 +135,13 @@ pub mod net {
|
|||||||
unimpl!();
|
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<()> {
|
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||||
unimpl!();
|
unimpl!();
|
||||||
@@ -226,9 +241,13 @@ pub mod net {
|
|||||||
unimpl!();
|
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> {
|
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||||
unimpl!();
|
unimpl!();
|
||||||
@@ -288,9 +307,13 @@ pub mod net {
|
|||||||
unimpl!();
|
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> {
|
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||||
unimpl!();
|
unimpl!();
|
||||||
@@ -364,23 +387,19 @@ pub mod net {
|
|||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
||||||
-> io::Result<()> {
|
|
||||||
unimpl!();
|
unimpl!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,7 +469,6 @@ pub mod net {
|
|||||||
unsafe impl Sync for LookupHost {}
|
unsafe impl Sync for LookupHost {}
|
||||||
unsafe impl Send for LookupHost {}
|
unsafe impl Send for LookupHost {}
|
||||||
|
|
||||||
|
|
||||||
impl TryFrom<&str> for LookupHost {
|
impl TryFrom<&str> for LookupHost {
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
|
|||||||
@@ -6,32 +6,27 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
|||||||
libc::memchr(
|
libc::memchr(
|
||||||
haystack.as_ptr() as *const libc::c_void,
|
haystack.as_ptr() as *const libc::c_void,
|
||||||
needle as libc::c_int,
|
needle as libc::c_int,
|
||||||
haystack.len())
|
haystack.len(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
if p.is_null() {
|
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(p as usize - (haystack.as_ptr() as usize))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
|
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||||
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
|
// 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 {
|
let p = unsafe {
|
||||||
libc::memrchr(
|
libc::memrchr(
|
||||||
haystack.as_ptr() as *const libc::c_void,
|
haystack.as_ptr() as *const libc::c_void,
|
||||||
needle as libc::c_int,
|
needle as libc::c_int,
|
||||||
haystack.len())
|
haystack.len(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
if p.is_null() {
|
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(p as usize - (haystack.as_ptr() as usize))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
use crate::cmp;
|
||||||
use crate::ffi::CStr;
|
use crate::ffi::CStr;
|
||||||
use crate::io::{self, IoSlice, IoSliceMut};
|
use crate::io::{self, IoSlice, IoSliceMut};
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::net::{SocketAddr, Shutdown};
|
use crate::net::{Shutdown, SocketAddr};
|
||||||
use crate::str;
|
use crate::str;
|
||||||
use crate::sys::fd::FileDesc;
|
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::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||||
|
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||||
use crate::time::{Duration, Instant};
|
use crate::time::{Duration, Instant};
|
||||||
use crate::cmp;
|
|
||||||
|
|
||||||
use libc::{c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
|
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<()> {
|
pub fn cvt_gai(err: c_int) -> io::Result<()> {
|
||||||
if err == 0 {
|
if err == 0 {
|
||||||
return Ok(())
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
|
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
|
||||||
on_resolver_failure();
|
on_resolver_failure();
|
||||||
|
|
||||||
if err == EAI_SYSTEM {
|
if err == EAI_SYSTEM {
|
||||||
return Err(io::Error::last_os_error())
|
return Err(io::Error::last_os_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
let detail = unsafe {
|
let detail = unsafe {
|
||||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
|
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap().to_owned()
|
||||||
.to_owned()
|
|
||||||
};
|
};
|
||||||
Err(io::Error::new(io::ErrorKind::Other,
|
Err(io::Error::new(
|
||||||
&format!("failed to lookup address information: {}",
|
io::ErrorKind::Other,
|
||||||
detail)[..]))
|
&format!("failed to lookup address information: {}", detail)[..],
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socket {
|
impl Socket {
|
||||||
@@ -106,7 +106,7 @@ impl Socket {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
|
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),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,15 +135,13 @@ impl Socket {
|
|||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pollfd = libc::pollfd {
|
let mut pollfd = libc::pollfd { fd: self.0.raw(), events: libc::POLLOUT, revents: 0 };
|
||||||
fd: self.0.raw(),
|
|
||||||
events: libc::POLLOUT,
|
|
||||||
revents: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
@@ -155,7 +153,8 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let timeout = timeout - elapsed;
|
let timeout = timeout - elapsed;
|
||||||
let mut timeout = timeout.as_secs()
|
let mut timeout = timeout
|
||||||
|
.as_secs()
|
||||||
.saturating_mul(1_000)
|
.saturating_mul(1_000)
|
||||||
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
@@ -176,8 +175,7 @@ impl Socket {
|
|||||||
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
||||||
// for POLLHUP rather than read readiness
|
// for POLLHUP rather than read readiness
|
||||||
if pollfd.revents & libc::POLLHUP != 0 {
|
if pollfd.revents & libc::POLLHUP != 0 {
|
||||||
let e = self.take_error()?
|
let e = self.take_error()?.unwrap_or_else(|| {
|
||||||
.unwrap_or_else(|| {
|
|
||||||
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
||||||
});
|
});
|
||||||
return Err(e);
|
return Err(e);
|
||||||
@@ -189,8 +187,7 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
|
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
|
||||||
-> io::Result<Socket> {
|
|
||||||
// Unfortunately the only known way right now to accept a socket and
|
// Unfortunately the only known way right now to accept a socket and
|
||||||
// atomically set the CLOEXEC flag is to use the `accept4` syscall on
|
// 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
|
// Linux. This was added in 2.6.28, however, and because we support
|
||||||
@@ -204,9 +201,7 @@ impl Socket {
|
|||||||
flags: c_int
|
flags: c_int
|
||||||
) -> c_int
|
) -> c_int
|
||||||
}
|
}
|
||||||
let res = cvt_r(|| unsafe {
|
let res = cvt_r(|| unsafe { accept4(self.0.raw(), storage, len, SOCK_CLOEXEC) });
|
||||||
accept4(self.0.raw(), storage, len, SOCK_CLOEXEC)
|
|
||||||
});
|
|
||||||
match res {
|
match res {
|
||||||
Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
|
Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
|
||||||
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
|
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
|
||||||
@@ -214,9 +209,7 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fd = cvt_r(|| unsafe {
|
let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?;
|
||||||
libc::accept(self.0.raw(), storage, len)
|
|
||||||
})?;
|
|
||||||
let fd = FileDesc::new(fd);
|
let fd = FileDesc::new(fd);
|
||||||
fd.set_cloexec()?;
|
fd.set_cloexec()?;
|
||||||
Ok(Socket(fd))
|
Ok(Socket(fd))
|
||||||
@@ -228,10 +221,7 @@ impl Socket {
|
|||||||
|
|
||||||
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::recv(self.0.raw(),
|
libc::recv(self.0.raw(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags)
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
|
||||||
buf.len(),
|
|
||||||
flags)
|
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
@@ -248,18 +238,23 @@ impl Socket {
|
|||||||
self.0.read_vectored(bufs)
|
self.0.read_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
|
fn recv_from_with_flags(
|
||||||
-> io::Result<(usize, SocketAddr)> {
|
&self,
|
||||||
|
buf: &mut [u8],
|
||||||
|
flags: c_int,
|
||||||
|
) -> io::Result<(usize, SocketAddr)> {
|
||||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||||
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
|
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
|
||||||
|
|
||||||
let n = cvt(unsafe {
|
let n = cvt(unsafe {
|
||||||
libc::recvfrom(self.0.raw(),
|
libc::recvfrom(
|
||||||
|
self.0.raw(),
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
buf.as_mut_ptr() as *mut c_void,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
flags,
|
flags,
|
||||||
&mut storage as *mut _ as *mut _,
|
&mut storage as *mut _ as *mut _,
|
||||||
&mut addrlen)
|
&mut addrlen,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||||
}
|
}
|
||||||
@@ -284,8 +279,10 @@ impl Socket {
|
|||||||
let timeout = match dur {
|
let timeout = match dur {
|
||||||
Some(dur) => {
|
Some(dur) => {
|
||||||
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
|
let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
|
||||||
@@ -302,12 +299,7 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
timeout
|
timeout
|
||||||
}
|
}
|
||||||
None => {
|
None => libc::timeval { tv_sec: 0, tv_usec: 0 },
|
||||||
libc::timeval {
|
|
||||||
tv_sec: 0,
|
|
||||||
tv_usec: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
||||||
}
|
}
|
||||||
@@ -349,24 +341,26 @@ impl Socket {
|
|||||||
|
|
||||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
|
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
|
||||||
if raw == 0 {
|
if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Ok(Some(io::Error::from_raw_os_error(raw as i32)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<c_int> for Socket {
|
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 {
|
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 {
|
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
|
// 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::ffi::OsStr;
|
||||||
|
use crate::path::Prefix;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_sep_byte(b: u8) -> bool {
|
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
|
// 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
|
// 2.6.27, however, and because we support 2.6.18 we must detect this
|
||||||
// support dynamically.
|
// support dynamically.
|
||||||
if cfg!(any(target_os = "dragonfly",
|
if cfg!(any(
|
||||||
|
target_os = "dragonfly",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "redox")) &&
|
target_os = "redox"
|
||||||
!INVALID.load(Ordering::SeqCst)
|
)) && !INVALID.load(Ordering::SeqCst)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Note that despite calling a glibc function here we may still
|
// Note that despite calling a glibc function here we may still
|
||||||
// get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
|
// 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
|
// 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.
|
// see the syscall.
|
||||||
match cvt(unsafe { pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
|
match cvt(unsafe { pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
return Ok((AnonPipe(FileDesc::new(fds[0])),
|
return Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1]))));
|
||||||
AnonPipe(FileDesc::new(fds[1]))));
|
|
||||||
}
|
}
|
||||||
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
|
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
|
||||||
INVALID.store(true, Ordering::SeqCst);
|
INVALID.store(true, Ordering::SeqCst);
|
||||||
@@ -73,15 +72,15 @@ impl AnonPipe {
|
|||||||
self.0.write_vectored(bufs)
|
self.0.write_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
pub fn fd(&self) -> &FileDesc {
|
||||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
&self.0
|
||||||
|
}
|
||||||
|
pub fn into_fd(self) -> FileDesc {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read2(p1: AnonPipe,
|
pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
|
||||||
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
|
// 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!
|
// in the `select` loop below, and we wouldn't want one to block the other!
|
||||||
let p1 = p1.into_fd();
|
let p1 = p1.into_fd();
|
||||||
@@ -117,8 +116,9 @@ pub fn read2(p1: AnonPipe,
|
|||||||
match fd.read_to_end(dst) {
|
match fd.read_to_end(dst) {
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
|
if e.raw_os_error() == Some(libc::EWOULDBLOCK)
|
||||||
e.raw_os_error() == Some(libc::EAGAIN) {
|
|| e.raw_os_error() == Some(libc::EAGAIN)
|
||||||
|
{
|
||||||
Ok(false)
|
Ok(false)
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::os::unix::prelude::*;
|
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::fmt;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
@@ -8,12 +9,11 @@ use crate::sys::fd::FileDesc;
|
|||||||
use crate::sys::fs::File;
|
use crate::sys::fs::File;
|
||||||
use crate::sys::pipe::{self, AnonPipe};
|
use crate::sys::pipe::{self, AnonPipe};
|
||||||
use crate::sys_common::process::CommandEnv;
|
use crate::sys_common::process::CommandEnv;
|
||||||
use crate::collections::BTreeMap;
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "fuchsia"))]
|
#[cfg(not(target_os = "fuchsia"))]
|
||||||
use crate::sys::fs::OpenOptions;
|
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! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "fuchsia")] {
|
if #[cfg(target_os = "fuchsia")] {
|
||||||
@@ -204,10 +204,7 @@ impl Command {
|
|||||||
&mut self.closures
|
&mut self.closures
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn pre_exec(
|
pub unsafe fn pre_exec(&mut self, f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
|
||||||
&mut self,
|
|
||||||
f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>,
|
|
||||||
) {
|
|
||||||
self.closures.push(f);
|
self.closures.push(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,26 +233,21 @@ impl Command {
|
|||||||
self.env.have_changed_path()
|
self.env.have_changed_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
|
pub fn setup_io(
|
||||||
-> io::Result<(StdioPipes, ChildPipes)> {
|
&self,
|
||||||
|
default: Stdio,
|
||||||
|
needs_stdin: bool,
|
||||||
|
) -> io::Result<(StdioPipes, ChildPipes)> {
|
||||||
let null = Stdio::Null;
|
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 stdin = self.stdin.as_ref().unwrap_or(default_stdin);
|
||||||
let stdout = self.stdout.as_ref().unwrap_or(&default);
|
let stdout = self.stdout.as_ref().unwrap_or(&default);
|
||||||
let stderr = self.stderr.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_stdin, our_stdin) = stdin.to_child_stdio(true)?;
|
||||||
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
|
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
|
||||||
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
|
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
|
||||||
let ours = StdioPipes {
|
let ours = StdioPipes { stdin: our_stdin, stdout: our_stdout, stderr: our_stderr };
|
||||||
stdin: our_stdin,
|
let theirs = ChildPipes { stdin: their_stdin, stdout: their_stdout, stderr: their_stderr };
|
||||||
stdout: our_stdout,
|
|
||||||
stderr: our_stderr,
|
|
||||||
};
|
|
||||||
let theirs = ChildPipes {
|
|
||||||
stdin: their_stdin,
|
|
||||||
stdout: their_stdout,
|
|
||||||
stderr: their_stderr,
|
|
||||||
};
|
|
||||||
Ok((ours, theirs))
|
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.
|
// Helper type to manage ownership of the strings within a C-style array.
|
||||||
pub struct CStringArray {
|
pub struct CStringArray {
|
||||||
items: Vec<CString>,
|
items: Vec<CString>,
|
||||||
ptrs: Vec<*const c_char>
|
ptrs: Vec<*const c_char>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CStringArray {
|
impl CStringArray {
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
let mut result = CStringArray {
|
let mut result = CStringArray {
|
||||||
items: Vec::with_capacity(capacity),
|
items: Vec::with_capacity(capacity),
|
||||||
ptrs: Vec::with_capacity(capacity+1)
|
ptrs: Vec::with_capacity(capacity + 1),
|
||||||
};
|
};
|
||||||
result.ptrs.push(ptr::null());
|
result.ptrs.push(ptr::null());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn push(&mut self, item: CString) {
|
pub fn push(&mut self, item: CString) {
|
||||||
let l = self.ptrs.len();
|
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.ptrs.push(ptr::null());
|
||||||
self.items.push(item);
|
self.items.push(item);
|
||||||
}
|
}
|
||||||
@@ -315,12 +307,9 @@ fn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStr
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stdio {
|
impl Stdio {
|
||||||
pub fn to_child_stdio(&self, readable: bool)
|
pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
||||||
-> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Stdio::Inherit => {
|
Stdio::Inherit => Ok((ChildStdio::Inherit, None)),
|
||||||
Ok((ChildStdio::Inherit, None))
|
|
||||||
},
|
|
||||||
|
|
||||||
// Make sure that the source descriptors are not an stdio
|
// Make sure that the source descriptors are not an stdio
|
||||||
// descriptor, otherwise the order which we set the child's
|
// descriptor, otherwise the order which we set the child's
|
||||||
@@ -339,11 +328,7 @@ impl Stdio {
|
|||||||
|
|
||||||
Stdio::MakePipe => {
|
Stdio::MakePipe => {
|
||||||
let (reader, writer) = pipe::anon_pipe()?;
|
let (reader, writer) = pipe::anon_pipe()?;
|
||||||
let (ours, theirs) = if readable {
|
let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) };
|
||||||
(writer, reader)
|
|
||||||
} else {
|
|
||||||
(reader, writer)
|
|
||||||
};
|
|
||||||
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
|
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,17 +337,13 @@ impl Stdio {
|
|||||||
let mut opts = OpenOptions::new();
|
let mut opts = OpenOptions::new();
|
||||||
opts.read(readable);
|
opts.read(readable);
|
||||||
opts.write(!readable);
|
opts.write(!readable);
|
||||||
let path = unsafe {
|
let path = unsafe { CStr::from_ptr(DEV_NULL.as_ptr() as *const _) };
|
||||||
CStr::from_ptr(DEV_NULL.as_ptr() as *const _)
|
|
||||||
};
|
|
||||||
let fd = File::open_c(&path, &opts)?;
|
let fd = File::open_c(&path, &opts)?;
|
||||||
Ok((ChildStdio::Owned(fd.into_fd()), None))
|
Ok((ChildStdio::Owned(fd.into_fd()), None))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "fuchsia")]
|
#[cfg(target_os = "fuchsia")]
|
||||||
Stdio::Null => {
|
Stdio::Null => Ok((ChildStdio::Null, None)),
|
||||||
Ok((ChildStdio::Null, None))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -430,7 +411,7 @@ mod tests {
|
|||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
|
Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// See #14232 for more information, but it appears that signal delivery to a
|
// 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 stdin_write = pipes.stdin.take().unwrap();
|
||||||
let stdout_read = pipes.stdout.take().unwrap();
|
let stdout_read = pipes.stdout.take().unwrap();
|
||||||
|
|
||||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
|
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut())));
|
||||||
ptr::null_mut())));
|
|
||||||
|
|
||||||
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
|
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
|
||||||
// We need to wait until SIGINT is definitely delivered. The
|
// We need to wait until SIGINT is definitely delivered. The
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use crate::convert::TryInto;
|
use crate::convert::TryInto;
|
||||||
use crate::io;
|
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
|
use crate::io;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
||||||
use crate::sys::process::zircon::{Handle, zx_handle_t};
|
|
||||||
use crate::sys::process::process_common::*;
|
use crate::sys::process::process_common::*;
|
||||||
|
use crate::sys::process::zircon::{zx_handle_t, Handle};
|
||||||
|
|
||||||
use libc::{c_int, size_t};
|
use libc::{c_int, size_t};
|
||||||
|
|
||||||
@@ -14,13 +14,18 @@ use libc::{c_int, size_t};
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
|
pub fn spawn(
|
||||||
-> io::Result<(Process, StdioPipes)> {
|
&mut self,
|
||||||
|
default: Stdio,
|
||||||
|
needs_stdin: bool,
|
||||||
|
) -> io::Result<(Process, StdioPipes)> {
|
||||||
let envp = self.capture_env();
|
let envp = self.capture_env();
|
||||||
|
|
||||||
if self.saw_nul() {
|
if self.saw_nul() {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"nul byte found in provided data"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"nul byte found in provided data",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (ours, theirs) = self.setup_io(default, needs_stdin)?;
|
let (ours, theirs) = self.setup_io(default, needs_stdin)?;
|
||||||
@@ -32,21 +37,23 @@ impl Command {
|
|||||||
|
|
||||||
pub fn exec(&mut self, default: Stdio) -> io::Error {
|
pub fn exec(&mut self, default: Stdio) -> io::Error {
|
||||||
if self.saw_nul() {
|
if self.saw_nul() {
|
||||||
return io::Error::new(io::ErrorKind::InvalidInput,
|
return io::Error::new(io::ErrorKind::InvalidInput, "nul byte found in provided data");
|
||||||
"nul byte found in provided data")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.setup_io(default, true) {
|
match self.setup_io(default, true) {
|
||||||
Ok((_, _)) => {
|
Ok((_, _)) => {
|
||||||
// FIXME: This is tough because we don't support the exec syscalls
|
// FIXME: This is tough because we don't support the exec syscalls
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
},
|
}
|
||||||
Err(e) => e,
|
Err(e) => e,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray>)
|
unsafe fn do_exec(
|
||||||
-> io::Result<zx_handle_t> {
|
&mut self,
|
||||||
|
stdio: ChildPipes,
|
||||||
|
maybe_envp: Option<&CStringArray>,
|
||||||
|
) -> io::Result<zx_handle_t> {
|
||||||
use crate::sys::process::zircon::*;
|
use crate::sys::process::zircon::*;
|
||||||
|
|
||||||
let envp = match maybe_envp {
|
let envp = match maybe_envp {
|
||||||
@@ -108,10 +115,15 @@ impl Command {
|
|||||||
let mut process_handle: zx_handle_t = 0;
|
let mut process_handle: zx_handle_t = 0;
|
||||||
zx_cvt(fdio_spawn_etc(
|
zx_cvt(fdio_spawn_etc(
|
||||||
ZX_HANDLE_INVALID,
|
ZX_HANDLE_INVALID,
|
||||||
FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE
|
FDIO_SPAWN_CLONE_JOB
|
||||||
|
| FDIO_SPAWN_CLONE_LDSVC
|
||||||
|
| FDIO_SPAWN_CLONE_NAMESPACE
|
||||||
| FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null
|
| FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null
|
||||||
self.get_program().as_ptr(), self.get_argv().as_ptr(), envp,
|
self.get_program().as_ptr(),
|
||||||
actions.len() as size_t, actions.as_ptr(),
|
self.get_argv().as_ptr(),
|
||||||
|
envp,
|
||||||
|
actions.len() as size_t,
|
||||||
|
actions.as_ptr(),
|
||||||
&mut process_handle,
|
&mut process_handle,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
))?;
|
))?;
|
||||||
@@ -137,7 +149,9 @@ impl Process {
|
|||||||
pub fn kill(&mut self) -> io::Result<()> {
|
pub fn kill(&mut self) -> io::Result<()> {
|
||||||
use crate::sys::process::zircon::*;
|
use crate::sys::process::zircon::*;
|
||||||
|
|
||||||
unsafe { zx_cvt(zx_task_kill(self.handle.raw()))?; }
|
unsafe {
|
||||||
|
zx_cvt(zx_task_kill(self.handle.raw()))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -151,16 +165,26 @@ impl Process {
|
|||||||
let mut avail: size_t = 0;
|
let mut avail: size_t = 0;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
zx_cvt(zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
|
zx_cvt(zx_object_wait_one(
|
||||||
ZX_TIME_INFINITE, ptr::null_mut()))?;
|
self.handle.raw(),
|
||||||
zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
|
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,
|
&mut proc_info as *mut _ as *mut libc::c_void,
|
||||||
mem::size_of::<zx_info_process_t>(), &mut actual,
|
mem::size_of::<zx_info_process_t>(),
|
||||||
&mut avail))?;
|
&mut actual,
|
||||||
|
&mut avail,
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
if actual != 1 {
|
if actual != 1 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidData,
|
return Err(io::Error::new(
|
||||||
"Failed to get exit status of process"));
|
io::ErrorKind::InvalidData,
|
||||||
|
"Failed to get exit status of process",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Ok(ExitStatus(proc_info.return_code))
|
Ok(ExitStatus(proc_info.return_code))
|
||||||
}
|
}
|
||||||
@@ -174,23 +198,31 @@ impl Process {
|
|||||||
let mut avail: size_t = 0;
|
let mut avail: size_t = 0;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let status = zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
|
let status =
|
||||||
0, ptr::null_mut());
|
zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut());
|
||||||
match status {
|
match status {
|
||||||
0 => { }, // Success
|
0 => {} // Success
|
||||||
x if x == ERR_TIMED_OUT => {
|
x if x == ERR_TIMED_OUT => {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
},
|
|
||||||
_ => { panic!("Failed to wait on process handle: {}", status); },
|
|
||||||
}
|
}
|
||||||
zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
|
_ => {
|
||||||
|
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,
|
&mut proc_info as *mut _ as *mut libc::c_void,
|
||||||
mem::size_of::<zx_info_process_t>(), &mut actual,
|
mem::size_of::<zx_info_process_t>(),
|
||||||
&mut avail))?;
|
&mut actual,
|
||||||
|
&mut avail,
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
if actual != 1 {
|
if actual != 1 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidData,
|
return Err(io::Error::new(
|
||||||
"Failed to get exit status of process"));
|
io::ErrorKind::InvalidData,
|
||||||
|
"Failed to get exit status of process",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Ok(Some(ExitStatus(proc_info.return_code)))
|
Ok(Some(ExitStatus(proc_info.return_code)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#![allow(non_camel_case_types, unused)]
|
#![allow(non_camel_case_types, unused)]
|
||||||
|
|
||||||
use crate::convert::TryInto;
|
use crate::convert::TryInto;
|
||||||
use crate::io;
|
|
||||||
use crate::i64;
|
use crate::i64;
|
||||||
|
use crate::io;
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
use crate::os::raw::c_char;
|
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 const ZX_HANDLE_INVALID: zx_handle_t = 0;
|
||||||
|
|
||||||
pub type zx_time_t = i64;
|
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 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 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 let Ok(status) = TryInto::try_into(t) {
|
||||||
if status < 0 {
|
if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
|
||||||
Err(io::Error::from_raw_os_error(status))
|
|
||||||
} else {
|
|
||||||
Ok(t)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::last_os_error())
|
Err(io::Error::last_os_error())
|
||||||
}
|
}
|
||||||
@@ -49,9 +48,7 @@ pub struct Handle {
|
|||||||
|
|
||||||
impl Handle {
|
impl Handle {
|
||||||
pub fn new(raw: zx_handle_t) -> Handle {
|
pub fn new(raw: zx_handle_t) -> Handle {
|
||||||
Handle {
|
Handle { raw }
|
||||||
raw,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw(&self) -> zx_handle_t {
|
pub fn raw(&self) -> zx_handle_t {
|
||||||
@@ -61,7 +58,9 @@ impl Handle {
|
|||||||
|
|
||||||
impl Drop for Handle {
|
impl Drop for Handle {
|
||||||
fn drop(&mut self) {
|
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,
|
pub debugger_attached: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn zx_job_default() -> zx_handle_t;
|
pub fn zx_job_default() -> zx_handle_t;
|
||||||
|
|
||||||
pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_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_close(handle: zx_handle_t) -> zx_status_t;
|
||||||
|
|
||||||
pub fn zx_handle_duplicate(handle: zx_handle_t, rights: zx_rights_t,
|
pub fn zx_handle_duplicate(
|
||||||
out: *const zx_handle_t) -> zx_handle_t;
|
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,
|
pub fn zx_object_wait_one(
|
||||||
pending: *mut zx_signals_t) -> zx_status_t;
|
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,
|
pub fn zx_object_get_info(
|
||||||
buffer_size: size_t, actual_size: *mut size_t,
|
handle: zx_handle_t,
|
||||||
avail: *mut size_t) -> zx_status_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)]
|
#[derive(Default)]
|
||||||
@@ -103,11 +114,18 @@ pub struct fdio_spawn_action_t {
|
|||||||
pub reserved1: u64,
|
pub reserved1: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char,
|
pub fn fdio_spawn_etc(
|
||||||
argv: *const *const c_char, envp: *const *const c_char,
|
job: zx_handle_t,
|
||||||
action_count: size_t, actions: *const fdio_spawn_action_t,
|
flags: u32,
|
||||||
process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
|
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_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;
|
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
|
// 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,
|
// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
|
||||||
// or enabled.
|
// 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
|
// ERR_NO_RESOURCES: The system was not able to allocate some resource
|
||||||
// needed for the operation.
|
// 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
|
// ERR_NO_MEMORY: The system was not able to allocate memory needed
|
||||||
// for the operation.
|
// 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
|
// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
|
||||||
// successfully.
|
// 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
|
// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
|
||||||
// retried. This should not be seen outside of the VDSO.
|
// 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 =======
|
// ======= Parameter errors =======
|
||||||
// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
|
// 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.
|
// 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
|
// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
|
||||||
// perform the operation.
|
// perform the operation.
|
||||||
// Example: Attempting a message_read on a thread handle.
|
// 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.
|
// 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
|
// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
|
||||||
// operation.
|
// 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
|
// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
|
||||||
// this operation.
|
// 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 =======
|
// ======= Precondition or state errors =======
|
||||||
// ERR_BAD_STATE: operation failed because the current state of the
|
// ERR_BAD_STATE: operation failed because the current state of the
|
||||||
// object does not allow it, or a precondition of the operation is
|
// object does not allow it, or a precondition of the operation is
|
||||||
// not satisfied
|
// 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
|
// ERR_TIMED_OUT: The time limit for the operation elapsed before
|
||||||
// the operation completed.
|
// 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
|
// ERR_SHOULD_WAIT: The operation cannot be performed currently but
|
||||||
// potentially could succeed if the caller waits for a prerequisite
|
// 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.
|
// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
|
||||||
// Attempting to read from a message pipe that has no messages waiting
|
// Attempting to read from a message pipe that has no messages waiting
|
||||||
// and has a closed remote end will return ERR_REMOTE_CLOSED.
|
// 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
|
// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
|
||||||
// // canceled.
|
// // 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
|
// ERR_PEER_CLOSED: The operation failed because the remote end
|
||||||
// of the subject of the operation was closed.
|
// 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.
|
// 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
|
// ERR_ALREADY_EXISTS: An object with the specified identifier
|
||||||
// already exists.
|
// already exists.
|
||||||
// Example: Attempting to create a file when a file already exists
|
// Example: Attempting to create a file when a file already exists
|
||||||
// with that name.
|
// 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
|
// ERR_ALREADY_BOUND: The operation failed because the named entity
|
||||||
// is already owned or controlled by another entity. The operation
|
// is already owned or controlled by another entity. The operation
|
||||||
// could succeed later if the current owner releases the entity.
|
// 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
|
// ERR_UNAVAILABLE: The subject of the operation is currently unable
|
||||||
// to perform the operation.
|
// to perform the operation.
|
||||||
// Note: This is used when there's no direct way for the caller to
|
// 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
|
// observe when the subject will be able to perform the operation
|
||||||
// and should thus retry.
|
// 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 =======
|
// ======= Permission check errors =======
|
||||||
// ERR_ACCESS_DENIED: The caller did not have permission to perform
|
// ERR_ACCESS_DENIED: The caller did not have permission to perform
|
||||||
// the specified operation.
|
// 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 =======
|
// ======= Input-output errors =======
|
||||||
// ERR_IO: Otherwise unspecified error occurred during I/O.
|
// 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
|
// ERR_REFUSED: The entity the I/O operation is being performed on
|
||||||
// rejected the operation.
|
// rejected the operation.
|
||||||
// Example: an I2C device NAK'ing a transaction or a disk controller
|
// Example: an I2C device NAK'ing a transaction or a disk controller
|
||||||
// rejecting an invalid command.
|
// 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
|
// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
|
||||||
// check and is possibly corrupted.
|
// check and is possibly corrupted.
|
||||||
// Example: CRC or Parity error.
|
// 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
|
// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
|
||||||
// and may be permanently lost.
|
// and may be permanently lost.
|
||||||
// Example: A disk block is irrecoverably damaged.
|
// 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
|
// Filesystem specific errors
|
||||||
#[allow(unused)] pub const ERR_BAD_PATH: zx_status_t = -50;
|
#[allow(unused)]
|
||||||
#[allow(unused)] pub const ERR_NOT_DIR: zx_status_t = -51;
|
pub const ERR_BAD_PATH: zx_status_t = -50;
|
||||||
#[allow(unused)] pub const ERR_NOT_FILE: zx_status_t = -52;
|
#[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.
|
// 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.
|
// 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) {
|
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||||
let mut v = (0, 0);
|
let mut v = (0, 0);
|
||||||
unsafe {
|
unsafe {
|
||||||
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
|
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, mem::size_of_val(&v));
|
||||||
mem::size_of_val(&v));
|
|
||||||
imp::fill_bytes(view);
|
imp::fill_bytes(view);
|
||||||
}
|
}
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(unix,
|
#[cfg(all(
|
||||||
|
unix,
|
||||||
not(target_os = "ios"),
|
not(target_os = "ios"),
|
||||||
not(target_os = "openbsd"),
|
not(target_os = "openbsd"),
|
||||||
not(target_os = "freebsd"),
|
not(target_os = "freebsd"),
|
||||||
not(target_os = "netbsd"),
|
not(target_os = "netbsd"),
|
||||||
not(target_os = "fuchsia"),
|
not(target_os = "fuchsia"),
|
||||||
not(target_os = "redox")))]
|
not(target_os = "redox")
|
||||||
|
))]
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::fs::File;
|
use crate::fs::File;
|
||||||
use crate::io::Read;
|
use crate::io::Read;
|
||||||
@@ -30,7 +31,9 @@ mod imp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
#[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"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
|
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
|
||||||
@@ -96,9 +99,7 @@ mod imp {
|
|||||||
pub fn fill_bytes(v: &mut [u8]) {
|
pub fn fill_bytes(v: &mut [u8]) {
|
||||||
// getentropy(2) permits a maximum buffer size of 256 bytes
|
// getentropy(2) permits a maximum buffer size of 256 bytes
|
||||||
for s in v.chunks_mut(256) {
|
for s in v.chunks_mut(256) {
|
||||||
let ret = unsafe {
|
let ret = unsafe { libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len()) };
|
||||||
libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len())
|
|
||||||
};
|
|
||||||
if ret == -1 {
|
if ret == -1 {
|
||||||
panic!("unexpected getentropy error: {}", errno());
|
panic!("unexpected getentropy error: {}", errno());
|
||||||
}
|
}
|
||||||
@@ -124,21 +125,14 @@ mod imp {
|
|||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
const kSecRandomDefault: *const SecRandom = ptr::null();
|
const kSecRandomDefault: *const SecRandom = ptr::null();
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn SecRandomCopyBytes(rnd: *const SecRandom,
|
fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int;
|
||||||
count: size_t,
|
|
||||||
bytes: *mut u8) -> c_int;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fill_bytes(v: &mut [u8]) {
|
pub fn fill_bytes(v: &mut [u8]) {
|
||||||
let ret = unsafe {
|
let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) };
|
||||||
SecRandomCopyBytes(kSecRandomDefault,
|
|
||||||
v.len(),
|
|
||||||
v.as_mut_ptr())
|
|
||||||
};
|
|
||||||
if ret == -1 {
|
if ret == -1 {
|
||||||
panic!("couldn't generate random bytes: {}",
|
panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
|
||||||
io::Error::last_os_error());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,13 +147,22 @@ mod imp {
|
|||||||
for s in v.chunks_mut(256) {
|
for s in v.chunks_mut(256) {
|
||||||
let mut s_len = s.len();
|
let mut s_len = s.len();
|
||||||
let ret = unsafe {
|
let ret = unsafe {
|
||||||
libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
|
libc::sysctl(
|
||||||
s.as_mut_ptr() as *mut _, &mut s_len,
|
mib.as_ptr(),
|
||||||
ptr::null(), 0)
|
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() {
|
if ret == -1 || s_len != s.len() {
|
||||||
panic!("kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
|
panic!(
|
||||||
ret, s.len(), s_len);
|
"kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
|
||||||
|
ret,
|
||||||
|
s.len(),
|
||||||
|
s_len
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +171,7 @@ mod imp {
|
|||||||
#[cfg(target_os = "fuchsia")]
|
#[cfg(target_os = "fuchsia")]
|
||||||
mod imp {
|
mod imp {
|
||||||
#[link(name = "zircon")]
|
#[link(name = "zircon")]
|
||||||
extern {
|
extern "C" {
|
||||||
fn zx_cprng_draw(buffer: *mut u8, len: usize);
|
fn zx_cprng_draw(buffer: *mut u8, len: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#![cfg_attr(test, allow(dead_code))]
|
#![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::cleanup;
|
||||||
pub use self::imp::init;
|
pub use self::imp::init;
|
||||||
|
|
||||||
pub struct Handler {
|
pub struct Handler {
|
||||||
_data: *mut libc::c_void
|
_data: *mut libc::c_void,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
@@ -23,28 +23,28 @@ impl Drop for Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux",
|
#[cfg(any(
|
||||||
|
target_os = "linux",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||||
target_os = "openbsd"))]
|
target_os = "openbsd"
|
||||||
|
))]
|
||||||
mod imp {
|
mod imp {
|
||||||
use super::Handler;
|
use super::Handler;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::ptr;
|
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::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;
|
use crate::sys_common::thread_info;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
|
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@@ -82,9 +82,11 @@ mod imp {
|
|||||||
// out many large systems and all implementations allow returning from a
|
// out many large systems and all implementations allow returning from a
|
||||||
// signal handler to work. For a more detailed explanation see the
|
// signal handler to work. For a more detailed explanation see the
|
||||||
// comments on #26458.
|
// comments on #26458.
|
||||||
unsafe extern fn signal_handler(signum: libc::c_int,
|
unsafe extern "C" fn signal_handler(
|
||||||
|
signum: libc::c_int,
|
||||||
info: *mut libc::siginfo_t,
|
info: *mut libc::siginfo_t,
|
||||||
_data: *mut libc::c_void) {
|
_data: *mut libc::c_void,
|
||||||
|
) {
|
||||||
use crate::sys_common::util::report_overflow;
|
use crate::sys_common::util::report_overflow;
|
||||||
|
|
||||||
let guard = thread_info::stack_guard().unwrap_or(0..0);
|
let guard = thread_info::stack_guard().unwrap_or(0..0);
|
||||||
@@ -124,24 +126,22 @@ mod imp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn get_stackp() -> *mut libc::c_void {
|
unsafe fn get_stackp() -> *mut libc::c_void {
|
||||||
let stackp = mmap(ptr::null_mut(),
|
let stackp =
|
||||||
SIGSTKSZ,
|
mmap(ptr::null_mut(), SIGSTKSZ, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
PROT_READ | PROT_WRITE,
|
|
||||||
MAP_PRIVATE | MAP_ANON,
|
|
||||||
-1,
|
|
||||||
0);
|
|
||||||
if stackp == MAP_FAILED {
|
if stackp == MAP_FAILED {
|
||||||
panic!("failed to allocate an alternative stack");
|
panic!("failed to allocate an alternative stack");
|
||||||
}
|
}
|
||||||
stackp
|
stackp
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux",
|
#[cfg(any(
|
||||||
|
target_os = "linux",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "solaris"))]
|
target_os = "solaris"
|
||||||
|
))]
|
||||||
unsafe fn get_stack() -> libc::stack_t {
|
unsafe fn get_stack() -> libc::stack_t {
|
||||||
libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
|
libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
|
||||||
}
|
}
|
||||||
@@ -181,26 +181,25 @@ mod imp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "linux",
|
#[cfg(not(any(
|
||||||
|
target_os = "linux",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||||
target_os = "openbsd")))]
|
target_os = "openbsd"
|
||||||
|
)))]
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::ptr;
|
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 {
|
pub unsafe fn make_handler() -> super::Handler {
|
||||||
super::Handler { _data: ptr::null_mut() }
|
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::io::{self, IoSlice, IoSliceMut};
|
||||||
use crate::sys::fd::FileDesc;
|
|
||||||
use crate::mem::ManuallyDrop;
|
use crate::mem::ManuallyDrop;
|
||||||
|
use crate::sys::fd::FileDesc;
|
||||||
|
|
||||||
pub struct Stdin(());
|
pub struct Stdin(());
|
||||||
pub struct Stdout(());
|
pub struct Stdout(());
|
||||||
pub struct Stderr(());
|
pub struct Stderr(());
|
||||||
|
|
||||||
impl Stdin {
|
impl Stdin {
|
||||||
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
|
pub fn new() -> io::Result<Stdin> {
|
||||||
|
Ok(Stdin(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Read for Stdin {
|
impl io::Read for Stdin {
|
||||||
@@ -21,7 +23,9 @@ impl io::Read for Stdin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stdout {
|
impl Stdout {
|
||||||
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
|
pub fn new() -> io::Result<Stdout> {
|
||||||
|
Ok(Stdout(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for Stdout {
|
impl io::Write for Stdout {
|
||||||
@@ -39,7 +43,9 @@ impl io::Write for Stdout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stderr {
|
impl Stderr {
|
||||||
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
|
pub fn new() -> io::Result<Stderr> {
|
||||||
|
Ok(Stderr(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for 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,
|
// 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.
|
// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
|
||||||
#[cfg(not(target_os = "emscripten"))]
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
|
unsafe fn pthread_attr_setstacksize(
|
||||||
stack_size: libc::size_t) -> libc::c_int {
|
attr: *mut libc::pthread_attr_t,
|
||||||
|
stack_size: libc::size_t,
|
||||||
|
) -> libc::c_int {
|
||||||
libc::pthread_attr_setstacksize(attr, stack_size)
|
libc::pthread_attr_setstacksize(attr, stack_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "emscripten")]
|
#[cfg(target_os = "emscripten")]
|
||||||
unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
|
unsafe fn pthread_attr_setstacksize(
|
||||||
_stack_size: libc::size_t) -> libc::c_int {
|
_attr: *mut libc::pthread_attr_t,
|
||||||
|
_stack_size: libc::size_t,
|
||||||
|
) -> libc::c_int {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||||
-> io::Result<Thread> {
|
|
||||||
let p = box p;
|
let p = box p;
|
||||||
let mut native: libc::pthread_t = mem::zeroed();
|
let mut native: libc::pthread_t = mem::zeroed();
|
||||||
let mut attr: libc::pthread_attr_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));
|
let stack_size = cmp::max(stack, min_stack_size(&attr));
|
||||||
|
|
||||||
match pthread_attr_setstacksize(&mut attr,
|
match pthread_attr_setstacksize(&mut attr, stack_size) {
|
||||||
stack_size) {
|
|
||||||
0 => {}
|
0 => {}
|
||||||
n => {
|
n => {
|
||||||
assert_eq!(n, libc::EINVAL);
|
assert_eq!(n, libc::EINVAL);
|
||||||
@@ -57,15 +59,13 @@ impl Thread {
|
|||||||
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
||||||
// Round up to the nearest page and try again.
|
// Round up to the nearest page and try again.
|
||||||
let page_size = os::page_size();
|
let page_size = os::page_size();
|
||||||
let stack_size = (stack_size + page_size - 1) &
|
let stack_size =
|
||||||
(-(page_size as isize - 1) as usize - 1);
|
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
|
||||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
|
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
|
||||||
stack_size), 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret = libc::pthread_create(&mut native, &attr, thread_start,
|
let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
|
||||||
&*p as *const _ as *mut _);
|
|
||||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||||
|
|
||||||
return if ret != 0 {
|
return if ret != 0 {
|
||||||
@@ -75,8 +75,10 @@ impl Thread {
|
|||||||
Ok(Thread { id: native })
|
Ok(Thread { id: native })
|
||||||
};
|
};
|
||||||
|
|
||||||
extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
||||||
unsafe { start_thread(main as *mut u8); }
|
unsafe {
|
||||||
|
start_thread(main as *mut u8);
|
||||||
|
}
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,8 +88,7 @@ impl Thread {
|
|||||||
debug_assert_eq!(ret, 0);
|
debug_assert_eq!(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux",
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
target_os = "android"))]
|
|
||||||
pub fn set_name(name: &CStr) {
|
pub fn set_name(name: &CStr) {
|
||||||
const PR_SET_NAME: libc::c_int = 15;
|
const PR_SET_NAME: libc::c_int = 15;
|
||||||
// pthread wrapper only appeared in glibc 2.12, so we use syscall
|
// pthread wrapper only appeared in glibc 2.12, so we use syscall
|
||||||
@@ -97,9 +98,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "freebsd",
|
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
|
||||||
target_os = "dragonfly",
|
|
||||||
target_os = "openbsd"))]
|
|
||||||
pub fn set_name(name: &CStr) {
|
pub fn set_name(name: &CStr) {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
|
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
|
||||||
@@ -118,8 +117,11 @@ impl Thread {
|
|||||||
use crate::ffi::CString;
|
use crate::ffi::CString;
|
||||||
let cname = CString::new(&b"%s"[..]).unwrap();
|
let cname = CString::new(&b"%s"[..]).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(),
|
libc::pthread_setname_np(
|
||||||
name.as_ptr() as *mut libc::c_void);
|
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() {
|
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",
|
#[cfg(any(
|
||||||
|
target_env = "newlib",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "l4re",
|
target_os = "l4re",
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "redox"))]
|
target_os = "redox"
|
||||||
|
))]
|
||||||
pub fn set_name(_name: &CStr) {
|
pub fn set_name(_name: &CStr) {
|
||||||
// Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
|
// Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
|
||||||
}
|
}
|
||||||
@@ -177,12 +183,13 @@ impl Thread {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
assert!(ret == 0,
|
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||||
"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 {
|
pub fn into_id(self) -> libc::pthread_t {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
@@ -198,31 +205,38 @@ impl Drop for Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
|
#[cfg(all(
|
||||||
|
not(all(target_os = "linux", not(target_env = "musl"))),
|
||||||
not(target_os = "freebsd"),
|
not(target_os = "freebsd"),
|
||||||
not(target_os = "macos"),
|
not(target_os = "macos"),
|
||||||
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
|
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
|
||||||
not(target_os = "openbsd"),
|
not(target_os = "openbsd"),
|
||||||
not(target_os = "solaris")))]
|
not(target_os = "solaris")
|
||||||
|
))]
|
||||||
#[cfg_attr(test, allow(dead_code))]
|
#[cfg_attr(test, allow(dead_code))]
|
||||||
pub mod guard {
|
pub mod guard {
|
||||||
use crate::ops::Range;
|
use crate::ops::Range;
|
||||||
pub type Guard = Range<usize>;
|
pub type Guard = Range<usize>;
|
||||||
pub unsafe fn current() -> Option<Guard> { None }
|
pub unsafe fn current() -> Option<Guard> {
|
||||||
pub unsafe fn init() -> Option<Guard> { None }
|
None
|
||||||
|
}
|
||||||
|
pub unsafe fn init() -> Option<Guard> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
#[cfg(any(all(target_os = "linux", not(target_env = "musl")),
|
all(target_os = "linux", not(target_env = "musl")),
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "solaris"))]
|
target_os = "solaris"
|
||||||
|
))]
|
||||||
#[cfg_attr(test, allow(dead_code))]
|
#[cfg_attr(test, allow(dead_code))]
|
||||||
pub mod guard {
|
pub mod guard {
|
||||||
use libc::{mmap, mprotect};
|
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::ops::Range;
|
||||||
use crate::sys::os;
|
use crate::sys::os;
|
||||||
@@ -241,16 +255,15 @@ pub mod guard {
|
|||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||||
let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
|
let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize
|
||||||
libc::pthread_get_stacksize_np(libc::pthread_self());
|
- libc::pthread_get_stacksize_np(libc::pthread_self());
|
||||||
Some(stackaddr as *mut libc::c_void)
|
Some(stackaddr as *mut libc::c_void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "openbsd")]
|
#[cfg(target_os = "openbsd")]
|
||||||
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||||
let mut current_stack: libc::stack_t = crate::mem::zeroed();
|
let mut current_stack: libc::stack_t = crate::mem::zeroed();
|
||||||
assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
|
assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(), &mut current_stack), 0);
|
||||||
&mut current_stack), 0);
|
|
||||||
|
|
||||||
let stackaddr = if libc::pthread_main_np() == 1 {
|
let stackaddr = if libc::pthread_main_np() == 1 {
|
||||||
// main thread
|
// main thread
|
||||||
@@ -262,8 +275,13 @@ pub mod guard {
|
|||||||
Some(stackaddr as *mut libc::c_void)
|
Some(stackaddr as *mut libc::c_void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android", target_os = "freebsd",
|
#[cfg(any(
|
||||||
target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
|
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> {
|
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
|
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
|
||||||
@@ -275,8 +293,7 @@ pub mod guard {
|
|||||||
if e == 0 {
|
if e == 0 {
|
||||||
let mut stackaddr = crate::ptr::null_mut();
|
let mut stackaddr = crate::ptr::null_mut();
|
||||||
let mut stacksize = 0;
|
let mut stacksize = 0;
|
||||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
|
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
|
||||||
&mut stacksize), 0);
|
|
||||||
ret = Some(stackaddr);
|
ret = Some(stackaddr);
|
||||||
}
|
}
|
||||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
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
|
// than the initial mmap() used, so we mmap() here with
|
||||||
// read/write permissions and only then mprotect() it to
|
// read/write permissions and only then mprotect() it to
|
||||||
// no permissions at all. See issue #50313.
|
// no permissions at all. See issue #50313.
|
||||||
let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE,
|
let result = mmap(
|
||||||
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
|
stackaddr,
|
||||||
|
PAGE_SIZE,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANON | MAP_FIXED,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
);
|
||||||
if result != stackaddr || result == MAP_FAILED {
|
if result != stackaddr || result == MAP_FAILED {
|
||||||
panic!("failed to allocate a guard page");
|
panic!("failed to allocate a guard page");
|
||||||
}
|
}
|
||||||
@@ -341,26 +364,25 @@ pub mod guard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let guardaddr = stackaddr as usize;
|
let guardaddr = stackaddr as usize;
|
||||||
let offset = if cfg!(target_os = "freebsd") {
|
let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 };
|
||||||
2
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(guardaddr..guardaddr + offset * PAGE_SIZE)
|
Some(guardaddr..guardaddr + offset * PAGE_SIZE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos",
|
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
|
||||||
target_os = "openbsd",
|
|
||||||
target_os = "solaris"))]
|
|
||||||
pub unsafe fn current() -> Option<Guard> {
|
pub unsafe fn current() -> Option<Guard> {
|
||||||
let stackaddr = get_stack_start()? as usize;
|
let stackaddr = get_stack_start()? as usize;
|
||||||
Some(stackaddr - PAGE_SIZE..stackaddr)
|
Some(stackaddr - PAGE_SIZE..stackaddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android", target_os = "freebsd",
|
#[cfg(any(
|
||||||
target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
|
target_os = "android",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "l4re"
|
||||||
|
))]
|
||||||
pub unsafe fn current() -> Option<Guard> {
|
pub unsafe fn current() -> Option<Guard> {
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
|
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
|
||||||
@@ -377,8 +399,7 @@ pub mod guard {
|
|||||||
}
|
}
|
||||||
let mut stackaddr = crate::ptr::null_mut();
|
let mut stackaddr = crate::ptr::null_mut();
|
||||||
let mut size = 0;
|
let mut size = 0;
|
||||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
|
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
|
||||||
&mut size), 0);
|
|
||||||
|
|
||||||
let stackaddr = stackaddr as usize;
|
let stackaddr = stackaddr as usize;
|
||||||
ret = if cfg!(target_os = "freebsd") {
|
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
|
// No point in looking up __pthread_get_minstack() on non-glibc
|
||||||
// platforms.
|
// platforms.
|
||||||
#[cfg(all(not(target_os = "linux"),
|
#[cfg(all(not(target_os = "linux"), not(target_os = "netbsd")))]
|
||||||
not(target_os = "netbsd")))]
|
|
||||||
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
||||||
libc::PTHREAD_STACK_MIN
|
libc::PTHREAD_STACK_MIN
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::mem;
|
|||||||
pub type Key = libc::pthread_key_t;
|
pub type Key = libc::pthread_key_t;
|
||||||
|
|
||||||
#[inline]
|
#[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;
|
let mut key = 0;
|
||||||
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
||||||
key
|
key
|
||||||
|
|||||||
@@ -36,11 +36,7 @@ pub struct Weak<F> {
|
|||||||
|
|
||||||
impl<F> Weak<F> {
|
impl<F> Weak<F> {
|
||||||
pub const fn new(name: &'static str) -> Weak<F> {
|
pub const fn new(name: &'static str) -> Weak<F> {
|
||||||
Weak {
|
Weak { name, addr: AtomicUsize::new(1), _marker: marker::PhantomData }
|
||||||
name,
|
|
||||||
addr: AtomicUsize::new(1),
|
|
||||||
_marker: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> Option<F> {
|
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::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")]
|
#[stable(feature = "alloc_system_type", since = "1.28.0")]
|
||||||
unsafe impl GlobalAlloc for System {
|
unsafe impl GlobalAlloc for System {
|
||||||
@@ -45,9 +45,5 @@ unsafe impl GlobalAlloc for System {
|
|||||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||||
let mut out = ptr::null_mut();
|
let mut out = ptr::null_mut();
|
||||||
let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
|
let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
|
||||||
if ret != 0 {
|
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
|
||||||
ptr::null_mut()
|
|
||||||
} else {
|
|
||||||
out as *mut u8
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,14 @@ use crate::marker::PhantomData;
|
|||||||
use crate::vec;
|
use crate::vec;
|
||||||
|
|
||||||
/// One-time global initialization.
|
/// 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.
|
/// One-time global cleanup.
|
||||||
pub unsafe fn cleanup() { imp::cleanup() }
|
pub unsafe fn cleanup() {
|
||||||
|
imp::cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the command line arguments
|
/// Returns the command line arguments
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
@@ -27,24 +31,32 @@ impl Args {
|
|||||||
|
|
||||||
impl Iterator for Args {
|
impl Iterator for Args {
|
||||||
type Item = OsString;
|
type Item = OsString;
|
||||||
fn next(&mut self) -> Option<OsString> { self.iter.next() }
|
fn next(&mut self) -> Option<OsString> {
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
self.iter.next()
|
||||||
|
}
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExactSizeIterator for Args {
|
impl ExactSizeIterator for Args {
|
||||||
fn len(&self) -> usize { self.iter.len() }
|
fn len(&self) -> usize {
|
||||||
|
self.iter.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DoubleEndedIterator for Args {
|
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 {
|
mod imp {
|
||||||
use crate::ptr;
|
use super::Args;
|
||||||
use crate::ffi::{CStr, OsString};
|
use crate::ffi::{CStr, OsString};
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
|
use crate::ptr;
|
||||||
use libc;
|
use libc;
|
||||||
use super::Args;
|
|
||||||
|
|
||||||
use crate::sys_common::mutex::Mutex;
|
use crate::sys_common::mutex::Mutex;
|
||||||
|
|
||||||
@@ -65,21 +77,20 @@ mod imp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
Args {
|
Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData }
|
||||||
iter: clone().into_iter(),
|
|
||||||
_dont_send_or_sync_me: PhantomData
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone() -> Vec<OsString> {
|
fn clone() -> Vec<OsString> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _guard = LOCK.lock();
|
let _guard = LOCK.lock();
|
||||||
let ret = (0..ARGC).map(|i| {
|
let ret = (0..ARGC)
|
||||||
|
.map(|i| {
|
||||||
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
|
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
|
||||||
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
||||||
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||||
}).collect();
|
})
|
||||||
return ret
|
.collect();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#![cfg(not(test))]
|
#![cfg(not(test))]
|
||||||
|
|
||||||
use libc::{c_float, c_double};
|
use libc::{c_double, c_float};
|
||||||
|
|
||||||
#[link_name = "m"]
|
#[link_name = "m"]
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn acos(n: c_double) -> c_double;
|
pub fn acos(n: c_double) -> c_double;
|
||||||
pub fn acosf(n: c_float) -> c_float;
|
pub fn acosf(n: c_float) -> c_float;
|
||||||
pub fn asin(n: c_double) -> c_double;
|
pub fn asin(n: c_double) -> c_double;
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ use crate::cell::UnsafeCell;
|
|||||||
use crate::sys::mutex::{self, Mutex};
|
use crate::sys::mutex::{self, Mutex};
|
||||||
use crate::time::Duration;
|
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 Send for Condvar {}
|
||||||
unsafe impl Sync for Condvar {}
|
unsafe impl Sync for Condvar {}
|
||||||
|
|
||||||
const TIMESPEC_MAX: libc::timespec = libc::timespec {
|
const TIMESPEC_MAX: libc::timespec =
|
||||||
tv_sec: <libc::time_t>::max_value(),
|
libc::timespec { tv_sec: <libc::time_t>::max_value(), tv_nsec: 1_000_000_000 - 1 };
|
||||||
tv_nsec: 1_000_000_000 - 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
|
fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
|
||||||
if value > <libc::time_t>::max_value() as u64 {
|
if value > <libc::time_t>::max_value() as u64 {
|
||||||
@@ -77,17 +77,14 @@ impl Condvar {
|
|||||||
.and_then(|s| s.checked_add(now.tv_sec));
|
.and_then(|s| s.checked_add(now.tv_sec));
|
||||||
let nsec = nsec % 1_000_000_000;
|
let nsec = nsec % 1_000_000_000;
|
||||||
|
|
||||||
let timeout = sec.map(|s| {
|
let timeout =
|
||||||
libc::timespec { tv_sec: s, tv_nsec: nsec as _}
|
sec.map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec as _ }).unwrap_or(TIMESPEC_MAX);
|
||||||
}).unwrap_or(TIMESPEC_MAX);
|
|
||||||
|
|
||||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
|
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), &timeout);
|
||||||
&timeout);
|
|
||||||
assert!(r == libc::ETIMEDOUT || r == 0);
|
assert!(r == libc::ETIMEDOUT || r == 0);
|
||||||
r == 0
|
r == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn destroy(&self) {
|
pub unsafe fn destroy(&self) {
|
||||||
let r = libc::pthread_cond_destroy(self.inner.get());
|
let r = libc::pthread_cond_destroy(self.inner.get());
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
use crate::fs::{self, Permissions};
|
use crate::fs::{self, Permissions};
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use libc;
|
|
||||||
use crate::path::Path;
|
use crate::path::Path;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::sys_common::{FromInner, AsInner, AsInnerMut};
|
|
||||||
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
|
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
|
||||||
|
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
|
||||||
|
use libc;
|
||||||
|
|
||||||
/// Unix-specific extensions to [`File`].
|
/// Unix-specific extensions to [`File`].
|
||||||
///
|
///
|
||||||
@@ -112,8 +112,7 @@ pub trait FileExt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !buf.is_empty() {
|
if !buf.is_empty() {
|
||||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
|
||||||
"failed to fill whole buffer"))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -196,8 +195,12 @@ pub trait FileExt {
|
|||||||
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
|
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
|
||||||
while !buf.is_empty() {
|
while !buf.is_empty() {
|
||||||
match self.write_at(buf, offset) {
|
match self.write_at(buf, offset) {
|
||||||
Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
|
Ok(0) => {
|
||||||
"failed to write whole buffer")),
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::WriteZero,
|
||||||
|
"failed to write whole buffer",
|
||||||
|
));
|
||||||
|
}
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
buf = &buf[n..];
|
buf = &buf[n..];
|
||||||
offset += n as u64
|
offset += n as u64
|
||||||
@@ -604,20 +607,48 @@ pub trait MetadataExt {
|
|||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||||
impl MetadataExt for fs::Metadata {
|
impl MetadataExt for fs::Metadata {
|
||||||
fn dev(&self) -> u64 { self.st_dev() }
|
fn dev(&self) -> u64 {
|
||||||
fn ino(&self) -> u64 { self.st_ino() }
|
self.st_dev()
|
||||||
fn mode(&self) -> u32 { self.st_mode() }
|
}
|
||||||
fn nlink(&self) -> u64 { self.st_nlink() }
|
fn ino(&self) -> u64 {
|
||||||
fn uid(&self) -> u32 { self.st_uid() }
|
self.st_ino()
|
||||||
fn gid(&self) -> u32 { self.st_gid() }
|
}
|
||||||
fn rdev(&self) -> u64 { self.st_rdev() }
|
fn mode(&self) -> u32 {
|
||||||
fn size(&self) -> u64 { self.st_size() }
|
self.st_mode()
|
||||||
fn atime(&self) -> i64 { self.st_atime() }
|
}
|
||||||
fn mtime(&self) -> i64 { self.st_mtime() }
|
fn nlink(&self) -> u64 {
|
||||||
fn ctime(&self) -> i64 { self.st_ctime() }
|
self.st_nlink()
|
||||||
fn blksize(&self) -> u64 { self.st_blksize() }
|
}
|
||||||
fn blocks(&self) -> u64 { self.st_blocks() }
|
fn uid(&self) -> u32 {
|
||||||
fn attrib(&self) -> u8 {self.st_attrib() }
|
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`].
|
/// Unix-specific extensions for [`FileType`].
|
||||||
@@ -704,10 +735,18 @@ pub trait FileTypeExt {
|
|||||||
|
|
||||||
#[stable(feature = "file_type_ext", since = "1.5.0")]
|
#[stable(feature = "file_type_ext", since = "1.5.0")]
|
||||||
impl FileTypeExt for fs::FileType {
|
impl FileTypeExt for fs::FileType {
|
||||||
fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
|
fn is_block_device(&self) -> bool {
|
||||||
fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
|
self.as_inner().is(libc::S_IFBLK)
|
||||||
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_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`].
|
/// Unix-specific extension methods for [`fs::DirEntry`].
|
||||||
@@ -739,7 +778,9 @@ pub trait DirEntryExt {
|
|||||||
|
|
||||||
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
|
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
|
||||||
impl DirEntryExt for fs::DirEntry {
|
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.
|
/// Creates a new symbolic link on the filesystem.
|
||||||
@@ -766,8 +807,7 @@ impl DirEntryExt for fs::DirEntry {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "symlink", since = "1.1.0")]
|
#[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())
|
sys::fs::symlink(src.as_ref(), dst.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use crate::fs;
|
use crate::fs;
|
||||||
|
use crate::io;
|
||||||
|
use crate::net;
|
||||||
use crate::os::raw;
|
use crate::os::raw;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::io;
|
|
||||||
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
|
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
|
||||||
use crate::net;
|
|
||||||
|
|
||||||
/// Raw file descriptors.
|
/// Raw file descriptors.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -84,47 +84,65 @@ impl IntoRawFd for fs::File {
|
|||||||
|
|
||||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
impl AsRawFd for io::Stdin {
|
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")]
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
impl AsRawFd for io::Stdout {
|
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")]
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
impl AsRawFd for io::Stderr {
|
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")]
|
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||||
impl<'a> AsRawFd for io::StdinLock<'a> {
|
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")]
|
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||||
impl<'a> AsRawFd for io::StdoutLock<'a> {
|
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")]
|
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
|
||||||
impl<'a> AsRawFd for io::StderrLock<'a> {
|
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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl AsRawFd for net::TcpStream {
|
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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl AsRawFd for net::TcpListener {
|
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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl AsRawFd for net::UdpSocket {
|
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")]
|
#[stable(feature = "from_raw_os", since = "1.1.0")]
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
pub mod io;
|
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod raw;
|
pub mod io;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
pub mod raw;
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
|
#[doc(no_inline)]
|
||||||
pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use super::ffi::{OsStrExt, OsStringExt};
|
pub use super::ffi::{OsStrExt, OsStringExt};
|
||||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
|
#[doc(no_inline)]
|
||||||
pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt};
|
#[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")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::sys::vxworks::ext::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
|
|
||||||
use crate::process;
|
use crate::process;
|
||||||
use crate::sys;
|
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.
|
/// Unix-specific extensions to the [`process::Command`] builder.
|
||||||
///
|
///
|
||||||
@@ -55,7 +55,8 @@ pub trait CommandExt {
|
|||||||
/// locations may not appear where intended.
|
/// locations may not appear where intended.
|
||||||
#[stable(feature = "process_pre_exec", since = "1.34.0")]
|
#[stable(feature = "process_pre_exec", since = "1.34.0")]
|
||||||
unsafe fn pre_exec<F>(&mut self, f: F) -> &mut 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;
|
||||||
|
|
||||||
/// Schedules a closure to be run just before the `exec` function is
|
/// Schedules a closure to be run just before the `exec` function is
|
||||||
/// invoked.
|
/// invoked.
|
||||||
@@ -67,7 +68,8 @@ pub trait CommandExt {
|
|||||||
#[stable(feature = "process_exec", since = "1.15.0")]
|
#[stable(feature = "process_exec", since = "1.15.0")]
|
||||||
#[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
|
#[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
|
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) }
|
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
|
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.as_inner_mut().pre_exec(Box::new(f));
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![cfg(target_thread_local)]
|
#![cfg(target_thread_local)]
|
||||||
#![unstable(feature = "thread_local_internals", issue = "0")]
|
#![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;
|
use crate::sys_common::thread_local::register_dtor_fallback;
|
||||||
register_dtor_fallback(t, dtor);
|
register_dtor_fallback(t, dtor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
#![unstable(reason = "not public", issue = "0", feature = "fd")]
|
||||||
|
|
||||||
use crate::cmp;
|
use crate::cmp;
|
||||||
use crate::io::{self, Read, Initializer, IoSlice, IoSliceMut};
|
use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
use crate::sys_common::AsInner;
|
use crate::sys_common::AsInner;
|
||||||
@@ -25,7 +25,9 @@ impl FileDesc {
|
|||||||
FileDesc { fd: fd }
|
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.
|
/// Extracts the actual filedescriptor without closing it.
|
||||||
pub fn into_raw(self) -> c_int {
|
pub fn into_raw(self) -> c_int {
|
||||||
@@ -36,18 +38,18 @@ impl FileDesc {
|
|||||||
|
|
||||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::read(self.fd,
|
libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
|
||||||
cmp::min(buf.len(), max_len()))
|
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::readv(self.fd,
|
libc::readv(
|
||||||
|
self.fd,
|
||||||
bufs.as_ptr() as *const libc::iovec,
|
bufs.as_ptr() as *const libc::iovec,
|
||||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
@@ -58,61 +60,69 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
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)
|
unsafe fn cvt_pread(
|
||||||
-> io::Result<isize>
|
fd: c_int,
|
||||||
{
|
buf: *mut c_void,
|
||||||
|
count: usize,
|
||||||
|
offset: i64,
|
||||||
|
) -> io::Result<isize> {
|
||||||
use libc::pread;
|
use libc::pread;
|
||||||
cvt(pread(fd, buf, count, offset))
|
cvt(pread(fd, buf, count, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt_pread(self.fd,
|
cvt_pread(
|
||||||
|
self.fd,
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
buf.as_mut_ptr() as *mut c_void,
|
||||||
cmp::min(buf.len(), max_len()),
|
cmp::min(buf.len(), max_len()),
|
||||||
offset as i64)
|
offset as i64,
|
||||||
|
)
|
||||||
.map(|n| n as usize)
|
.map(|n| n as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::write(self.fd,
|
libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
|
||||||
buf.as_ptr() as *const c_void,
|
|
||||||
cmp::min(buf.len(), max_len()))
|
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::writev(self.fd,
|
libc::writev(
|
||||||
|
self.fd,
|
||||||
bufs.as_ptr() as *const libc::iovec,
|
bufs.as_ptr() as *const libc::iovec,
|
||||||
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
|
cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<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)
|
unsafe fn cvt_pwrite(
|
||||||
-> io::Result<isize>
|
fd: c_int,
|
||||||
{
|
buf: *const c_void,
|
||||||
|
count: usize,
|
||||||
|
offset: i64,
|
||||||
|
) -> io::Result<isize> {
|
||||||
use libc::pwrite;
|
use libc::pwrite;
|
||||||
cvt(pwrite(fd, buf, count, offset))
|
cvt(pwrite(fd, buf, count, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt_pwrite(self.fd,
|
cvt_pwrite(
|
||||||
|
self.fd,
|
||||||
buf.as_ptr() as *const c_void,
|
buf.as_ptr() as *const c_void,
|
||||||
cmp::min(buf.len(), max_len()),
|
cmp::min(buf.len(), max_len()),
|
||||||
offset as i64)
|
offset as i64,
|
||||||
|
)
|
||||||
.map(|n| n as usize)
|
.map(|n| n as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cloexec(&self) -> io::Result<bool> {
|
pub fn get_cloexec(&self) -> io::Result<bool> {
|
||||||
unsafe {
|
unsafe { Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
|
||||||
Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cloexec(&self) -> io::Result<()> {
|
pub fn set_cloexec(&self) -> io::Result<()> {
|
||||||
@@ -139,23 +149,16 @@ impl FileDesc {
|
|||||||
pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> {
|
pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?;
|
let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?;
|
||||||
flags = if nonblocking {
|
flags = if nonblocking { flags | libc::O_NONBLOCK } else { flags & !libc::O_NONBLOCK };
|
||||||
flags | libc::O_NONBLOCK
|
|
||||||
} else {
|
|
||||||
flags & !libc::O_NONBLOCK
|
|
||||||
};
|
|
||||||
cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?;
|
cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn duplicate(&self) -> io::Result<FileDesc> {
|
pub fn duplicate(&self) -> io::Result<FileDesc> {
|
||||||
let fd = self.raw();
|
let fd = self.raw();
|
||||||
match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) {
|
match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) {
|
||||||
Ok(newfd) => {
|
Ok(newfd) => Ok(FileDesc::new(newfd)),
|
||||||
Ok(FileDesc::new(newfd))
|
|
||||||
}
|
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,7 +176,9 @@ impl<'a> Read for &'a FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<c_int> for 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 {
|
impl Drop for FileDesc {
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
// copies from linuxx
|
// copies from linuxx
|
||||||
use crate::ffi::{CString, CStr, OsString, OsStr};
|
use crate::ffi::{CStr, CString, OsStr, OsString};
|
||||||
use crate::sys::vxworks::ext::ffi::OsStrExt;
|
|
||||||
use crate::fmt;
|
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::mem;
|
||||||
use crate::path::{Path, PathBuf};
|
use crate::path::{Path, PathBuf};
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::sync::Arc;
|
use crate::sync::Arc;
|
||||||
use crate::sys::fd::FileDesc;
|
use crate::sys::fd::FileDesc;
|
||||||
use crate::sys::time::SystemTime;
|
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::{cvt, cvt_r};
|
||||||
use crate::sys_common::{AsInner, FromInner};
|
use crate::sys_common::{AsInner, FromInner};
|
||||||
use libc::{self, c_int, mode_t, stat64, off_t};
|
use libc::{self, c_int, mode_t, off_t, stat64};
|
||||||
use libc::{ftruncate, lseek, dirent, readdir_r as readdir64_r, open};
|
use libc::{dirent, ftruncate, lseek, open, readdir_r as readdir64_r};
|
||||||
use crate::sys::vxworks::ext::ffi::OsStringExt;
|
|
||||||
pub struct File(FileDesc);
|
pub struct File(FileDesc);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -58,16 +58,24 @@ pub struct OpenOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct FilePermissions { mode: mode_t }
|
pub struct FilePermissions {
|
||||||
|
mode: mode_t,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct FileType { mode: mode_t }
|
pub struct FileType {
|
||||||
|
mode: mode_t,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DirBuilder { mode: mode_t }
|
pub struct DirBuilder {
|
||||||
|
mode: mode_t,
|
||||||
|
}
|
||||||
|
|
||||||
impl FileAttr {
|
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 {
|
pub fn perm(&self) -> FilePermissions {
|
||||||
FilePermissions { mode: (self.stat.st_mode as mode_t) }
|
FilePermissions { mode: (self.stat.st_mode as mode_t) }
|
||||||
}
|
}
|
||||||
@@ -91,14 +99,17 @@ impl FileAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
Err(io::Error::new(io::ErrorKind::Other,
|
Err(io::Error::new(
|
||||||
"creation time is not available on this platform currently"))
|
io::ErrorKind::Other,
|
||||||
|
"creation time is not available on this platform currently",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<stat64> for FileAttr {
|
impl AsInner<stat64> for FileAttr {
|
||||||
fn as_inner(&self) -> &stat64 { &self.stat }
|
fn as_inner(&self) -> &stat64 {
|
||||||
|
&self.stat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilePermissions {
|
impl FilePermissions {
|
||||||
@@ -116,15 +127,25 @@ impl FilePermissions {
|
|||||||
self.mode |= 0o222;
|
self.mode |= 0o222;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn mode(&self) -> u32 { self.mode as u32 }
|
pub fn mode(&self) -> u32 {
|
||||||
|
self.mode as u32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileType {
|
impl FileType {
|
||||||
pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) }
|
pub fn is_dir(&self) -> bool {
|
||||||
pub fn is_file(&self) -> bool { self.is(libc::S_IFREG) }
|
self.is(libc::S_IFDIR)
|
||||||
pub fn is_symlink(&self) -> bool { self.is(libc::S_IFLNK) }
|
}
|
||||||
|
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 {
|
impl FromInner<u32> for FilePermissions {
|
||||||
@@ -149,10 +170,7 @@ impl Iterator for ReadDir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ret = DirEntry {
|
let mut ret = DirEntry { entry: mem::zeroed(), dir: self.clone() };
|
||||||
entry: mem::zeroed(),
|
|
||||||
dir: self.clone(),
|
|
||||||
};
|
|
||||||
let mut entry_ptr = ptr::null_mut();
|
let mut entry_ptr = ptr::null_mut();
|
||||||
loop {
|
loop {
|
||||||
if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
|
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)
|
// (instead of looping forever)
|
||||||
self.end_of_stream = true;
|
self.end_of_stream = true;
|
||||||
}
|
}
|
||||||
return Some(Err(Error::last_os_error()))
|
return Some(Err(Error::last_os_error()));
|
||||||
}
|
}
|
||||||
if entry_ptr.is_null() {
|
if entry_ptr.is_null() {
|
||||||
return None
|
return None;
|
||||||
}
|
}
|
||||||
if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
|
if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
|
||||||
return Some(Ok(ret))
|
return Some(Ok(ret));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,14 +211,12 @@ impl DirEntry {
|
|||||||
OsStr::from_bytes(self.name_bytes()).to_os_string()
|
OsStr::from_bytes(self.name_bytes()).to_os_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn metadata(&self) -> io::Result<FileAttr> {
|
pub fn metadata(&self) -> io::Result<FileAttr> {
|
||||||
lstat(&self.path())
|
lstat(&self.path())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_type(&self) -> io::Result<FileType> {
|
pub fn file_type(&self) -> io::Result<FileType> {
|
||||||
lstat(&self.path()).map(|m| m.file_type())
|
lstat(&self.path()).map(|m| m.file_type())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ino(&self) -> u64 {
|
pub fn ino(&self) -> u64 {
|
||||||
@@ -231,13 +247,27 @@ impl OpenOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self, read: bool) { self.read = read; }
|
pub fn read(&mut self, read: bool) {
|
||||||
pub fn write(&mut self, write: bool) { self.write = write; }
|
self.read = read;
|
||||||
pub fn append(&mut self, append: bool) { self.append = append; }
|
}
|
||||||
pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
|
pub fn write(&mut self, write: bool) {
|
||||||
pub fn create(&mut self, create: bool) { self.create = create; }
|
self.write = write;
|
||||||
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 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> {
|
fn get_access_mode(&self) -> io::Result<c_int> {
|
||||||
match (self.read, self.write, self.append) {
|
match (self.read, self.write, self.append) {
|
||||||
@@ -253,14 +283,16 @@ impl OpenOptions {
|
|||||||
fn get_creation_mode(&self) -> io::Result<c_int> {
|
fn get_creation_mode(&self) -> io::Result<c_int> {
|
||||||
match (self.write, self.append) {
|
match (self.write, self.append) {
|
||||||
(true, false) => {}
|
(true, false) => {}
|
||||||
(false, false) =>
|
(false, false) => {
|
||||||
if self.truncate || self.create || self.create_new {
|
if self.truncate || self.create || self.create_new {
|
||||||
return Err(Error::from_raw_os_error(libc::EINVAL));
|
return Err(Error::from_raw_os_error(libc::EINVAL));
|
||||||
},
|
}
|
||||||
(_, true) =>
|
}
|
||||||
|
(_, true) => {
|
||||||
if self.truncate && !self.create_new {
|
if self.truncate && !self.create_new {
|
||||||
return Err(Error::from_raw_os_error(libc::EINVAL));
|
return Err(Error::from_raw_os_error(libc::EINVAL));
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(match (self.create, self.truncate, self.create_new) {
|
Ok(match (self.create, self.truncate, self.create_new) {
|
||||||
@@ -280,21 +312,17 @@ impl File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
|
pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
|
||||||
let flags = libc::O_CLOEXEC |
|
let flags = libc::O_CLOEXEC
|
||||||
opts.get_access_mode()? |
|
| opts.get_access_mode()?
|
||||||
opts.get_creation_mode()? |
|
| opts.get_creation_mode()?
|
||||||
(opts.custom_flags as c_int & !libc::O_ACCMODE);
|
| (opts.custom_flags as c_int & !libc::O_ACCMODE);
|
||||||
let fd = cvt_r(|| unsafe {
|
let fd = cvt_r(|| unsafe { open(path.as_ptr(), flags, opts.mode as c_int) })?;
|
||||||
open(path.as_ptr(), flags, opts.mode as c_int)
|
|
||||||
})?;
|
|
||||||
Ok(File(FileDesc::new(fd)))
|
Ok(File(FileDesc::new(fd)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_attr(&self) -> io::Result<FileAttr> {
|
pub fn file_attr(&self) -> io::Result<FileAttr> {
|
||||||
let mut stat: stat64 = unsafe { mem::zeroed() };
|
let mut stat: stat64 = unsafe { mem::zeroed() };
|
||||||
cvt(unsafe {
|
cvt(unsafe { ::libc::fstat(self.0.raw(), &mut stat) })?;
|
||||||
::libc::fstat(self.0.raw(), &mut stat)
|
|
||||||
})?;
|
|
||||||
Ok(FileAttr { stat: stat })
|
Ok(FileAttr { stat: stat })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,13 +334,13 @@ impl File {
|
|||||||
pub fn datasync(&self) -> io::Result<()> {
|
pub fn datasync(&self) -> io::Result<()> {
|
||||||
cvt_r(|| unsafe { os_datasync(self.0.raw()) })?;
|
cvt_r(|| unsafe { os_datasync(self.0.raw()) })?;
|
||||||
return Ok(());
|
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<()> {
|
pub fn truncate(&self, size: u64) -> io::Result<()> {
|
||||||
return cvt_r(|| unsafe {
|
return cvt_r(|| unsafe { ftruncate(self.0.raw(), size as off_t) }).map(|_| ());
|
||||||
ftruncate(self.0.raw(), size as off_t)
|
|
||||||
}).map(|_| ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
@@ -339,7 +367,9 @@ impl File {
|
|||||||
self.0.write_at(buf, offset)
|
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> {
|
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
|
||||||
let (whence, pos) = match pos {
|
let (whence, pos) = match pos {
|
||||||
@@ -357,9 +387,13 @@ impl File {
|
|||||||
self.0.duplicate().map(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<()> {
|
pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
|
||||||
cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
|
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 {
|
impl fmt::Debug for File {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fn get_path(fd: c_int) -> Option<PathBuf> {
|
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()) };
|
let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) };
|
||||||
if n == -1 {
|
if n == -1 {
|
||||||
return None;
|
return None;
|
||||||
@@ -419,7 +453,7 @@ impl fmt::Debug for File {
|
|||||||
libc::O_RDONLY => Some((true, false)),
|
libc::O_RDONLY => Some((true, false)),
|
||||||
libc::O_RDWR => Some((true, true)),
|
libc::O_RDWR => Some((true, true)),
|
||||||
libc::O_WRONLY => Some((false, 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())
|
Err(Error::last_os_error())
|
||||||
} else {
|
} else {
|
||||||
let inner = InnerReadDir { dirp: Dir(ptr), root };
|
let inner = InnerReadDir { dirp: Dir(ptr), root };
|
||||||
Ok(ReadDir{
|
Ok(ReadDir { inner: Arc::new(inner), end_of_stream: false })
|
||||||
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<()> {
|
pub fn remove_dir_all(path: &Path) -> io::Result<()> {
|
||||||
let filetype = lstat(path)?.file_type();
|
let filetype = lstat(path)?.file_type();
|
||||||
if filetype.is_symlink() {
|
if filetype.is_symlink() { unlink(path) } else { remove_dir_all_recursive(path) }
|
||||||
unlink(path)
|
|
||||||
} else {
|
|
||||||
remove_dir_all_recursive(path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
|
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);
|
let mut buf = Vec::with_capacity(256);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let buf_read = cvt(unsafe {
|
let buf_read =
|
||||||
libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity())
|
cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize;
|
||||||
})? as usize;
|
|
||||||
|
|
||||||
unsafe { buf.set_len(buf_read); }
|
unsafe {
|
||||||
|
buf.set_len(buf_read);
|
||||||
|
}
|
||||||
|
|
||||||
if buf_read != buf.capacity() {
|
if buf_read != buf.capacity() {
|
||||||
buf.shrink_to_fit();
|
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> {
|
pub fn stat(p: &Path) -> io::Result<FileAttr> {
|
||||||
let p = cstr(p)?;
|
let p = cstr(p)?;
|
||||||
let mut stat: stat64 = unsafe { mem::zeroed() };
|
let mut stat: stat64 = unsafe { mem::zeroed() };
|
||||||
cvt(unsafe {
|
cvt(unsafe { libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?;
|
||||||
libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _)
|
|
||||||
})?;
|
|
||||||
Ok(FileAttr { stat })
|
Ok(FileAttr { stat })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
|
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
|
||||||
let p = cstr(p)?;
|
let p = cstr(p)?;
|
||||||
let mut stat: stat64 = unsafe { mem::zeroed() };
|
let mut stat: stat64 = unsafe { mem::zeroed() };
|
||||||
cvt(unsafe {
|
cvt(unsafe { ::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?;
|
||||||
::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
|
|
||||||
})?;
|
|
||||||
Ok(FileAttr { stat })
|
Ok(FileAttr { stat })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +588,7 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::realpath(path.as_ptr(), ptr::null_mut());
|
let r = libc::realpath(path.as_ptr(), ptr::null_mut());
|
||||||
if r.is_null() {
|
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();
|
buf = CStr::from_ptr(r).to_bytes().to_vec();
|
||||||
libc::free(r as *mut _);
|
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> {
|
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||||
use crate::fs::File;
|
use crate::fs::File;
|
||||||
if !from.is_file() {
|
if !from.is_file() {
|
||||||
return Err(Error::new(ErrorKind::InvalidInput,
|
return Err(Error::new(
|
||||||
"the source path is not an existing regular file"))
|
ErrorKind::InvalidInput,
|
||||||
|
"the source path is not an existing regular file",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = File::open(from)?;
|
let mut reader = File::open(from)?;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use crate::slice;
|
use crate::slice;
|
||||||
|
|
||||||
use libc::{iovec, c_void};
|
use libc::{c_void, iovec};
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct IoSlice<'a> {
|
pub struct IoSlice<'a> {
|
||||||
@@ -13,10 +13,7 @@ impl<'a> IoSlice<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||||
IoSlice {
|
IoSlice {
|
||||||
vec: iovec {
|
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
|
||||||
iov_base: buf.as_ptr() as *mut u8 as *mut c_void,
|
|
||||||
iov_len: buf.len()
|
|
||||||
},
|
|
||||||
_p: PhantomData,
|
_p: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,9 +32,7 @@ impl<'a> IoSlice<'a> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe {
|
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,10 +45,7 @@ impl<'a> IoSliceMut<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||||
IoSliceMut {
|
IoSliceMut {
|
||||||
vec: iovec {
|
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
|
||||||
iov_base: buf.as_mut_ptr() as *mut c_void,
|
|
||||||
iov_len: buf.len()
|
|
||||||
},
|
|
||||||
_p: PhantomData,
|
_p: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,15 +64,11 @@ impl<'a> IoSliceMut<'a> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe {
|
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
unsafe {
|
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
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(
|
libc::memchr(
|
||||||
haystack.as_ptr() as *const libc::c_void,
|
haystack.as_ptr() as *const libc::c_void,
|
||||||
needle as libc::c_int,
|
needle as libc::c_int,
|
||||||
haystack.len())
|
haystack.len(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
if p.is_null() {
|
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(p as usize - (haystack.as_ptr() as usize))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
use crate::io::ErrorKind;
|
use crate::io::ErrorKind;
|
||||||
|
|
||||||
pub use crate::os::vxworks as platform;
|
|
||||||
pub use self::rand::hashmap_random_keys;
|
pub use self::rand::hashmap_random_keys;
|
||||||
|
pub use crate::os::vxworks as platform;
|
||||||
pub use libc::strlen;
|
pub use libc::strlen;
|
||||||
|
|
||||||
pub mod alloc;
|
pub mod alloc;
|
||||||
@@ -16,8 +16,8 @@ pub mod ext;
|
|||||||
pub mod fast_thread_local;
|
pub mod fast_thread_local;
|
||||||
pub mod fd;
|
pub mod fd;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod memchr;
|
|
||||||
pub mod io;
|
pub mod io;
|
||||||
|
pub mod memchr;
|
||||||
pub mod mutex;
|
pub mod mutex;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod os;
|
pub mod os;
|
||||||
@@ -27,10 +27,10 @@ pub mod process;
|
|||||||
pub mod rand;
|
pub mod rand;
|
||||||
pub mod rwlock;
|
pub mod rwlock;
|
||||||
pub mod stack_overflow;
|
pub mod stack_overflow;
|
||||||
|
pub mod stdio;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
pub mod thread_local;
|
pub mod thread_local;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
pub mod stdio;
|
|
||||||
|
|
||||||
pub use crate::sys_common::os_str_bytes as os_str;
|
pub use crate::sys_common::os_str_bytes as os_str;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ pub fn init() {
|
|||||||
reset_sigpipe();
|
reset_sigpipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn reset_sigpipe() { }
|
unsafe fn reset_sigpipe() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use libc::signal;
|
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,
|
// These two constants can have the same value on some systems,
|
||||||
// but different values on others, so we can't use a match
|
// but different values on others, so we can't use a match
|
||||||
// clause
|
// clause
|
||||||
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
|
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => ErrorKind::WouldBlock,
|
||||||
ErrorKind::WouldBlock,
|
|
||||||
|
|
||||||
_ => ErrorKind::Other,
|
_ => ErrorKind::Other,
|
||||||
}
|
}
|
||||||
@@ -94,16 +93,13 @@ macro_rules! impl_is_minus_one {
|
|||||||
impl_is_minus_one! { i8 i16 i32 i64 isize }
|
impl_is_minus_one! { i8 i16 i32 i64 isize }
|
||||||
|
|
||||||
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
|
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
|
||||||
if t.is_minus_one() {
|
if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) }
|
||||||
Err(crate::io::Error::last_os_error())
|
|
||||||
} else {
|
|
||||||
Ok(t)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
|
pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
|
||||||
where T: IsMinusOne,
|
where
|
||||||
F: FnMut() -> T
|
T: IsMinusOne,
|
||||||
|
F: FnMut() -> T,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
match cvt(f()) {
|
match cvt(f()) {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use crate::cell::UnsafeCell;
|
use crate::cell::UnsafeCell;
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
|
|
||||||
pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
|
pub struct Mutex {
|
||||||
|
inner: UnsafeCell<libc::pthread_mutex_t>,
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t {
|
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 Send for ReentrantMutex {}
|
||||||
unsafe impl Sync for ReentrantMutex {}
|
unsafe impl Sync for ReentrantMutex {}
|
||||||
@@ -96,8 +100,8 @@ impl ReentrantMutex {
|
|||||||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||||
let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
|
let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
|
||||||
debug_assert_eq!(result, 0);
|
debug_assert_eq!(result, 0);
|
||||||
let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
|
let result =
|
||||||
libc::PTHREAD_MUTEX_RECURSIVE);
|
libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_RECURSIVE);
|
||||||
debug_assert_eq!(result, 0);
|
debug_assert_eq!(result, 0);
|
||||||
let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
|
let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
|
||||||
debug_assert_eq!(result, 0);
|
debug_assert_eq!(result, 0);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
|
use crate::cmp;
|
||||||
use crate::ffi::CStr;
|
use crate::ffi::CStr;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::io::{IoSlice, IoSliceMut};
|
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::mem;
|
||||||
use crate::net::{SocketAddr, Shutdown};
|
use crate::net::{Shutdown, SocketAddr};
|
||||||
use crate::str;
|
use crate::str;
|
||||||
use crate::sys::fd::FileDesc;
|
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::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||||
|
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||||
use crate::time::{Duration, Instant};
|
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};
|
pub use crate::sys::{cvt, cvt_r};
|
||||||
|
|
||||||
@@ -18,7 +18,6 @@ pub extern crate libc as netc;
|
|||||||
|
|
||||||
pub type wrlen_t = size_t;
|
pub type wrlen_t = size_t;
|
||||||
|
|
||||||
|
|
||||||
const SOCK_CLOEXEC: c_int = 0;
|
const SOCK_CLOEXEC: c_int = 0;
|
||||||
const SO_NOSIGPIPE: 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<()> {
|
pub fn cvt_gai(err: c_int) -> io::Result<()> {
|
||||||
if err == 0 {
|
if err == 0 {
|
||||||
return Ok(())
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
|
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
|
||||||
on_resolver_failure();
|
on_resolver_failure();
|
||||||
|
|
||||||
if err == EAI_SYSTEM {
|
if err == EAI_SYSTEM {
|
||||||
return Err(io::Error::last_os_error())
|
return Err(io::Error::last_os_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
let detail = unsafe {
|
let detail = unsafe {
|
||||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
|
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap().to_owned()
|
||||||
.to_owned()
|
|
||||||
};
|
};
|
||||||
Err(io::Error::new(io::ErrorKind::Other,
|
Err(io::Error::new(
|
||||||
&format!("failed to lookup address information: {}",
|
io::ErrorKind::Other,
|
||||||
detail)[..]))
|
&format!("failed to lookup address information: {}", detail)[..],
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socket {
|
impl Socket {
|
||||||
@@ -85,15 +84,13 @@ impl Socket {
|
|||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pollfd = libc::pollfd {
|
let mut pollfd = libc::pollfd { fd: self.0.raw(), events: libc::POLLOUT, revents: 0 };
|
||||||
fd: self.0.raw(),
|
|
||||||
events: libc::POLLOUT,
|
|
||||||
revents: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
@@ -105,7 +102,8 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let timeout = timeout - elapsed;
|
let timeout = timeout - elapsed;
|
||||||
let mut timeout = timeout.as_secs()
|
let mut timeout = timeout
|
||||||
|
.as_secs()
|
||||||
.saturating_mul(1_000)
|
.saturating_mul(1_000)
|
||||||
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
@@ -126,8 +124,7 @@ impl Socket {
|
|||||||
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
||||||
// for POLLHUP rather than read readiness
|
// for POLLHUP rather than read readiness
|
||||||
if pollfd.revents & libc::POLLHUP != 0 {
|
if pollfd.revents & libc::POLLHUP != 0 {
|
||||||
let e = self.take_error()?
|
let e = self.take_error()?.unwrap_or_else(|| {
|
||||||
.unwrap_or_else(|| {
|
|
||||||
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
|
||||||
});
|
});
|
||||||
return Err(e);
|
return Err(e);
|
||||||
@@ -139,11 +136,8 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
|
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
|
||||||
-> io::Result<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);
|
let fd = FileDesc::new(fd);
|
||||||
fd.set_cloexec()?;
|
fd.set_cloexec()?;
|
||||||
Ok(Socket(fd))
|
Ok(Socket(fd))
|
||||||
@@ -155,10 +149,7 @@ impl Socket {
|
|||||||
|
|
||||||
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::recv(self.0.raw(),
|
libc::recv(self.0.raw(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags)
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
|
||||||
buf.len(),
|
|
||||||
flags)
|
|
||||||
})?;
|
})?;
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
@@ -175,18 +166,23 @@ impl Socket {
|
|||||||
self.0.read_vectored(bufs)
|
self.0.read_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
|
fn recv_from_with_flags(
|
||||||
-> io::Result<(usize, SocketAddr)> {
|
&self,
|
||||||
|
buf: &mut [u8],
|
||||||
|
flags: c_int,
|
||||||
|
) -> io::Result<(usize, SocketAddr)> {
|
||||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||||
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
|
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
|
||||||
|
|
||||||
let n = cvt(unsafe {
|
let n = cvt(unsafe {
|
||||||
libc::recvfrom(self.0.raw(),
|
libc::recvfrom(
|
||||||
|
self.0.raw(),
|
||||||
buf.as_mut_ptr() as *mut c_void,
|
buf.as_mut_ptr() as *mut c_void,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
flags,
|
flags,
|
||||||
&mut storage as *mut _ as *mut _,
|
&mut storage as *mut _ as *mut _,
|
||||||
&mut addrlen)
|
&mut addrlen,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||||
}
|
}
|
||||||
@@ -211,8 +207,10 @@ impl Socket {
|
|||||||
let timeout = match dur {
|
let timeout = match dur {
|
||||||
Some(dur) => {
|
Some(dur) => {
|
||||||
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
return Err(io::Error::new(
|
||||||
"cannot set a 0 duration timeout"));
|
io::ErrorKind::InvalidInput,
|
||||||
|
"cannot set a 0 duration timeout",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
|
let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
|
||||||
@@ -229,12 +227,7 @@ impl Socket {
|
|||||||
}
|
}
|
||||||
timeout
|
timeout
|
||||||
}
|
}
|
||||||
None => {
|
None => libc::timeval { tv_sec: 0, tv_usec: 0 },
|
||||||
libc::timeval {
|
|
||||||
tv_sec: 0,
|
|
||||||
tv_usec: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
||||||
}
|
}
|
||||||
@@ -276,24 +269,26 @@ impl Socket {
|
|||||||
|
|
||||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
|
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
|
||||||
if raw == 0 {
|
if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Ok(Some(io::Error::from_raw_os_error(raw as i32)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsInner<c_int> for Socket {
|
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 {
|
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 {
|
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
|
// 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).
|
// believe it's thread-safe).
|
||||||
#[cfg(target_env = "gnu")]
|
#[cfg(target_env = "gnu")]
|
||||||
fn on_resolver_failure() {
|
fn on_resolver_failure() {
|
||||||
/*
|
/*
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
|
|
||||||
// If the version fails to parse, we treat it the same as "not glibc".
|
// 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::ffi::OsStr;
|
||||||
|
use crate::path::Prefix;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_sep_byte(b: u8) -> bool {
|
pub fn is_sep_byte(b: u8) -> bool {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::io::{self, IoSlice, IoSliceMut};
|
use crate::io::{self, IoSlice, IoSliceMut};
|
||||||
use libc::{self /*, c_int apparently not used? */};
|
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::sync::atomic::{AtomicBool};
|
use crate::sync::atomic::AtomicBool;
|
||||||
use crate::sys::fd::FileDesc;
|
use crate::sys::fd::FileDesc;
|
||||||
use crate::sys::{cvt, cvt_r};
|
use crate::sys::{cvt, cvt_r};
|
||||||
|
use libc::{self /*, c_int apparently not used? */};
|
||||||
|
|
||||||
pub struct AnonPipe(FileDesc);
|
pub struct AnonPipe(FileDesc);
|
||||||
|
|
||||||
@@ -36,18 +36,18 @@ impl AnonPipe {
|
|||||||
self.0.write_vectored(bufs)
|
self.0.write_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
pub fn fd(&self) -> &FileDesc {
|
||||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
&self.0
|
||||||
|
}
|
||||||
|
pub fn into_fd(self) -> FileDesc {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
pub fn diverge(&self) -> ! {
|
pub fn diverge(&self) -> ! {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read2(p1: AnonPipe,
|
pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
|
||||||
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
|
// 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!
|
// in the `select` loop below, and we wouldn't want one to block the other!
|
||||||
let p1 = p1.into_fd();
|
let p1 = p1.into_fd();
|
||||||
@@ -83,8 +83,9 @@ pub fn read2(p1: AnonPipe,
|
|||||||
match fd.read_to_end(dst) {
|
match fd.read_to_end(dst) {
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
|
if e.raw_os_error() == Some(libc::EWOULDBLOCK)
|
||||||
e.raw_os_error() == Some(libc::EAGAIN) {
|
|| e.raw_os_error() == Some(libc::EAGAIN)
|
||||||
|
{
|
||||||
Ok(false)
|
Ok(false)
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
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 self::process_inner::Process;
|
||||||
pub use crate::ffi::OsString as EnvKey;
|
pub use crate::ffi::OsString as EnvKey;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::os::unix::prelude::*;
|
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::fmt;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
@@ -8,9 +9,8 @@ use crate::sys::fd::FileDesc;
|
|||||||
use crate::sys::fs::{File, OpenOptions};
|
use crate::sys::fs::{File, OpenOptions};
|
||||||
use crate::sys::pipe::{self, AnonPipe};
|
use crate::sys::pipe::{self, AnonPipe};
|
||||||
use crate::sys_common::process::CommandEnv;
|
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
|
// Command
|
||||||
@@ -150,10 +150,7 @@ impl Command {
|
|||||||
&mut self.closures
|
&mut self.closures
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn pre_exec(
|
pub unsafe fn pre_exec(&mut self, _f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
|
||||||
&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.
|
// Fork() is not supported in vxWorks so no way to run the closure in the new procecss.
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
@@ -183,26 +180,21 @@ impl Command {
|
|||||||
self.env.have_changed_path()
|
self.env.have_changed_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
|
pub fn setup_io(
|
||||||
-> io::Result<(StdioPipes, ChildPipes)> {
|
&self,
|
||||||
|
default: Stdio,
|
||||||
|
needs_stdin: bool,
|
||||||
|
) -> io::Result<(StdioPipes, ChildPipes)> {
|
||||||
let null = Stdio::Null;
|
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 stdin = self.stdin.as_ref().unwrap_or(default_stdin);
|
||||||
let stdout = self.stdout.as_ref().unwrap_or(&default);
|
let stdout = self.stdout.as_ref().unwrap_or(&default);
|
||||||
let stderr = self.stderr.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_stdin, our_stdin) = stdin.to_child_stdio(true)?;
|
||||||
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
|
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
|
||||||
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
|
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
|
||||||
let ours = StdioPipes {
|
let ours = StdioPipes { stdin: our_stdin, stdout: our_stdout, stderr: our_stderr };
|
||||||
stdin: our_stdin,
|
let theirs = ChildPipes { stdin: their_stdin, stdout: their_stdout, stderr: their_stderr };
|
||||||
stdout: our_stdout,
|
|
||||||
stderr: our_stderr,
|
|
||||||
};
|
|
||||||
let theirs = ChildPipes {
|
|
||||||
stdin: their_stdin,
|
|
||||||
stdout: their_stdout,
|
|
||||||
stderr: their_stderr,
|
|
||||||
};
|
|
||||||
Ok((ours, theirs))
|
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.
|
// Helper type to manage ownership of the strings within a C-style array.
|
||||||
pub struct CStringArray {
|
pub struct CStringArray {
|
||||||
items: Vec<CString>,
|
items: Vec<CString>,
|
||||||
ptrs: Vec<*const c_char>
|
ptrs: Vec<*const c_char>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CStringArray {
|
impl CStringArray {
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
let mut result = CStringArray {
|
let mut result = CStringArray {
|
||||||
items: Vec::with_capacity(capacity),
|
items: Vec::with_capacity(capacity),
|
||||||
ptrs: Vec::with_capacity(capacity+1)
|
ptrs: Vec::with_capacity(capacity + 1),
|
||||||
};
|
};
|
||||||
result.ptrs.push(ptr::null());
|
result.ptrs.push(ptr::null());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn push(&mut self, item: CString) {
|
pub fn push(&mut self, item: CString) {
|
||||||
let l = self.ptrs.len();
|
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.ptrs.push(ptr::null());
|
||||||
self.items.push(item);
|
self.items.push(item);
|
||||||
}
|
}
|
||||||
@@ -262,12 +254,9 @@ fn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStr
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stdio {
|
impl Stdio {
|
||||||
pub fn to_child_stdio(&self, readable: bool)
|
pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
||||||
-> io::Result<(ChildStdio, Option<AnonPipe>)> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Stdio::Inherit => {
|
Stdio::Inherit => Ok((ChildStdio::Inherit, None)),
|
||||||
Ok((ChildStdio::Inherit, None))
|
|
||||||
},
|
|
||||||
|
|
||||||
// Make sure that the source descriptors are not an stdio
|
// Make sure that the source descriptors are not an stdio
|
||||||
// descriptor, otherwise the order which we set the child's
|
// descriptor, otherwise the order which we set the child's
|
||||||
@@ -286,11 +275,7 @@ impl Stdio {
|
|||||||
|
|
||||||
Stdio::MakePipe => {
|
Stdio::MakePipe => {
|
||||||
let (reader, writer) = pipe::anon_pipe()?;
|
let (reader, writer) = pipe::anon_pipe()?;
|
||||||
let (ours, theirs) = if readable {
|
let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) };
|
||||||
(writer, reader)
|
|
||||||
} else {
|
|
||||||
(reader, writer)
|
|
||||||
};
|
|
||||||
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
|
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,9 +283,7 @@ impl Stdio {
|
|||||||
let mut opts = OpenOptions::new();
|
let mut opts = OpenOptions::new();
|
||||||
opts.read(readable);
|
opts.read(readable);
|
||||||
opts.write(!readable);
|
opts.write(!readable);
|
||||||
let path = unsafe {
|
let path = unsafe { CStr::from_ptr("/null\0".as_ptr() as *const _) };
|
||||||
CStr::from_ptr("/null\0".as_ptr() as *const _)
|
|
||||||
};
|
|
||||||
let fd = File::open_c(&path, &opts)?;
|
let fd = File::open_c(&path, &opts)?;
|
||||||
Ok((ChildStdio::Owned(fd.into_fd()), None))
|
Ok((ChildStdio::Owned(fd.into_fd()), None))
|
||||||
}
|
}
|
||||||
@@ -350,7 +333,8 @@ impl ExitStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exited(&self) -> bool {
|
fn exited(&self) -> bool {
|
||||||
/*unsafe*/ { libc::WIFEXITED(self.0) }
|
/*unsafe*/
|
||||||
|
{ libc::WIFEXITED(self.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn success(&self) -> bool {
|
pub fn success(&self) -> bool {
|
||||||
|
|||||||
@@ -4,17 +4,16 @@ use crate::slice;
|
|||||||
pub fn hashmap_random_keys() -> (u64, u64) {
|
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||||
let mut v = (0, 0);
|
let mut v = (0, 0);
|
||||||
unsafe {
|
unsafe {
|
||||||
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
|
let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, mem::size_of_val(&v));
|
||||||
mem::size_of_val(&v));
|
|
||||||
imp::fill_bytes(view);
|
imp::fill_bytes(view);
|
||||||
}
|
}
|
||||||
return v
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use libc;
|
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
|
use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
|
||||||
|
use libc;
|
||||||
|
|
||||||
pub fn fill_bytes(v: &mut [u8]) {
|
pub fn fill_bytes(v: &mut [u8]) {
|
||||||
static RNG_INIT: AtomicBool = AtomicBool::new(false);
|
static RNG_INIT: AtomicBool = AtomicBool::new(false);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use libc;
|
|
||||||
use crate::cell::UnsafeCell;
|
use crate::cell::UnsafeCell;
|
||||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use libc;
|
||||||
|
|
||||||
pub struct RWLock {
|
pub struct RWLock {
|
||||||
inner: UnsafeCell<libc::pthread_rwlock_t>,
|
inner: UnsafeCell<libc::pthread_rwlock_t>,
|
||||||
@@ -57,8 +57,10 @@ impl RWLock {
|
|||||||
let r = libc::pthread_rwlock_wrlock(self.inner.get());
|
let r = libc::pthread_rwlock_wrlock(self.inner.get());
|
||||||
// See comments above for why we check for EDEADLK and write_locked. We
|
// See comments above for why we check for EDEADLK and write_locked. We
|
||||||
// also need to check that num_readers is 0.
|
// also need to check that num_readers is 0.
|
||||||
if r == libc::EDEADLK || *self.write_locked.get() ||
|
if r == libc::EDEADLK
|
||||||
self.num_readers.load(Ordering::Relaxed) != 0 {
|
|| *self.write_locked.get()
|
||||||
|
|| self.num_readers.load(Ordering::Relaxed) != 0
|
||||||
|
{
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
self.raw_unlock();
|
self.raw_unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#![cfg_attr(test, allow(dead_code))]
|
#![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::cleanup;
|
||||||
pub use self::imp::init;
|
pub use self::imp::init;
|
||||||
|
|
||||||
pub struct Handler {
|
pub struct Handler {
|
||||||
_data: *mut libc::c_void
|
_data: *mut libc::c_void,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
@@ -26,16 +26,13 @@ impl Drop for Handler {
|
|||||||
mod imp {
|
mod imp {
|
||||||
use crate::ptr;
|
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 {
|
pub unsafe fn make_handler() -> super::Handler {
|
||||||
super::Handler { _data: ptr::null_mut() }
|
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(());
|
pub struct Stderr(());
|
||||||
|
|
||||||
impl Stdin {
|
impl Stdin {
|
||||||
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
|
pub fn new() -> io::Result<Stdin> {
|
||||||
|
Ok(Stdin(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Read for Stdin {
|
impl io::Read for Stdin {
|
||||||
@@ -19,7 +21,9 @@ impl io::Read for Stdin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stdout {
|
impl Stdout {
|
||||||
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
|
pub fn new() -> io::Result<Stdout> {
|
||||||
|
Ok(Stdout(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for Stdout {
|
impl io::Write for Stdout {
|
||||||
@@ -36,7 +40,9 @@ impl io::Write for Stdout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stderr {
|
impl Stderr {
|
||||||
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
|
pub fn new() -> io::Result<Stderr> {
|
||||||
|
Ok(Stderr(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for 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,
|
// 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.
|
// 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,
|
unsafe fn pthread_attr_setstacksize(
|
||||||
stack_size: libc::size_t) -> libc::c_int {
|
attr: *mut libc::pthread_attr_t,
|
||||||
|
stack_size: libc::size_t,
|
||||||
|
) -> libc::c_int {
|
||||||
libc::pthread_attr_setstacksize(attr, stack_size)
|
libc::pthread_attr_setstacksize(attr, stack_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||||
-> io::Result<Thread> {
|
|
||||||
let p = box p;
|
let p = box p;
|
||||||
let mut native: libc::pthread_t = mem::zeroed();
|
let mut native: libc::pthread_t = mem::zeroed();
|
||||||
let mut attr: libc::pthread_attr_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));
|
let stack_size = cmp::max(stack, min_stack_size(&attr));
|
||||||
|
|
||||||
match pthread_attr_setstacksize(&mut attr,
|
match pthread_attr_setstacksize(&mut attr, stack_size) {
|
||||||
stack_size) {
|
|
||||||
0 => {}
|
0 => {}
|
||||||
n => {
|
n => {
|
||||||
assert_eq!(n, libc::EINVAL);
|
assert_eq!(n, libc::EINVAL);
|
||||||
@@ -47,15 +47,13 @@ impl Thread {
|
|||||||
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
||||||
// Round up to the nearest page and try again.
|
// Round up to the nearest page and try again.
|
||||||
let page_size = os::page_size();
|
let page_size = os::page_size();
|
||||||
let stack_size = (stack_size + page_size - 1) &
|
let stack_size =
|
||||||
(-(page_size as isize - 1) as usize - 1);
|
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
|
||||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
|
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
|
||||||
stack_size), 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret = libc::pthread_create(&mut native, &attr, thread_start,
|
let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
|
||||||
&*p as *const _ as *mut _);
|
|
||||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||||
|
|
||||||
return if ret != 0 {
|
return if ret != 0 {
|
||||||
@@ -65,8 +63,10 @@ impl Thread {
|
|||||||
Ok(Thread { id: native })
|
Ok(Thread { id: native })
|
||||||
};
|
};
|
||||||
|
|
||||||
extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
|
||||||
unsafe { start_thread(main as *mut u8); }
|
unsafe {
|
||||||
|
start_thread(main as *mut u8);
|
||||||
|
}
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,12 +108,13 @@ impl Thread {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
assert!(ret == 0,
|
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
|
||||||
"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 {
|
pub fn into_id(self) -> libc::pthread_t {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
@@ -133,8 +134,12 @@ impl Drop for Thread {
|
|||||||
pub mod guard {
|
pub mod guard {
|
||||||
use crate::ops::Range;
|
use crate::ops::Range;
|
||||||
pub type Guard = Range<usize>;
|
pub type Guard = Range<usize>;
|
||||||
pub unsafe fn current() -> Option<Guard> { None }
|
pub unsafe fn current() -> Option<Guard> {
|
||||||
pub unsafe fn init() -> Option<Guard> { None }
|
None
|
||||||
|
}
|
||||||
|
pub unsafe fn init() -> Option<Guard> {
|
||||||
|
None
|
||||||
|
}
|
||||||
pub unsafe fn deinit() {}
|
pub unsafe fn deinit() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::mem;
|
|||||||
pub type Key = libc::pthread_key_t;
|
pub type Key = libc::pthread_key_t;
|
||||||
|
|
||||||
#[inline]
|
#[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;
|
let mut key = 0;
|
||||||
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
||||||
key
|
key
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::cmp::Ordering;
|
use crate::cmp::Ordering;
|
||||||
use libc;
|
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
use ::core::hash::{Hash, Hasher};
|
use ::core::hash::{Hash, Hasher};
|
||||||
|
use libc;
|
||||||
|
|
||||||
pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
|
pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
|
||||||
use crate::convert::TryInto;
|
use crate::convert::TryInto;
|
||||||
@@ -15,19 +15,20 @@ struct Timespec {
|
|||||||
|
|
||||||
impl Timespec {
|
impl Timespec {
|
||||||
const fn zero() -> Timespec {
|
const fn zero() -> Timespec {
|
||||||
Timespec {
|
Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
|
||||||
t: libc::timespec { tv_sec: 0, tv_nsec: 0 },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
||||||
if self >= other {
|
if self >= other {
|
||||||
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
||||||
Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
|
Duration::new(
|
||||||
(self.t.tv_nsec - other.t.tv_nsec) as u32)
|
(self.t.tv_sec - other.t.tv_sec) as u64,
|
||||||
|
(self.t.tv_nsec - other.t.tv_nsec) as u32,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
Duration::new(
|
||||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
|
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||||
other.t.tv_nsec as u32)
|
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
match other.sub_timespec(self) {
|
match other.sub_timespec(self) {
|
||||||
@@ -51,12 +52,7 @@ impl Timespec {
|
|||||||
nsec -= NSEC_PER_SEC as u32;
|
nsec -= NSEC_PER_SEC as u32;
|
||||||
secs = secs.checked_add(1)?;
|
secs = secs.checked_add(1)?;
|
||||||
}
|
}
|
||||||
Some(Timespec {
|
Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||||
t: libc::timespec {
|
|
||||||
tv_sec: secs,
|
|
||||||
tv_nsec: nsec as _,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
|
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
|
||||||
@@ -72,12 +68,7 @@ impl Timespec {
|
|||||||
nsec += NSEC_PER_SEC as i32;
|
nsec += NSEC_PER_SEC as i32;
|
||||||
secs = secs.checked_sub(1)?;
|
secs = secs.checked_sub(1)?;
|
||||||
}
|
}
|
||||||
Some(Timespec {
|
Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||||
t: libc::timespec {
|
|
||||||
tv_sec: secs,
|
|
||||||
tv_nsec: nsec as _,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,16 +95,16 @@ impl Ord for Timespec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Hash 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_sec.hash(state);
|
||||||
self.t.tv_nsec.hash(state);
|
self.t.tv_nsec.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod inner {
|
mod inner {
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use libc;
|
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
|
use libc;
|
||||||
|
|
||||||
use super::Timespec;
|
use super::Timespec;
|
||||||
|
|
||||||
@@ -127,14 +118,8 @@ mod inner {
|
|||||||
t: Timespec,
|
t: Timespec,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const UNIX_EPOCH: SystemTime = SystemTime {
|
pub const UNIX_EPOCH: SystemTime =
|
||||||
t: Timespec {
|
SystemTime { t: Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } } };
|
||||||
t: libc::timespec {
|
|
||||||
tv_sec: 0,
|
|
||||||
tv_nsec: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Instant {
|
impl Instant {
|
||||||
pub fn now() -> Instant {
|
pub fn now() -> Instant {
|
||||||
@@ -142,9 +127,7 @@ mod inner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const fn zero() -> Instant {
|
pub const fn zero() -> Instant {
|
||||||
Instant {
|
Instant { t: Timespec::zero() }
|
||||||
t: Timespec::zero(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn actually_monotonic() -> bool {
|
pub fn actually_monotonic() -> bool {
|
||||||
@@ -178,8 +161,7 @@ mod inner {
|
|||||||
SystemTime { t: now(libc::CLOCK_REALTIME) }
|
SystemTime { t: now(libc::CLOCK_REALTIME) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub_time(&self, other: &SystemTime)
|
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||||
-> Result<Duration, Duration> {
|
|
||||||
self.t.sub_timespec(&other.t)
|
self.t.sub_timespec(&other.t)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,15 +192,8 @@ mod inner {
|
|||||||
pub type clock_t = libc::c_int;
|
pub type clock_t = libc::c_int;
|
||||||
|
|
||||||
fn now(clock: clock_t) -> Timespec {
|
fn now(clock: clock_t) -> Timespec {
|
||||||
let mut t = Timespec {
|
let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
|
||||||
t: libc::timespec {
|
cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
|
||||||
tv_sec: 0,
|
|
||||||
tv_nsec: 0,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cvt(unsafe {
|
|
||||||
libc::clock_gettime(clock, &mut t.t)
|
|
||||||
}).unwrap();
|
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,7 @@ pub struct Weak<F> {
|
|||||||
|
|
||||||
impl<F> Weak<F> {
|
impl<F> Weak<F> {
|
||||||
pub const fn new(name: &'static str) -> Weak<F> {
|
pub const fn new(name: &'static str) -> Weak<F> {
|
||||||
Weak {
|
Weak { name, addr: AtomicUsize::new(1), _marker: marker::PhantomData }
|
||||||
name,
|
|
||||||
addr: AtomicUsize::new(1),
|
|
||||||
_marker: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> Option<F> {
|
pub fn get(&self) -> Option<F> {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user