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 fe0427d4e5f9c..95439640f7cc5 100644 --- a/src/libstd/os/raw.rs +++ b/src/libstd/os/raw.rs @@ -21,6 +21,7 @@ use fmt; 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 @@ use fmt; 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 98bc90dd4e132..63b81c4f4c27a 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -36,6 +36,7 @@ pub mod fs; 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 4393aedf162a3..efa149646048e 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -44,6 +44,7 @@ pub mod fd; 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 ae24021fb6c3a..870db8200273e 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -160,20 +160,22 @@ impl Command { 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 433499a90a405..115adf6e3f9c1 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -466,6 +466,7 @@ pub mod error; 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 72eed549f62a0..b460bd90f1735 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -27,7 +27,7 @@ pub use sys::unix_ext as unix; #[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 810d2d40c05f4..72169773df596 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -65,6 +65,7 @@ impl DoubleEndedIterator for Args { 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 b9ea573b323d2..89a44b9765783 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -38,10 +38,16 @@ impl 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 eff3a8c2a34a4..3d9a06bedd57c 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 f50b093acc848..5dafc3251e755 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -144,6 +144,7 @@ impl FileDesc { 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 @@ impl FileDesc { 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 f94af4913324f..13112fc1fa590 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -23,19 +23,21 @@ use sys::time::SystemTime; 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 @@ impl DirEntry { 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 @@ impl DirEntry { #[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 efa149646048e..697e9b962b1c4 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -28,6 +28,7 @@ use libc; #[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 8e41fd009be67..5ef98d247105e 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -38,7 +38,10 @@ static ENV_LOCK: Mutex = Mutex::new(); 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 @@ pub fn current_exe() -> io::Result { } } -#[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 40f1d6a6db15b..5e2610736a8dd 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -52,6 +52,11 @@ impl Thread { 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 @@ impl Thread { #[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 @@ pub mod guard { } #[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 mod guard { } #[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 ccd4b91a7b733..ae8d280d5763b 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -47,7 +47,7 @@ pub mod wtf8; #[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 115adf6e3f9c1..433499a90a405 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -466,7 +466,6 @@ pub mod error; 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 63b81c4f4c27a..98bc90dd4e132 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -36,7 +36,6 @@ pub mod fs; 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 0000000000000..e07c864a6cbdc --- /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 697e9b962b1c4..1b3f1000b77bb 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -47,6 +47,10 @@ pub mod memchr; 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 ae8d280d5763b..97058372e4c89 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -44,7 +44,7 @@ pub mod thread_local; 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 1ca39ff9d4a1c..19dc841b9b502 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -24,22 +24,22 @@ use time::Duration; #[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 5e2610736a8dd..60bce7924cdd8 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -53,10 +53,6 @@ impl Thread { 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 daa0c15920b66..41be6f4376348 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 04a5e75c99dc9..95848f9622dec 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 b2c0e285f0663..c4aad8d86f8b1 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -16,6 +16,8 @@ use sys_common::thread::start_thread; 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 e07c864a6cbdc..2121848967939 100644 --- a/src/libstd/sys/unix/l4re.rs +++ b/src/libstd/sys/unix/l4re.rs @@ -104,11 +104,11 @@ pub mod net { 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 60bce7924cdd8..6c4a332429646 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -20,6 +20,11 @@ use time::Duration; 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 2cdd86e88b0a0..6aea9d1fb560f 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -19,6 +19,8 @@ use sys::handle::Handle; 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 3ee160da5fa5b..87fb34a9dec06 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 41be6f4376348..a391c7cc6ef0c 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 4912ff93abdb3..ca01eaefcaef4 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -174,7 +174,7 @@ use sync::{Mutex, Condvar, Arc}; 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 @@ impl Builder { { 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();