diff options
| author | Christiaan Dirkx <christiaan@dirkx.email> | 2021-04-12 05:58:30 +0200 | 
|---|---|---|
| committer | Christiaan Dirkx <christiaan@dirkx.email> | 2021-04-19 13:29:22 +0200 | 
| commit | 12120409d56ecfb5bd8ddd06bfecd0443b043834 (patch) | |
| tree | 84e16a54eade27bb3a9747cf473088d5e578d8dd /library/std/src/sys/unix | |
| parent | 62652865b6029b4776a7c03efa13a37b15c9b953 (diff) | |
| download | rust-12120409d56ecfb5bd8ddd06bfecd0443b043834.tar.gz rust-12120409d56ecfb5bd8ddd06bfecd0443b043834.zip | |
Move `sys::vxworks` code to `sys::unix`
Diffstat (limited to 'library/std/src/sys/unix')
| -rw-r--r-- | library/std/src/sys/unix/env.rs | 11 | ||||
| -rw-r--r-- | library/std/src/sys/unix/ext/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/unix/mod.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/mod.rs | 22 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_vxworks.rs | 217 | ||||
| -rw-r--r-- | library/std/src/sys/unix/rand.rs | 29 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread_local_dtor.rs | 6 | 
7 files changed, 279 insertions, 9 deletions
| diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs index 7f5e9b04dba..3a88dc083b0 100644 --- a/library/std/src/sys/unix/env.rs +++ b/library/std/src/sys/unix/env.rs @@ -173,3 +173,14 @@ pub mod os { pub const EXE_SUFFIX: &str = ""; pub const EXE_EXTENSION: &str = ""; } + +#[cfg(target_os = "vxworks")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "vxworks"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} diff --git a/library/std/src/sys/unix/ext/mod.rs b/library/std/src/sys/unix/ext/mod.rs index e5048f7e545..735bf35a3ce 100644 --- a/library/std/src/sys/unix/ext/mod.rs +++ b/library/std/src/sys/unix/ext/mod.rs @@ -62,6 +62,8 @@ cfg_if::cfg_if! { use crate::os::redox as platform; #[cfg(target_os = "solaris")] use crate::os::solaris as platform; + #[cfg(target_os = "vxworks")] + use crate::os::vxworks as platform; } } diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 6e44ac19c7b..1316835a89d 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -71,6 +71,7 @@ pub fn init() { } else if #[cfg(not(any( target_os = "emscripten", target_os = "fuchsia", + target_os = "vxworks", // The poll on Darwin doesn't set POLLNVAL for closed fds. target_os = "macos", target_os = "ios", diff --git a/library/std/src/sys/unix/process/mod.rs b/library/std/src/sys/unix/process/mod.rs index 1b7b93f9d4a..f67c70c0177 100644 --- a/library/std/src/sys/unix/process/mod.rs +++ b/library/std/src/sys/unix/process/mod.rs @@ -4,11 +4,17 @@ pub use crate::ffi::OsString as EnvKey; pub use crate::sys_common::process::CommandEnvs; mod process_common; -#[cfg(not(target_os = "fuchsia"))] -#[path = "process_unix.rs"] -mod process_inner; -#[cfg(target_os = "fuchsia")] -#[path = "process_fuchsia.rs"] -mod process_inner; -#[cfg(target_os = "fuchsia")] -mod zircon; + +cfg_if::cfg_if! { + if #[cfg(target_os = "fuchsia")] { + #[path = "process_fuchsia.rs"] + mod process_inner; + mod zircon; + } else if #[cfg(target_os = "vxworks")] { + #[path = "process_vxworks.rs"] + mod process_inner; + } else { + #[path = "process_unix.rs"] + mod process_inner; + } +} diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs new file mode 100644 index 00000000000..68605c2dfee --- /dev/null +++ b/library/std/src/sys/unix/process/process_vxworks.rs @@ -0,0 +1,217 @@ +use crate::fmt; +use crate::io::{self, Error, ErrorKind}; +use crate::sys; +use crate::sys::cvt; +use crate::sys::process::process_common::*; +use crate::sys_common::thread; +use libc::RTP_ID; +use libc::{self, c_char, c_int}; + +//////////////////////////////////////////////////////////////////////////////// +// Command +//////////////////////////////////////////////////////////////////////////////// + +impl Command { + pub fn spawn( + &mut self, + default: Stdio, + needs_stdin: bool, + ) -> io::Result<(Process, StdioPipes)> { + use crate::sys::cvt_r; + const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX"; + let envp = self.capture_env(); + + if self.saw_nul() { + return Err(io::Error::new_const( + ErrorKind::InvalidInput, + &"nul byte found in provided data", + )); + } + let (ours, theirs) = self.setup_io(default, needs_stdin)?; + let mut p = Process { pid: 0, status: None }; + + unsafe { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => return Err(e.into()), + } + }; + } + + let mut orig_stdin = libc::STDIN_FILENO; + let mut orig_stdout = libc::STDOUT_FILENO; + let mut orig_stderr = libc::STDERR_FILENO; + + if let Some(fd) = theirs.stdin.fd() { + orig_stdin = t!(cvt_r(|| libc::dup(libc::STDIN_FILENO))); + t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))); + } + if let Some(fd) = theirs.stdout.fd() { + orig_stdout = t!(cvt_r(|| libc::dup(libc::STDOUT_FILENO))); + t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))); + } + if let Some(fd) = theirs.stderr.fd() { + orig_stderr = t!(cvt_r(|| libc::dup(libc::STDERR_FILENO))); + t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); + } + + if let Some(ref cwd) = *self.get_cwd() { + t!(cvt(libc::chdir(cwd.as_ptr()))); + } + + let c_envp = envp + .as_ref() + .map(|c| c.as_ptr()) + .unwrap_or_else(|| *sys::os::environ() as *const _); + let stack_size = thread::min_stack(); + + // ensure that access to the environment is synchronized + let _lock = sys::os::env_read_lock(); + + let ret = libc::rtpSpawn( + self.get_program_cstr().as_ptr(), + self.get_argv().as_ptr() as *mut *const c_char, // argv + c_envp as *mut *const c_char, + 100 as c_int, // initial priority + stack_size, // initial stack size. + 0, // options + 0, // task options + ); + + // Because FileDesc was not used, each duplicated file descriptor + // needs to be closed manually + if orig_stdin != libc::STDIN_FILENO { + t!(cvt_r(|| libc::dup2(orig_stdin, libc::STDIN_FILENO))); + libc::close(orig_stdin); + } + if orig_stdout != libc::STDOUT_FILENO { + t!(cvt_r(|| libc::dup2(orig_stdout, libc::STDOUT_FILENO))); + libc::close(orig_stdout); + } + if orig_stderr != libc::STDERR_FILENO { + t!(cvt_r(|| libc::dup2(orig_stderr, libc::STDERR_FILENO))); + libc::close(orig_stderr); + } + + if ret != libc::RTP_ID_ERROR { + p.pid = ret; + Ok((p, ours)) + } else { + Err(io::Error::last_os_error()) + } + } + } + + pub fn exec(&mut self, default: Stdio) -> io::Error { + let ret = Command::spawn(self, default, false); + match ret { + Ok(t) => unsafe { + let mut status = 0 as c_int; + libc::waitpid(t.0.pid, &mut status, 0); + libc::exit(0); + }, + Err(e) => e, + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Processes +//////////////////////////////////////////////////////////////////////////////// + +/// The unique id of the process (this should never be negative). +pub struct Process { + pid: RTP_ID, + status: Option<ExitStatus>, +} + +impl Process { + pub fn id(&self) -> u32 { + self.pid as u32 + } + + pub fn kill(&mut self) -> io::Result<()> { + // If we've already waited on this process then the pid can be recycled + // and used for another process, and we probably shouldn't be killing + // random processes, so just return an error. + if self.status.is_some() { + Err(Error::new_const( + ErrorKind::InvalidInput, + &"invalid argument: can't kill an exited process", + )) + } else { + cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(drop) + } + } + + pub fn wait(&mut self) -> io::Result<ExitStatus> { + use crate::sys::cvt_r; + if let Some(status) = self.status { + return Ok(status); + } + let mut status = 0 as c_int; + cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) })?; + self.status = Some(ExitStatus::new(status)); + Ok(ExitStatus::new(status)) + } + + pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { + if let Some(status) = self.status { + return Ok(Some(status)); + } + let mut status = 0 as c_int; + let pid = cvt(unsafe { libc::waitpid(self.pid, &mut status, libc::WNOHANG) })?; + if pid == 0 { + Ok(None) + } else { + self.status = Some(ExitStatus::new(status)); + Ok(Some(ExitStatus::new(status))) + } + } +} + +/// Unix exit statuses +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitStatus(c_int); + +impl ExitStatus { + pub fn new(status: c_int) -> ExitStatus { + ExitStatus(status) + } + + fn exited(&self) -> bool { + libc::WIFEXITED(self.0) + } + + pub fn success(&self) -> bool { + self.code() == Some(0) + } + + pub fn code(&self) -> Option<i32> { + if self.exited() { Some(libc::WEXITSTATUS(self.0)) } else { None } + } + + pub fn signal(&self) -> Option<i32> { + if !self.exited() { Some(libc::WTERMSIG(self.0)) } else { None } + } +} + +/// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying. +impl From<c_int> for ExitStatus { + fn from(a: c_int) -> ExitStatus { + ExitStatus(a) + } +} + +impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(code) = self.code() { + write!(f, "exit code: {}", code) + } else { + let signal = self.signal().unwrap(); + write!(f, "signal: {}", signal) + } + } +} diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index 38ddb41700c..44f9eabc319 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -18,7 +18,8 @@ pub fn hashmap_random_keys() -> (u64, u64) { not(target_os = "freebsd"), not(target_os = "netbsd"), not(target_os = "fuchsia"), - not(target_os = "redox") + not(target_os = "redox"), + not(target_os = "vxworks") ))] mod imp { use crate::fs::File; @@ -237,3 +238,29 @@ mod imp { file.read_exact(v).expect("failed to read rand:") } } + +#[cfg(target_os = "vxworks")] +mod imp { + use crate::io; + use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; + + pub fn fill_bytes(v: &mut [u8]) { + static RNG_INIT: AtomicBool = AtomicBool::new(false); + while !RNG_INIT.load(Relaxed) { + let ret = unsafe { libc::randSecure() }; + if ret < 0 { + panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); + } else if ret > 0 { + RNG_INIT.store(true, Relaxed); + break; + } + unsafe { libc::usleep(10) }; + } + let ret = unsafe { + libc::randABytes(v.as_mut_ptr() as *mut libc::c_uchar, v.len() as libc::c_int) + }; + if ret < 0 { + panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); + } + } +} diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs index c3275eb6f0e..c3f410353b9 100644 --- a/library/std/src/sys/unix/thread_local_dtor.rs +++ b/library/std/src/sys/unix/thread_local_dtor.rs @@ -92,3 +92,9 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { } } } + +#[cfg(target_os = "vxworks")] +pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { + use crate::sys_common::thread_local_dtor::register_dtor_fallback; + register_dtor_fallback(t, dtor); +} | 
