Avoid fork/exec spawning on tvOS/watchOS, as those functions are marked as prohibited
This commit is contained in:
parent
b80e0b7f53
commit
49da0acb71
@ -15,6 +15,8 @@ use crate::sys::weak::raw_syscall;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "watchos",
|
||||
target_os = "tvos",
|
||||
target_os = "freebsd",
|
||||
all(target_os = "linux", target_env = "gnu"),
|
||||
all(target_os = "linux", target_env = "musl"),
|
||||
@ -28,7 +30,12 @@ use libc::RTP_ID as pid_t;
|
||||
#[cfg(not(target_os = "vxworks"))]
|
||||
use libc::{c_int, pid_t};
|
||||
|
||||
#[cfg(not(any(target_os = "vxworks", target_os = "l4re")))]
|
||||
#[cfg(not(any(
|
||||
target_os = "vxworks",
|
||||
target_os = "l4re",
|
||||
target_os = "tvos",
|
||||
target_os = "watchos",
|
||||
)))]
|
||||
use libc::{gid_t, uid_t};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
@ -84,7 +91,6 @@ impl Command {
|
||||
if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? {
|
||||
return Ok((ret, ours));
|
||||
}
|
||||
|
||||
let (input, output) = sys::pipe::anon_pipe()?;
|
||||
|
||||
// Whatever happens after the fork is almost for sure going to touch or
|
||||
@ -166,9 +172,32 @@ impl Command {
|
||||
crate::sys_common::process::wait_with_output(proc, pipes)
|
||||
}
|
||||
|
||||
// WatchOS and TVOS can theoretically spawn processes using `posix_spawn*`
|
||||
// (although it just fails with a runtime error AFAICT, so we don't yet
|
||||
// support it in `std`), but forbid use of `fork`/`exec*`. It's unclear the
|
||||
// extent to which these is restricted, but the headers say
|
||||
// `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, so we go out of our way to
|
||||
// avoid containing any calls to them at all, to avoid linking against their
|
||||
// symbols on those targets.
|
||||
#[cfg(any(target_os = "tvos", target_os = "watchos"))]
|
||||
const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_io_error!(
|
||||
ErrorKind::Unsupported,
|
||||
"`fork`+`exec`-based process spawning is not supported on this target",
|
||||
);
|
||||
|
||||
#[cfg(any(target_os = "tvos", target_os = "watchos"))]
|
||||
unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
|
||||
return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC);
|
||||
}
|
||||
|
||||
// Attempts to fork the process. If successful, returns Ok((0, -1))
|
||||
// in the child, and Ok((child_pid, -1)) in the parent.
|
||||
#[cfg(not(any(target_os = "linux", all(target_os = "nto", target_env = "nto71"))))]
|
||||
#[cfg(not(any(
|
||||
target_os = "linux",
|
||||
target_os = "watchos",
|
||||
target_os = "tvos",
|
||||
all(target_os = "nto", target_env = "nto71"),
|
||||
)))]
|
||||
unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
|
||||
cvt(libc::fork()).map(|res| (res, -1))
|
||||
}
|
||||
@ -339,6 +368,7 @@ impl Command {
|
||||
// allocation). Instead we just close it manually. This will never
|
||||
// have the drop glue anyway because this code never returns (the
|
||||
// child will either exec() or invoke libc::exit)
|
||||
#[cfg(not(any(target_os = "tvos", target_os = "watchos")))]
|
||||
unsafe fn do_exec(
|
||||
&mut self,
|
||||
stdio: ChildPipes,
|
||||
@ -445,8 +475,19 @@ impl Command {
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "tvos", target_os = "watchos"))]
|
||||
unsafe fn do_exec(
|
||||
&mut self,
|
||||
_stdio: ChildPipes,
|
||||
_maybe_envp: Option<&CStringArray>,
|
||||
) -> Result<!, io::Error> {
|
||||
return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC);
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
target_os = "tvos",
|
||||
target_os = "watchos",
|
||||
target_os = "freebsd",
|
||||
all(target_os = "linux", target_env = "gnu"),
|
||||
all(target_os = "linux", target_env = "musl"),
|
||||
@ -464,6 +505,9 @@ impl Command {
|
||||
// directly.
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
// FIXME: `target_os = "ios"`?
|
||||
target_os = "tvos",
|
||||
target_os = "watchos",
|
||||
target_os = "freebsd",
|
||||
all(target_os = "linux", target_env = "gnu"),
|
||||
all(target_os = "linux", target_env = "musl"),
|
||||
@ -550,7 +594,7 @@ impl Command {
|
||||
}
|
||||
let addchdir = match self.get_cwd() {
|
||||
Some(cwd) => {
|
||||
if cfg!(target_os = "macos") {
|
||||
if cfg!(any(target_os = "macos", target_os = "tvos", target_os = "watchos")) {
|
||||
// There is a bug in macOS where a relative executable
|
||||
// path like "../myprogram" will cause `posix_spawn` to
|
||||
// successfully launch the program, but erroneously return
|
||||
|
Loading…
x
Reference in New Issue
Block a user