Skip to content
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

Merged
merged 41 commits into from
Dec 15, 2016
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8b09e01
Add redox system
jackpot51 Oct 28, 2016
a5de9bb
Remove unsafe libc layer
jackpot51 Oct 28, 2016
68fd7ee
Can import unwind now
jackpot51 Oct 28, 2016
b1b35dd
Implement env, reentrant mutex, and partially implement scoped thread…
jackpot51 Oct 30, 2016
ea6f5aa
Implement rand and args, cleanup other modules
jackpot51 Oct 30, 2016
37bfef0
Implement thread
jackpot51 Oct 30, 2016
4edcddf
Implement TLS scoped keys, compiler builtins
jackpot51 Oct 30, 2016
c77979b
Fix for thread locals
jackpot51 Oct 31, 2016
123d08b
Merge branch 'master' of https://github.com/rust-lang/rust into redox
jackpot51 Oct 31, 2016
74dc845
Merge branch 'master' into redox
jackpot51 Nov 3, 2016
01e8378
Update to new sys requirements
jackpot51 Nov 3, 2016
ced32a0
Fix exec
jackpot51 Nov 10, 2016
a908509
Fixes for stdio and processes on Redox
jackpot51 Nov 11, 2016
79a8c27
Fix readdir
jackpot51 Nov 11, 2016
25e1a4a
Use target_os = redox for cfg
jackpot51 Nov 11, 2016
0bb9a95
Merge branch 'master' into redox
jackpot51 Nov 11, 2016
a0b5dfe
Add fcntl
jackpot51 Nov 14, 2016
18bf054
Fix redox prefix handling
jackpot51 Nov 14, 2016
de68ace
Add current_exe support
jackpot51 Nov 15, 2016
73f24d4
Simple implementation of read2
jackpot51 Nov 15, 2016
2e5c821
Add set_perm
jackpot51 Nov 15, 2016
267bc54
Use chmod instead of fcntl to change file perms
jackpot51 Nov 16, 2016
f01add1
Add signal support, better exec error handling
jackpot51 Nov 17, 2016
2556400
Replace setuid, setgid with setreuid, setregid
jackpot51 Nov 17, 2016
ae2029f
Merge branch 'master' into redox
jackpot51 Nov 20, 2016
b3c91df
Merge branch 'master' into redox
jackpot51 Nov 23, 2016
4a0bc71
Add File set_permissions
jackpot51 Nov 23, 2016
6733074
Allow setting nonblock on sockets
jackpot51 Nov 23, 2016
3a1bb2b
Use O_DIRECTORY
jackpot51 Nov 26, 2016
d73d32f
Fix canonicalize
jackpot51 Nov 26, 2016
746222f
Switch to using syscall crate directly - without import
jackpot51 Nov 29, 2016
2ec2132
Switch to using Prefix::Verbatim
jackpot51 Nov 29, 2016
1d0bba8
Move stdout/err flush into sys
jackpot51 Nov 29, 2016
6378c77
Remove file path from std::fs::File
jackpot51 Nov 29, 2016
e683933
Commit to fix make tidy
jackpot51 Nov 29, 2016
7294422
Cleanup env
jackpot51 Dec 1, 2016
056ebcc
Rollback prefix
jackpot51 Dec 12, 2016
c61baa0
Fix accidental removal of import
jackpot51 Dec 12, 2016
7e7775c
Merge branch 'master' into redox
jackpot51 Dec 12, 2016
daaa231
Fix tidy checks
jackpot51 Dec 12, 2016
3e15dc1
Merge branch 'master' into redox
jackpot51 Dec 14, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libpanic_abort/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#![panic_runtime]
#![feature(panic_runtime)]
#![cfg_attr(unix, feature(libc))]
#![cfg_attr(windows, feature(core_intrinsics))]
#![cfg_attr(any(target_os = "redox", windows), feature(core_intrinsics))]
Copy link
Contributor Author

@jackpot51 jackpot51 Nov 11, 2016

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


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

#[cfg(windows)]
#[cfg(any(target_os = "redox", windows))]
unsafe fn abort() -> ! {
core::intrinsics::abort();
}
Expand Down
1 change: 1 addition & 0 deletions src/libpanic_unwind/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ mod imp;

// i686-pc-windows-gnu and all others
#[cfg(any(all(unix, not(target_os = "emscripten")),
target_os = "redox",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redox could potentially use libunwind for backtraces. Right now, panic_abort is preferred.

all(windows, target_arch = "x86", target_env = "gnu")))]
#[path = "gcc.rs"]
mod imp;
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Redox, the stdio needs to be flushed when in raw mode. This perhaps could be removed by adjusting programs that enter raw mode

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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> {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/os/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#![stable(feature = "os", since = "1.0.0")]
#![allow(missing_docs, bad_style)]

#[cfg(unix)]
#[cfg(any(target_os = "redox", unix))]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also export os::unix items that we are compatible with - perhaps we should do os::redox for these items, even if they are identical to the os::unix ones?

#[stable(feature = "rust1", since = "1.0.0")]
pub use sys::ext as unix;
#[cfg(windows)]
Expand Down
7 changes: 6 additions & 1 deletion src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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) +
Expand Down
4 changes: 4 additions & 0 deletions src/libstd/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

pub use self::imp::*;

#[cfg(target_os = "redox")]
#[path = "redox/mod.rs"]
mod imp;
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 sys::redox module


#[cfg(unix)]
#[path = "unix/mod.rs"]
mod imp;
Expand Down
109 changes: 109 additions & 0 deletions src/libstd/sys/redox/args.rs
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) }
}

}
18 changes: 18 additions & 0 deletions src/libstd/sys/redox/backtrace.rs
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)
}
106 changes: 106 additions & 0 deletions src/libstd/sys/redox/condvar.rs
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!();
Copy link
Contributor Author

@jackpot51 jackpot51 Nov 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be implemented shortly with additional flags to futex

}

#[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 {}
19 changes: 19 additions & 0 deletions src/libstd/sys/redox/env.rs
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 = "";
}
61 changes: 61 additions & 0 deletions src/libstd/sys/redox/ext/ffi.rs
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
}
}
Loading