From 2cf0a4ad4690c587d755dc6e5383779dddb9b178 Mon Sep 17 00:00:00 2001 From: Sebastian Humenda Date: Thu, 17 Aug 2017 13:23:00 +0200 Subject: [PATCH 1/6] Match c_char definitions and enable signal reset for L4Re * Match definition of c_char in os/raw.rs with the libc definition Due to historic reasons, os/raw.rs redefines types for c_char from libc, but these didn't match. Now they do :). * Enable signal reset on exec for L4Re L4Re has full signal emulation and hence it needs to reset the signal set of the child with sigemptyset. However, gid and uid should *not* be set. --- src/libstd/os/raw.rs | 2 ++ src/libstd/sys/unix/ext/mod.rs | 1 + src/libstd/sys/unix/mod.rs | 1 + src/libstd/sys/unix/process/process_unix.rs | 28 +++++++++++---------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw.rs index fe0427d4e5f9..95439640f7cc 100644 --- a/src/libstd/os/raw.rs +++ b/src/libstd/os/raw.rs @@ -21,6 +21,7 @@ target_arch = "s390x")), all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")), + all(target_os = "l4re", target_arch = "x86_64"), all(target_os = "fuchsia", target_arch = "aarch64")))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64", @@ -30,6 +31,7 @@ target_arch = "s390x")), all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")), + all(target_os = "l4re", target_arch = "x86_64"), all(target_os = "fuchsia", target_arch = "aarch64"))))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs index 98bc90dd4e13..63b81c4f4c27 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -36,6 +36,7 @@ pub mod process; pub mod raw; pub mod thread; +#[cfg(not(target_os = "l4re"))] pub mod net; /// A prelude for conveniently writing platform-specific code. diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 4393aedf162a..efa149646048 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -44,6 +44,7 @@ pub mod fs; pub mod memchr; pub mod mutex; +#[cfg(not(target_os = "l4re"))] pub mod net; pub mod os; pub mod os_str; diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index ae24021fb6c3..870db8200273 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -160,20 +160,22 @@ macro_rules! t { t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); } - if let Some(u) = self.get_gid() { - t!(cvt(libc::setgid(u as gid_t))); - } - if let Some(u) = self.get_uid() { - // When dropping privileges from root, the `setgroups` call - // will remove any extraneous groups. If we don't call this, - // then even though our uid has dropped, we may still have - // groups that enable us to do super-user things. This will - // fail if we aren't root, so don't bother checking the - // return value, this is just done as an optimistic - // privilege dropping function. - let _ = libc::setgroups(0, ptr::null()); + if cfg!(not(any(target_os = "l4re"))) { + if let Some(u) = self.get_gid() { + t!(cvt(libc::setgid(u as gid_t))); + } + if let Some(u) = self.get_uid() { + // When dropping privileges from root, the `setgroups` call + // will remove any extraneous groups. If we don't call this, + // then even though our uid has dropped, we may still have + // groups that enable us to do super-user things. This will + // fail if we aren't root, so don't bother checking the + // return value, this is just done as an optimistic + // privilege dropping function. + let _ = libc::setgroups(0, ptr::null()); - t!(cvt(libc::setuid(u as uid_t))); + t!(cvt(libc::setuid(u as uid_t))); + } } if let Some(ref cwd) = *self.get_cwd() { t!(cvt(libc::chdir(cwd.as_ptr()))); From 9bbc6dbde3e3807362680a355098102bb38a67fe Mon Sep 17 00:00:00 2001 From: Tobias Schaffner Date: Fri, 18 Aug 2017 11:50:20 +0200 Subject: [PATCH 2/6] Add modifications needed for L4re in libstd This commit adds the needed modifications to compile the std crate for the L4 Runtime environment (L4Re). A target for the L4Re was introduced in commit: c151220a84e40b65e45308cc0f3bbea4466d3acf In many aspects implementations for linux also apply for the L4Re microkernel. Two uncommon characteristics had to be resolved: * L4Re has no network funktionality * L4Re has a maximum stacksize of 1Mb for threads Co-authored-by: Sebastian Humenda --- src/libstd/lib.rs | 1 + src/libstd/os/mod.rs | 2 +- src/libstd/sys/unix/args.rs | 1 + src/libstd/sys/unix/condvar.rs | 10 ++++++++-- src/libstd/sys/unix/env.rs | 11 +++++++++++ src/libstd/sys/unix/fd.rs | 2 ++ src/libstd/sys/unix/fs.rs | 6 +++++- src/libstd/sys/unix/mod.rs | 1 + src/libstd/sys/unix/os.rs | 9 ++++++--- src/libstd/sys/unix/thread.rs | 10 ++++++++-- src/libstd/sys_common/mod.rs | 2 +- 11 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 433499a90a40..115adf6e3f9c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -466,6 +466,7 @@ pub mod ffi; pub mod fs; pub mod io; +#[cfg(not(target_os = "l4re"))] pub mod net; pub mod num; pub mod os; diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 72eed549f62a..b460bd90f173 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -27,7 +27,7 @@ #[stable(feature = "rust1", since = "1.0.0")] pub use sys::windows_ext as windows; -#[cfg(any(dox, target_os = "linux"))] +#[cfg(any(dox, target_os = "linux", target_os = "l4re"))] #[doc(cfg(target_os = "linux"))] pub mod linux; diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 810d2d40c05f..72169773df59 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -65,6 +65,7 @@ fn next_back(&mut self) -> Option { self.iter.next_back() } target_os = "solaris", target_os = "emscripten", target_os = "haiku", + target_os = "l4re", target_os = "fuchsia"))] mod imp { use os::unix::prelude::*; diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index b9ea573b323d..89a44b976578 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -38,10 +38,16 @@ pub const fn new() -> Condvar { Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) } } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))] + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "l4re", + target_os = "android"))] pub unsafe fn init(&mut self) {} - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))] + #[cfg(not(any(target_os = "macos", + target_os = "ios", + target_os = "l4re", + target_os = "android")))] pub unsafe fn init(&mut self) { use mem; let mut attr: libc::pthread_condattr_t = mem::uninitialized(); diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index eff3a8c2a34a..3d9a06bedd57 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -182,3 +182,14 @@ pub mod os { pub const EXE_SUFFIX: &'static str = ""; pub const EXE_EXTENSION: &'static str = ""; } + +#[cfg(target_os = "l4re")] +pub mod os { + pub const FAMILY: &'static str = "unix"; + pub const OS: &'static str = "l4re"; + 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 = ""; +} diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index f50b093acc84..5dafc3251e75 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -144,6 +144,7 @@ unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64) target_os = "solaris", target_os = "emscripten", target_os = "fuchsia", + target_os = "l4re", target_os = "haiku")))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { @@ -155,6 +156,7 @@ pub fn set_cloexec(&self) -> io::Result<()> { target_os = "solaris", target_os = "emscripten", target_os = "fuchsia", + target_os = "l4re", target_os = "haiku"))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index f94af4913324..13112fc1fa59 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -23,19 +23,21 @@ use sys::{cvt, cvt_r}; use sys_common::{AsInner, FromInner}; -#[cfg(any(target_os = "linux", target_os = "emscripten"))] +#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))] use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64}; #[cfg(target_os = "android")] use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, lseek64, dirent as dirent64, open as open64}; #[cfg(not(any(target_os = "linux", target_os = "emscripten", + target_os = "l4re", target_os = "android")))] use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off_t as off64_t, ftruncate as ftruncate64, lseek as lseek64, dirent as dirent64, open as open64}; #[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "solaris", + target_os = "l4re", target_os = "fuchsia")))] use libc::{readdir_r as readdir64_r}; @@ -316,6 +318,7 @@ pub fn file_type(&self) -> io::Result { target_os = "android", target_os = "solaris", target_os = "haiku", + target_os = "l4re", target_os = "fuchsia"))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 @@ -346,6 +349,7 @@ fn name_bytes(&self) -> &[u8] { #[cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", + target_os = "l4re", target_os = "haiku"))] fn name_bytes(&self) -> &[u8] { unsafe { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index efa149646048..697e9b962b1c 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -28,6 +28,7 @@ #[cfg(all(not(dox), target_os = "solaris"))] pub use os::solaris as platform; #[cfg(all(not(dox), target_os = "emscripten"))] pub use os::emscripten as platform; #[cfg(all(not(dox), target_os = "fuchsia"))] pub use os::fuchsia as platform; +#[cfg(all(not(dox), target_os = "l4re"))] pub use os::linux as platform; #[macro_use] pub mod weak; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 8e41fd009be6..5ef98d247105 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -38,7 +38,10 @@ extern { #[cfg(not(target_os = "dragonfly"))] - #[cfg_attr(any(target_os = "linux", target_os = "emscripten", target_os = "fuchsia"), + #[cfg_attr(any(target_os = "linux", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "l4re"), link_name = "__errno_location")] #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", @@ -346,10 +349,10 @@ fn _get_next_image_info(team_id: i32, cookie: *mut i32, } } -#[cfg(target_os = "fuchsia")] +#[cfg(any(target_os = "fuchsia", target_os = "l4re"))] pub fn current_exe() -> io::Result { use io::ErrorKind; - Err(io::Error::new(ErrorKind::Other, "Not yet implemented on fuchsia")) + Err(io::Error::new(ErrorKind::Other, "Not yet implemented!")) } pub struct Env { diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 40f1d6a6db15..5e2610736a8d 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -52,6 +52,11 @@ pub unsafe fn new<'a>(stack: usize, p: Box) assert_eq!(libc::pthread_attr_init(&mut attr), 0); let stack_size = cmp::max(stack, min_stack_size(&attr)); + + // L4Re only supports a maximum of 1Mb per default. + #[cfg(target_os = "l4re")] + let stack_size = cmp::min(stack_size, 1024 * 1024); + match pthread_attr_setstacksize(&mut attr, stack_size) { 0 => {} @@ -131,6 +136,7 @@ pub fn set_name(name: &CStr) { #[cfg(any(target_env = "newlib", target_os = "solaris", target_os = "haiku", + target_os = "l4re", target_os = "emscripten"))] pub fn set_name(_name: &CStr) { // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name. @@ -226,7 +232,7 @@ unsafe fn get_stack_start() -> Option<*mut libc::c_void> { } #[cfg(any(target_os = "android", target_os = "freebsd", - target_os = "linux", target_os = "netbsd"))] + target_os = "linux", target_os = "netbsd", target_os = "l4re"))] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let mut ret = None; let mut attr: libc::pthread_attr_t = ::mem::zeroed(); @@ -328,7 +334,7 @@ pub unsafe fn current() -> Option { } #[cfg(any(target_os = "android", target_os = "freebsd", - target_os = "linux", target_os = "netbsd"))] + target_os = "linux", target_os = "netbsd", target_os = "l4re"))] pub unsafe fn current() -> Option { let mut ret = None; let mut attr: libc::pthread_attr_t = ::mem::zeroed(); diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index ccd4b91a7b73..ae8d280d5763 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -47,7 +47,7 @@ #[cfg(target_os = "redox")] pub use sys::net; -#[cfg(not(target_os = "redox"))] +#[cfg(not(any(target_os = "redox", target_os = "l4re")))] pub mod net; #[cfg(feature = "backtrace")] From 0b77464d2234231e13d03acd1d580ab2e3369d64 Mon Sep 17 00:00:00 2001 From: Sebastian Humenda Date: Wed, 6 Sep 2017 16:01:51 +0200 Subject: [PATCH 3/6] Re-enable networking module fo rL4Re As suggested in the discussion of PR #43972, std should provide a uniform API to all platforms. Since there's no networking on L4Re, this now is a module in `sys::net` providing types and functions/methods returning an error for each action. --- src/libstd/lib.rs | 1 - src/libstd/sys/unix/ext/mod.rs | 1 - src/libstd/sys/unix/l4re.rs | 441 +++++++++++++++++++++++++++++++++ src/libstd/sys/unix/mod.rs | 4 + src/libstd/sys_common/mod.rs | 2 +- src/libstd/sys_common/net.rs | 8 +- 6 files changed, 450 insertions(+), 7 deletions(-) create mode 100644 src/libstd/sys/unix/l4re.rs diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 115adf6e3f9c..433499a90a40 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -466,7 +466,6 @@ pub mod ffi; pub mod fs; pub mod io; -#[cfg(not(target_os = "l4re"))] pub mod net; pub mod num; pub mod os; diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs index 63b81c4f4c27..98bc90dd4e13 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -36,7 +36,6 @@ pub mod process; pub mod raw; pub mod thread; -#[cfg(not(target_os = "l4re"))] pub mod net; /// A prelude for conveniently writing platform-specific code. diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs new file mode 100644 index 000000000000..e07c864a6cbd --- /dev/null +++ b/src/libstd/sys/unix/l4re.rs @@ -0,0 +1,441 @@ +// Copyright 2016-2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! unimpl { + () => (return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));) +} + +pub mod net { + #![allow(warnings)] + use fmt; + use io; + use libc; + use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr}; + use sys_common::{AsInner, FromInner, IntoInner}; + use sys::fd::FileDesc; + use time::Duration; + + + pub extern crate libc as netc; + + pub struct Socket(FileDesc); + impl Socket { + pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result { + unimpl!(); + } + + pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result { + unimpl!(); + } + + pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> { + unimpl!(); + } + + pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> { + unimpl!(); + } + + pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t) + -> io::Result { + unimpl!(); + } + + pub fn duplicate(&self) -> io::Result { + unimpl!(); + } + + pub fn read(&self, _: &mut [u8]) -> io::Result { + unimpl!(); + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + unimpl!(); + } + + pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + unimpl!(); + } + + pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + unimpl!(); + } + + pub fn write(&self, _: &[u8]) -> io::Result { + unimpl!(); + } + + pub fn set_timeout(&self, _: Option, _: libc::c_int) -> io::Result<()> { + unimpl!(); + } + + pub fn timeout(&self, _: libc::c_int) -> io::Result> { + unimpl!(); + } + + pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { + unimpl!(); + } + + pub fn set_nodelay(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn nodelay(&self) -> io::Result { + unimpl!(); + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn take_error(&self) -> io::Result> { + unimpl!(); + } + } + + impl AsInner for Socket { + fn as_inner(&self) -> &libc::c_int { self.0.as_inner() } + } + + impl FromInner for Socket { + fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) } + } + + impl IntoInner for Socket { + fn into_inner(self) -> libc::c_int { self.0.into_raw() } + } + + pub struct TcpStream { + inner: Socket, + } + + impl TcpStream { + pub fn connect(_: &SocketAddr) -> io::Result { + unimpl!(); + } + + pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { + unimpl!(); + } + + pub fn socket(&self) -> &Socket { &self.inner } + + pub fn into_socket(self) -> Socket { self.inner } + + pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { + unimpl!(); + } + + pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { + unimpl!(); + } + + pub fn read_timeout(&self) -> io::Result> { + unimpl!(); + } + + pub fn write_timeout(&self) -> io::Result> { + unimpl!(); + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + unimpl!(); + } + + pub fn read(&self, _: &mut [u8]) -> io::Result { + unimpl!(); + } + + pub fn write(&self, _: &[u8]) -> io::Result { + unimpl!(); + } + + pub fn peer_addr(&self) -> io::Result { + unimpl!(); + } + + pub fn socket_addr(&self) -> io::Result { + unimpl!(); + } + + pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { + unimpl!(); + } + + pub fn duplicate(&self) -> io::Result { + unimpl!(); + } + + pub fn set_nodelay(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn nodelay(&self) -> io::Result { + unimpl!(); + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + unimpl!(); + } + + pub fn ttl(&self) -> io::Result { + unimpl!(); + } + + pub fn take_error(&self) -> io::Result> { + unimpl!(); + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + } + + impl FromInner for TcpStream { + fn from_inner(socket: Socket) -> TcpStream { + TcpStream { inner: socket } + } + } + + impl fmt::Debug for TcpStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "No networking support available on L4Re") + } + } + + pub struct TcpListener { + inner: Socket, + } + + impl TcpListener { + pub fn bind(_: &SocketAddr) -> io::Result { + unimpl!(); + } + + pub fn socket(&self) -> &Socket { &self.inner } + + pub fn into_socket(self) -> Socket { self.inner } + + pub fn socket_addr(&self) -> io::Result { + unimpl!(); + } + + pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { + unimpl!(); + } + + pub fn duplicate(&self) -> io::Result { + unimpl!(); + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + unimpl!(); + } + + pub fn ttl(&self) -> io::Result { + unimpl!(); + } + + pub fn set_only_v6(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn only_v6(&self) -> io::Result { + unimpl!(); + } + + pub fn take_error(&self) -> io::Result> { + unimpl!(); + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + } + + impl FromInner for TcpListener { + fn from_inner(socket: Socket) -> TcpListener { + TcpListener { inner: socket } + } + } + + impl fmt::Debug for TcpListener { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "No networking support available on L4Re.") + } + } + + pub struct UdpSocket { + inner: Socket, + } + + impl UdpSocket { + pub fn bind(_: &SocketAddr) -> io::Result { + unimpl!(); + } + + pub fn socket(&self) -> &Socket { &self.inner } + + pub fn into_socket(self) -> Socket { self.inner } + + pub fn socket_addr(&self) -> io::Result { + unimpl!(); + } + + pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + unimpl!(); + } + + pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + unimpl!(); + } + + pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result { + unimpl!(); + } + + pub fn duplicate(&self) -> io::Result { + unimpl!(); + } + + pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { + unimpl!(); + } + + pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { + unimpl!(); + } + + pub fn read_timeout(&self) -> io::Result> { + unimpl!(); + } + + pub fn write_timeout(&self) -> io::Result> { + unimpl!(); + } + + pub fn set_broadcast(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn broadcast(&self) -> io::Result { + unimpl!(); + } + + pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn multicast_loop_v4(&self) -> io::Result { + unimpl!(); + } + + pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { + unimpl!(); + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + unimpl!(); + } + + pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn multicast_loop_v6(&self) -> io::Result { + unimpl!(); + } + + pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) + -> io::Result<()> { + unimpl!(); + } + + pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) + -> io::Result<()> { + unimpl!(); + } + + pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) + -> io::Result<()> { + unimpl!(); + } + + pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) + -> io::Result<()> { + unimpl!(); + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + unimpl!(); + } + + pub fn ttl(&self) -> io::Result { + unimpl!(); + } + + pub fn take_error(&self) -> io::Result> { + unimpl!(); + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + unimpl!(); + } + + pub fn recv(&self, _: &mut [u8]) -> io::Result { + unimpl!(); + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + unimpl!(); + } + + pub fn send(&self, _: &[u8]) -> io::Result { + unimpl!(); + } + + pub fn connect(&self, _: &SocketAddr) -> io::Result<()> { + unimpl!(); + } + } + + impl FromInner for UdpSocket { + fn from_inner(socket: Socket) -> UdpSocket { + UdpSocket { inner: socket } + } + } + + impl fmt::Debug for UdpSocket { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "No networking support on L4Re available.") + } + } + + pub struct LookupHost { + original: *mut libc::addrinfo, + cur: *mut libc::addrinfo, + } + + impl Iterator for LookupHost { + type Item = SocketAddr; + fn next(&mut self) -> Option { + None + } + } + + unsafe impl Sync for LookupHost {} + unsafe impl Send for LookupHost {} + + pub fn lookup_host(_: &str) -> io::Result { + unimpl!(); + } +} + diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 697e9b962b1c..1b3f1000b77b 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -47,6 +47,10 @@ pub mod mutex; #[cfg(not(target_os = "l4re"))] pub mod net; +#[cfg(target_os = "l4re")] +mod l4re; +#[cfg(target_os = "l4re")] +pub use self::l4re::net; pub mod os; pub mod os_str; pub mod path; diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index ae8d280d5763..97058372e4c8 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -44,7 +44,7 @@ pub mod util; pub mod wtf8; -#[cfg(target_os = "redox")] +#[cfg(any(target_os = "redox", target_os = "l4re"))] pub use sys::net; #[cfg(not(any(target_os = "redox", target_os = "l4re")))] diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 1ca39ff9d4a1..19dc841b9b50 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -24,22 +24,22 @@ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd", - target_os = "solaris", target_os = "haiku"))] + target_os = "solaris", target_os = "haiku", target_os = "l4re"))] use sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd", - target_os = "solaris", target_os = "haiku")))] + target_os = "solaris", target_os = "haiku", target_os = "l4re")))] use sys::net::netc::IPV6_ADD_MEMBERSHIP; #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd", - target_os = "solaris", target_os = "haiku"))] + target_os = "solaris", target_os = "haiku", target_os = "l4re"))] use sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd", - target_os = "solaris", target_os = "haiku")))] + target_os = "solaris", target_os = "haiku", target_os = "l4re")))] use sys::net::netc::IPV6_DROP_MEMBERSHIP; #[cfg(any(target_os = "linux", target_os = "android", From 40794bf4b890ed4a6fba9a7c2bee81304a754379 Mon Sep 17 00:00:00 2001 From: Sebastian Humenda Date: Thu, 7 Sep 2017 21:04:24 +0200 Subject: [PATCH 4/6] Move the stack size value for L4Re to the min_stack_size function --- src/libstd/sys/unix/thread.rs | 4 ---- src/libstd/sys_common/util.rs | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 5e2610736a8d..60bce7924cdd 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -53,10 +53,6 @@ pub unsafe fn new<'a>(stack: usize, p: Box) let stack_size = cmp::max(stack, min_stack_size(&attr)); - // L4Re only supports a maximum of 1Mb per default. - #[cfg(target_os = "l4re")] - let stack_size = cmp::min(stack_size, 1024 * 1024); - match pthread_attr_setstacksize(&mut attr, stack_size) { 0 => {} diff --git a/src/libstd/sys_common/util.rs b/src/libstd/sys_common/util.rs index daa0c15920b6..41be6f437634 100644 --- a/src/libstd/sys_common/util.rs +++ b/src/libstd/sys_common/util.rs @@ -22,7 +22,12 @@ pub fn min_stack() -> usize { n => return n - 1, } let amt = env::var("RUST_MIN_STACK").ok().and_then(|s| s.parse().ok()); + #[cfg(not(target_os = "l4re"))] let amt = amt.unwrap_or(2 * 1024 * 1024); + // L4Re only supports a maximum of 1Mb per default. + #[cfg(target_os = "l4re")] + let amt = amt.unwrap_or(1024 * 1024); + // 0 is our sentinel value, so ensure that we'll never see 0 after // initialization has run MIN.store(amt + 1, Ordering::SeqCst); From 5d1a9d7ae761cb7fd88b37bab0d55f59379462ef Mon Sep 17 00:00:00 2001 From: Tobias Schaffner Date: Fri, 8 Sep 2017 14:34:10 +0200 Subject: [PATCH 5/6] Update liblibc submodule to include latest uclibc changes --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index 04a5e75c99dc..95848f9622de 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 04a5e75c99dc92afab490c38fcbbeac9b4bc8104 +Subproject commit 95848f9622deccc9cbadcd5d3a4faef01a90ead4 From b2b50635172254777d16d0fc6112e6d5b68b63f2 Mon Sep 17 00:00:00 2001 From: Tobias Schaffner Date: Sat, 9 Sep 2017 11:09:34 +0200 Subject: [PATCH 6/6] Move default stack min size to thread implementations The default min stack size value is smaller on l4re and therefore this value has to be different depending on the platform. --- src/libstd/sys/redox/thread.rs | 2 ++ src/libstd/sys/unix/l4re.rs | 4 ++-- src/libstd/sys/unix/thread.rs | 5 +++++ src/libstd/sys/windows/thread.rs | 2 ++ src/libstd/sys_common/thread.rs | 18 ++++++++++++++++++ src/libstd/sys_common/util.rs | 21 --------------------- src/libstd/thread/mod.rs | 4 ++-- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index b2c0e285f066..c4aad8d86f8b 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -16,6 +16,8 @@ use sys::{cvt, syscall}; use time::Duration; +pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; + pub struct Thread { id: usize, } diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs index e07c864a6cbd..212184896793 100644 --- a/src/libstd/sys/unix/l4re.rs +++ b/src/libstd/sys/unix/l4re.rs @@ -104,11 +104,11 @@ pub fn take_error(&self) -> io::Result> { impl AsInner for Socket { fn as_inner(&self) -> &libc::c_int { self.0.as_inner() } } - + impl FromInner for Socket { fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) } } - + impl IntoInner for Socket { fn into_inner(self) -> libc::c_int { self.0.into_raw() } } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 60bce7924cdd..6c4a33242964 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -20,6 +20,11 @@ use sys_common::thread::*; +#[cfg(not(target_os = "l4re"))] +pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; +#[cfg(target_os = "l4re")] +pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024; + pub struct Thread { id: libc::pthread_t, } diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 2cdd86e88b0a..6aea9d1fb560 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -19,6 +19,8 @@ use sys_common::thread::*; use time::Duration; +pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; + pub struct Thread { handle: Handle } diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs index 3ee160da5fa5..87fb34a9dec0 100644 --- a/src/libstd/sys_common/thread.rs +++ b/src/libstd/sys_common/thread.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use env; use alloc::boxed::FnBox; use libc; +use sync::atomic::{self, Ordering}; use sys::stack_overflow; +use sys::thread as imp; pub unsafe fn start_thread(main: *mut libc::c_void) { // Next, set up our stack overflow handler which may get triggered if we run @@ -20,3 +23,18 @@ pub unsafe fn start_thread(main: *mut libc::c_void) { // Finally, let's run some code. Box::from_raw(main as *mut Box)() } + +pub fn min_stack() -> usize { + static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0); + match MIN.load(Ordering::SeqCst) { + 0 => {} + n => return n - 1, + } + let amt = env::var("RUST_MIN_STACK").ok().and_then(|s| s.parse().ok()); + let amt = amt.unwrap_or(imp::DEFAULT_MIN_STACK_SIZE); + + // 0 is our sentinel value, so ensure that we'll never see 0 after + // initialization has run + MIN.store(amt + 1, Ordering::SeqCst); + amt +} diff --git a/src/libstd/sys_common/util.rs b/src/libstd/sys_common/util.rs index 41be6f437634..a391c7cc6ef0 100644 --- a/src/libstd/sys_common/util.rs +++ b/src/libstd/sys_common/util.rs @@ -8,32 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use env; use fmt; use io::prelude::*; -use sync::atomic::{self, Ordering}; use sys::stdio::Stderr; use thread; -pub fn min_stack() -> usize { - static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0); - match MIN.load(Ordering::SeqCst) { - 0 => {} - n => return n - 1, - } - let amt = env::var("RUST_MIN_STACK").ok().and_then(|s| s.parse().ok()); - #[cfg(not(target_os = "l4re"))] - let amt = amt.unwrap_or(2 * 1024 * 1024); - // L4Re only supports a maximum of 1Mb per default. - #[cfg(target_os = "l4re")] - let amt = amt.unwrap_or(1024 * 1024); - - // 0 is our sentinel value, so ensure that we'll never see 0 after - // initialization has run - MIN.store(amt + 1, Ordering::SeqCst); - amt -} - pub fn dumb_print(args: fmt::Arguments) { let _ = Stderr::new().map(|mut stderr| stderr.write_fmt(args)); } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 4912ff93abdb..ca01eaefcaef 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -174,7 +174,7 @@ use sys::thread as imp; use sys_common::mutex; use sys_common::thread_info; -use sys_common::util; +use sys_common::thread; use sys_common::{AsInner, IntoInner}; use time::Duration; @@ -374,7 +374,7 @@ pub fn spawn(self, f: F) -> io::Result> where { let Builder { name, stack_size } = self; - let stack_size = stack_size.unwrap_or_else(util::min_stack); + let stack_size = stack_size.unwrap_or_else(thread::min_stack); let my_thread = Thread::new(name); let their_thread = my_thread.clone();