-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redox Support Preview #37702
Redox Support Preview #37702
Changes from 35 commits
8b09e01
a5de9bb
68fd7ee
b1b35dd
ea6f5aa
37bfef0
4edcddf
c77979b
123d08b
74dc845
01e8378
ced32a0
a908509
79a8c27
25e1a4a
0bb9a95
a0b5dfe
18bf054
de68ace
73f24d4
2e5c821
267bc54
f01add1
2556400
ae2029f
b3c91df
4a0bc71
6733074
3a1bb2b
d73d32f
746222f
2ec2132
1d0bba8
6378c77
e683933
7294422
056ebcc
c61baa0
7e7775c
daaa231
3e15dc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,7 @@ mod imp; | |
|
||
// i686-pc-windows-gnu and all others | ||
#[cfg(any(all(unix, not(target_os = "emscripten")), | ||
target_os = "redox", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redox could potentially use |
||
all(windows, target_arch = "x86", target_env = "gnu")))] | ||
#[path = "gcc.rs"] | ||
mod imp; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,11 +81,11 @@ impl Read for StdinRaw { | |
} | ||
impl Write for StdoutRaw { | ||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) } | ||
fn flush(&mut self) -> io::Result<()> { Ok(()) } | ||
fn flush(&mut self) -> io::Result<()> { self.0.flush() } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Redox, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to support manual terminal refreshes, Redox allows applications to access fsync on stdout and stderr |
||
} | ||
impl Write for StderrRaw { | ||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) } | ||
fn flush(&mut self) -> io::Result<()> { Ok(()) } | ||
fn flush(&mut self) -> io::Result<()> { self.0.flush() } | ||
} | ||
|
||
enum Maybe<T> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ | |
#![stable(feature = "os", since = "1.0.0")] | ||
#![allow(missing_docs, bad_style)] | ||
|
||
#[cfg(unix)] | ||
#[cfg(any(target_os = "redox", unix))] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We also export |
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub use sys::ext as unix; | ||
#[cfg(windows)] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,7 +136,9 @@ use sys::path::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix}; | |
// Windows Prefixes | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
/// Path prefixes (Windows only). | ||
/// Path prefixes (Redox and Windows only). | ||
/// | ||
/// Redox uses schemes like `scheme:reference` to identify different I/O systems | ||
/// | ||
/// Windows uses a variety of path styles, including references to drive | ||
/// volumes (like `C:`), network shared folders (like `\\server\share`) and | ||
|
@@ -185,6 +187,9 @@ impl<'a> Prefix<'a> { | |
os_str_as_u8_slice(s).len() | ||
} | ||
match *self { | ||
#[cfg(target_os = "redox")] | ||
Verbatim(x) => 1 + os_str_len(x), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Due to having only an extra b':', we add 1 to the verbatim string length instead of 4 |
||
#[cfg(not(target_os = "redox"))] | ||
Verbatim(x) => 4 + os_str_len(x), | ||
VerbatimUNC(x, y) => { | ||
8 + os_str_len(x) + | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,10 @@ | |
|
||
pub use self::imp::*; | ||
|
||
#[cfg(target_os = "redox")] | ||
#[path = "redox/mod.rs"] | ||
mod imp; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As we have a lot of different code, we create a new target family and a new |
||
|
||
#[cfg(unix)] | ||
#[path = "unix/mod.rs"] | ||
mod imp; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
//! Global initialization and retreival of command line arguments. | ||
//! | ||
//! On some platforms these are stored during runtime startup, | ||
//! and on some they are retrieved from the system on demand. | ||
|
||
#![allow(dead_code)] // runtime init functions not used during testing | ||
|
||
use ffi::OsString; | ||
use marker::PhantomData; | ||
use vec; | ||
|
||
/// One-time global initialization. | ||
pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) } | ||
|
||
/// One-time global cleanup. | ||
pub unsafe fn cleanup() { imp::cleanup() } | ||
|
||
/// Returns the command line arguments | ||
pub fn args() -> Args { | ||
imp::args() | ||
} | ||
|
||
pub struct Args { | ||
iter: vec::IntoIter<OsString>, | ||
_dont_send_or_sync_me: PhantomData<*mut ()>, | ||
} | ||
|
||
impl Iterator for Args { | ||
type Item = OsString; | ||
fn next(&mut self) -> Option<OsString> { self.iter.next() } | ||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } | ||
} | ||
|
||
impl ExactSizeIterator for Args { | ||
fn len(&self) -> usize { self.iter.len() } | ||
} | ||
|
||
impl DoubleEndedIterator for Args { | ||
fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() } | ||
} | ||
|
||
mod imp { | ||
use os::unix::prelude::*; | ||
use mem; | ||
use ffi::OsString; | ||
use marker::PhantomData; | ||
use slice; | ||
use str; | ||
use super::Args; | ||
|
||
use sys_common::mutex::Mutex; | ||
|
||
static mut GLOBAL_ARGS_PTR: usize = 0; | ||
static LOCK: Mutex = Mutex::new(); | ||
|
||
pub unsafe fn init(argc: isize, argv: *const *const u8) { | ||
let mut args: Vec<Vec<u8>> = Vec::new(); | ||
for i in 0..argc { | ||
let len = *(argv.offset(i * 2)) as usize; | ||
let ptr = *(argv.offset(i * 2 + 1)); | ||
args.push(slice::from_raw_parts(ptr, len).to_vec()); | ||
} | ||
|
||
LOCK.lock(); | ||
let ptr = get_global_ptr(); | ||
assert!((*ptr).is_none()); | ||
(*ptr) = Some(box args); | ||
LOCK.unlock(); | ||
} | ||
|
||
pub unsafe fn cleanup() { | ||
LOCK.lock(); | ||
*get_global_ptr() = None; | ||
LOCK.unlock(); | ||
} | ||
|
||
pub fn args() -> Args { | ||
let bytes = clone().unwrap_or(Vec::new()); | ||
let v: Vec<OsString> = bytes.into_iter().map(|v| { | ||
OsStringExt::from_vec(v) | ||
}).collect(); | ||
Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData } | ||
} | ||
|
||
fn clone() -> Option<Vec<Vec<u8>>> { | ||
unsafe { | ||
LOCK.lock(); | ||
let ptr = get_global_ptr(); | ||
let ret = (*ptr).as_ref().map(|s| (**s).clone()); | ||
LOCK.unlock(); | ||
return ret | ||
} | ||
} | ||
|
||
fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> { | ||
unsafe { mem::transmute(&GLOBAL_ARGS_PTR) } | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use libc; | ||
use io; | ||
use sys_common::backtrace::output; | ||
|
||
#[inline(never)] | ||
pub fn write(w: &mut io::Write) -> io::Result<()> { | ||
output(w, 0, 0 as *mut libc::c_void, None) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use cell::UnsafeCell; | ||
use intrinsics::{atomic_cxchg, atomic_xadd, atomic_xchg}; | ||
use ptr; | ||
use time::Duration; | ||
|
||
use sys::mutex::{mutex_lock, mutex_unlock, Mutex}; | ||
use sys::syscall::{futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE}; | ||
|
||
pub struct Condvar { | ||
lock: UnsafeCell<*mut i32>, | ||
seq: UnsafeCell<i32> | ||
} | ||
|
||
impl Condvar { | ||
pub const fn new() -> Condvar { | ||
Condvar { | ||
lock: UnsafeCell::new(ptr::null_mut()), | ||
seq: UnsafeCell::new(0) | ||
} | ||
} | ||
|
||
#[inline] | ||
pub unsafe fn init(&self) { | ||
*self.lock.get() = ptr::null_mut(); | ||
*self.seq.get() = 0; | ||
} | ||
|
||
#[inline] | ||
pub fn notify_one(&self) { | ||
unsafe { | ||
let seq = self.seq.get(); | ||
|
||
atomic_xadd(seq, 1); | ||
|
||
let _ = futex(seq, FUTEX_WAKE, 1, 0, ptr::null_mut()); | ||
} | ||
} | ||
|
||
#[inline] | ||
pub fn notify_all(&self) { | ||
unsafe { | ||
let lock = self.lock.get(); | ||
let seq = self.seq.get(); | ||
|
||
if *lock == ptr::null_mut() { | ||
return; | ||
} | ||
|
||
atomic_xadd(seq, 1); | ||
|
||
let _ = futex(seq, FUTEX_REQUEUE, 1, ::usize::MAX, *lock); | ||
} | ||
} | ||
|
||
#[inline] | ||
pub fn wait(&self, mutex: &Mutex) { | ||
unsafe { | ||
let lock = self.lock.get(); | ||
let seq = self.seq.get(); | ||
|
||
if *lock != mutex.lock.get() { | ||
if *lock != ptr::null_mut() { | ||
panic!("Condvar used with more than one Mutex"); | ||
} | ||
|
||
atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize); | ||
} | ||
|
||
mutex_unlock(*lock); | ||
|
||
let _ = futex(seq, FUTEX_WAIT, *seq, 0, ptr::null_mut()); | ||
|
||
while atomic_xchg(*lock, 2) != 0 { | ||
let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut()); | ||
} | ||
|
||
mutex_lock(*lock); | ||
} | ||
} | ||
|
||
#[inline] | ||
pub fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { | ||
::sys_common::util::dumb_print(format_args!("condvar wait_timeout\n")); | ||
unimplemented!(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will be implemented shortly with additional flags to |
||
} | ||
|
||
#[inline] | ||
pub unsafe fn destroy(&self) { | ||
*self.lock.get() = ptr::null_mut(); | ||
*self.seq.get() = 0; | ||
} | ||
} | ||
|
||
unsafe impl Send for Condvar {} | ||
|
||
unsafe impl Sync for Condvar {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
pub mod os { | ||
pub const FAMILY: &'static str = "redox"; | ||
pub const OS: &'static str = "redox"; | ||
pub const DLL_PREFIX: &'static str = "lib"; | ||
pub const DLL_SUFFIX: &'static str = ".so"; | ||
pub const DLL_EXTENSION: &'static str = "so"; | ||
pub const EXE_SUFFIX: &'static str = ""; | ||
pub const EXE_EXTENSION: &'static str = ""; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
//! Unix-specific extension to the primitives in the `std::ffi` module | ||
|
||
#![stable(feature = "rust1", since = "1.0.0")] | ||
|
||
use ffi::{OsStr, OsString}; | ||
use mem; | ||
use sys::os_str::Buf; | ||
use sys_common::{FromInner, IntoInner, AsInner}; | ||
|
||
/// Unix-specific extensions to `OsString`. | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub trait OsStringExt { | ||
/// Creates an `OsString` from a byte vector. | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
fn from_vec(vec: Vec<u8>) -> Self; | ||
|
||
/// Yields the underlying byte vector of this `OsString`. | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
fn into_vec(self) -> Vec<u8>; | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl OsStringExt for OsString { | ||
fn from_vec(vec: Vec<u8>) -> OsString { | ||
FromInner::from_inner(Buf { inner: vec }) | ||
} | ||
fn into_vec(self) -> Vec<u8> { | ||
self.into_inner().inner | ||
} | ||
} | ||
|
||
/// Unix-specific extensions to `OsStr`. | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub trait OsStrExt { | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
fn from_bytes(slice: &[u8]) -> &Self; | ||
|
||
/// Gets the underlying byte view of the `OsStr` slice. | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
fn as_bytes(&self) -> &[u8]; | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl OsStrExt for OsStr { | ||
fn from_bytes(slice: &[u8]) -> &OsStr { | ||
unsafe { mem::transmute(slice) } | ||
} | ||
fn as_bytes(&self) -> &[u8] { | ||
&self.as_inner().inner | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redox has no
libc
function for abort, so using the intrinsic is required