Skip to content

Commit cfa668f

Browse files
committed
Auto merge of #37702 - redox-os:redox, r=brson
Redox Support Preview # Important - This is only a preview of a working `sys::redox`. Compiling the Redox default distribution with this `libstd` results in a fully functioning distribution. As such, all further changes would be cosmetic or implementing features that have not been used by the default distribution (of which there are only a small number). I do not expect this to be merged, but would like to discuss how it may be improved and get feedback. There are a few `unimplemented!()` - `cloexec` for example. I have documented them below. These would be resolved before desiring a merge. There are also issues with how the Redox syscall library is called - currently I am using a re-export in `libc` but that probably would not be desired.
2 parents 7ad7232 + 3e15dc1 commit cfa668f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4252
-8
lines changed

src/libpanic_abort/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#![panic_runtime]
2929
#![feature(panic_runtime)]
3030
#![cfg_attr(unix, feature(libc))]
31-
#![cfg_attr(windows, feature(core_intrinsics))]
31+
#![cfg_attr(any(target_os = "redox", windows), feature(core_intrinsics))]
3232

3333
// Rust's "try" function, but if we're aborting on panics we just call the
3434
// function as there's nothing else we need to do here.
@@ -61,7 +61,7 @@ pub unsafe extern fn __rust_start_panic(_data: usize, _vtable: usize) -> u32 {
6161
libc::abort();
6262
}
6363

64-
#[cfg(windows)]
64+
#[cfg(any(target_os = "redox", windows))]
6565
unsafe fn abort() -> ! {
6666
core::intrinsics::abort();
6767
}

src/libpanic_unwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ mod imp;
6969

7070
// i686-pc-windows-gnu and all others
7171
#[cfg(any(all(unix, not(target_os = "emscripten")),
72+
target_os = "redox",
7273
all(windows, target_arch = "x86", target_env = "gnu")))]
7374
#[path = "gcc.rs"]
7475
mod imp;

src/libstd/io/stdio.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ impl Read for StdinRaw {
8181
}
8282
impl Write for StdoutRaw {
8383
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
84-
fn flush(&mut self) -> io::Result<()> { Ok(()) }
84+
fn flush(&mut self) -> io::Result<()> { self.0.flush() }
8585
}
8686
impl Write for StderrRaw {
8787
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
88-
fn flush(&mut self) -> io::Result<()> { Ok(()) }
88+
fn flush(&mut self) -> io::Result<()> { self.0.flush() }
8989
}
9090

9191
enum Maybe<T> {

src/libstd/os/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#![stable(feature = "os", since = "1.0.0")]
1414
#![allow(missing_docs, bad_style)]
1515

16-
#[cfg(unix)]
16+
#[cfg(any(target_os = "redox", unix))]
1717
#[stable(feature = "rust1", since = "1.0.0")]
1818
pub use sys::ext as unix;
1919
#[cfg(windows)]

src/libstd/sys/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
3333
pub use self::imp::*;
3434

35+
#[cfg(target_os = "redox")]
36+
#[path = "redox/mod.rs"]
37+
mod imp;
38+
3539
#[cfg(unix)]
3640
#[path = "unix/mod.rs"]
3741
mod imp;

src/libstd/sys/redox/args.rs

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Global initialization and retreival of command line arguments.
12+
//!
13+
//! On some platforms these are stored during runtime startup,
14+
//! and on some they are retrieved from the system on demand.
15+
16+
#![allow(dead_code)] // runtime init functions not used during testing
17+
18+
use ffi::OsString;
19+
use marker::PhantomData;
20+
use vec;
21+
22+
/// One-time global initialization.
23+
pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) }
24+
25+
/// One-time global cleanup.
26+
pub unsafe fn cleanup() { imp::cleanup() }
27+
28+
/// Returns the command line arguments
29+
pub fn args() -> Args {
30+
imp::args()
31+
}
32+
33+
pub struct Args {
34+
iter: vec::IntoIter<OsString>,
35+
_dont_send_or_sync_me: PhantomData<*mut ()>,
36+
}
37+
38+
impl Iterator for Args {
39+
type Item = OsString;
40+
fn next(&mut self) -> Option<OsString> { self.iter.next() }
41+
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
42+
}
43+
44+
impl ExactSizeIterator for Args {
45+
fn len(&self) -> usize { self.iter.len() }
46+
}
47+
48+
impl DoubleEndedIterator for Args {
49+
fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
50+
}
51+
52+
mod imp {
53+
use os::unix::prelude::*;
54+
use mem;
55+
use ffi::OsString;
56+
use marker::PhantomData;
57+
use slice;
58+
use str;
59+
use super::Args;
60+
61+
use sys_common::mutex::Mutex;
62+
63+
static mut GLOBAL_ARGS_PTR: usize = 0;
64+
static LOCK: Mutex = Mutex::new();
65+
66+
pub unsafe fn init(argc: isize, argv: *const *const u8) {
67+
let mut args: Vec<Vec<u8>> = Vec::new();
68+
for i in 0..argc {
69+
let len = *(argv.offset(i * 2)) as usize;
70+
let ptr = *(argv.offset(i * 2 + 1));
71+
args.push(slice::from_raw_parts(ptr, len).to_vec());
72+
}
73+
74+
LOCK.lock();
75+
let ptr = get_global_ptr();
76+
assert!((*ptr).is_none());
77+
(*ptr) = Some(box args);
78+
LOCK.unlock();
79+
}
80+
81+
pub unsafe fn cleanup() {
82+
LOCK.lock();
83+
*get_global_ptr() = None;
84+
LOCK.unlock();
85+
}
86+
87+
pub fn args() -> Args {
88+
let bytes = clone().unwrap_or(Vec::new());
89+
let v: Vec<OsString> = bytes.into_iter().map(|v| {
90+
OsStringExt::from_vec(v)
91+
}).collect();
92+
Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData }
93+
}
94+
95+
fn clone() -> Option<Vec<Vec<u8>>> {
96+
unsafe {
97+
LOCK.lock();
98+
let ptr = get_global_ptr();
99+
let ret = (*ptr).as_ref().map(|s| (**s).clone());
100+
LOCK.unlock();
101+
return ret
102+
}
103+
}
104+
105+
fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
106+
unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
107+
}
108+
109+
}

src/libstd/sys/redox/backtrace.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use libc;
12+
use io;
13+
use sys_common::backtrace::output;
14+
15+
#[inline(never)]
16+
pub fn write(w: &mut io::Write) -> io::Result<()> {
17+
output(w, 0, 0 as *mut libc::c_void, None)
18+
}

src/libstd/sys/redox/condvar.rs

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use cell::UnsafeCell;
12+
use intrinsics::{atomic_cxchg, atomic_xadd, atomic_xchg};
13+
use ptr;
14+
use time::Duration;
15+
16+
use sys::mutex::{mutex_lock, mutex_unlock, Mutex};
17+
use sys::syscall::{futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
18+
19+
pub struct Condvar {
20+
lock: UnsafeCell<*mut i32>,
21+
seq: UnsafeCell<i32>
22+
}
23+
24+
impl Condvar {
25+
pub const fn new() -> Condvar {
26+
Condvar {
27+
lock: UnsafeCell::new(ptr::null_mut()),
28+
seq: UnsafeCell::new(0)
29+
}
30+
}
31+
32+
#[inline]
33+
pub unsafe fn init(&self) {
34+
*self.lock.get() = ptr::null_mut();
35+
*self.seq.get() = 0;
36+
}
37+
38+
#[inline]
39+
pub fn notify_one(&self) {
40+
unsafe {
41+
let seq = self.seq.get();
42+
43+
atomic_xadd(seq, 1);
44+
45+
let _ = futex(seq, FUTEX_WAKE, 1, 0, ptr::null_mut());
46+
}
47+
}
48+
49+
#[inline]
50+
pub fn notify_all(&self) {
51+
unsafe {
52+
let lock = self.lock.get();
53+
let seq = self.seq.get();
54+
55+
if *lock == ptr::null_mut() {
56+
return;
57+
}
58+
59+
atomic_xadd(seq, 1);
60+
61+
let _ = futex(seq, FUTEX_REQUEUE, 1, ::usize::MAX, *lock);
62+
}
63+
}
64+
65+
#[inline]
66+
pub fn wait(&self, mutex: &Mutex) {
67+
unsafe {
68+
let lock = self.lock.get();
69+
let seq = self.seq.get();
70+
71+
if *lock != mutex.lock.get() {
72+
if *lock != ptr::null_mut() {
73+
panic!("Condvar used with more than one Mutex");
74+
}
75+
76+
atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize);
77+
}
78+
79+
mutex_unlock(*lock);
80+
81+
let _ = futex(seq, FUTEX_WAIT, *seq, 0, ptr::null_mut());
82+
83+
while atomic_xchg(*lock, 2) != 0 {
84+
let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut());
85+
}
86+
87+
mutex_lock(*lock);
88+
}
89+
}
90+
91+
#[inline]
92+
pub fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
93+
::sys_common::util::dumb_print(format_args!("condvar wait_timeout\n"));
94+
unimplemented!();
95+
}
96+
97+
#[inline]
98+
pub unsafe fn destroy(&self) {
99+
*self.lock.get() = ptr::null_mut();
100+
*self.seq.get() = 0;
101+
}
102+
}
103+
104+
unsafe impl Send for Condvar {}
105+
106+
unsafe impl Sync for Condvar {}

src/libstd/sys/redox/env.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub mod os {
12+
pub const FAMILY: &'static str = "redox";
13+
pub const OS: &'static str = "redox";
14+
pub const DLL_PREFIX: &'static str = "lib";
15+
pub const DLL_SUFFIX: &'static str = ".so";
16+
pub const DLL_EXTENSION: &'static str = "so";
17+
pub const EXE_SUFFIX: &'static str = "";
18+
pub const EXE_EXTENSION: &'static str = "";
19+
}

src/libstd/sys/redox/ext/ffi.rs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Unix-specific extension to the primitives in the `std::ffi` module
12+
13+
#![stable(feature = "rust1", since = "1.0.0")]
14+
15+
use ffi::{OsStr, OsString};
16+
use mem;
17+
use sys::os_str::Buf;
18+
use sys_common::{FromInner, IntoInner, AsInner};
19+
20+
/// Unix-specific extensions to `OsString`.
21+
#[stable(feature = "rust1", since = "1.0.0")]
22+
pub trait OsStringExt {
23+
/// Creates an `OsString` from a byte vector.
24+
#[stable(feature = "rust1", since = "1.0.0")]
25+
fn from_vec(vec: Vec<u8>) -> Self;
26+
27+
/// Yields the underlying byte vector of this `OsString`.
28+
#[stable(feature = "rust1", since = "1.0.0")]
29+
fn into_vec(self) -> Vec<u8>;
30+
}
31+
32+
#[stable(feature = "rust1", since = "1.0.0")]
33+
impl OsStringExt for OsString {
34+
fn from_vec(vec: Vec<u8>) -> OsString {
35+
FromInner::from_inner(Buf { inner: vec })
36+
}
37+
fn into_vec(self) -> Vec<u8> {
38+
self.into_inner().inner
39+
}
40+
}
41+
42+
/// Unix-specific extensions to `OsStr`.
43+
#[stable(feature = "rust1", since = "1.0.0")]
44+
pub trait OsStrExt {
45+
#[stable(feature = "rust1", since = "1.0.0")]
46+
fn from_bytes(slice: &[u8]) -> &Self;
47+
48+
/// Gets the underlying byte view of the `OsStr` slice.
49+
#[stable(feature = "rust1", since = "1.0.0")]
50+
fn as_bytes(&self) -> &[u8];
51+
}
52+
53+
#[stable(feature = "rust1", since = "1.0.0")]
54+
impl OsStrExt for OsStr {
55+
fn from_bytes(slice: &[u8]) -> &OsStr {
56+
unsafe { mem::transmute(slice) }
57+
}
58+
fn as_bytes(&self) -> &[u8] {
59+
&self.as_inner().inner
60+
}
61+
}

0 commit comments

Comments
 (0)