@@ -15,6 +15,8 @@ use crate::sys::weak::raw_syscall;
1515
1616#[ cfg( any(
1717 target_os = "macos" ,
18+ target_os = "watchos" ,
19+ target_os = "tvos" ,
1820 target_os = "freebsd" ,
1921 all( target_os = "linux" , target_env = "gnu" ) ,
2022 all( target_os = "linux" , target_env = "musl" ) ,
@@ -28,7 +30,12 @@ use libc::RTP_ID as pid_t;
2830#[ cfg( not( target_os = "vxworks" ) ) ]
2931use libc:: { c_int, pid_t} ;
3032
31- #[ cfg( not( any( target_os = "vxworks" , target_os = "l4re" ) ) ) ]
33+ #[ cfg( not( any(
34+ target_os = "vxworks" ,
35+ target_os = "l4re" ,
36+ target_os = "tvos" ,
37+ target_os = "watchos" ,
38+ ) ) ) ]
3239use libc:: { gid_t, uid_t} ;
3340
3441cfg_if:: cfg_if! {
@@ -84,7 +91,6 @@ impl Command {
8491 if let Some ( ret) = self . posix_spawn ( & theirs, envp. as_ref ( ) ) ? {
8592 return Ok ( ( ret, ours) ) ;
8693 }
87-
8894 let ( input, output) = sys:: pipe:: anon_pipe ( ) ?;
8995
9096 // Whatever happens after the fork is almost for sure going to touch or
@@ -166,9 +172,32 @@ impl Command {
166172 crate :: sys_common:: process:: wait_with_output ( proc, pipes)
167173 }
168174
175+ // WatchOS and TVOS can theoretically spawn processes using `posix_spawn*`
176+ // (although it just fails with a runtime error AFAICT, so we don't yet
177+ // support it in `std`), but forbid use of `fork`/`exec*`. It's unclear the
178+ // extent to which these is restricted, but the headers say
179+ // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, so we go out of our way to
180+ // avoid containing any calls to them at all, to avoid linking against their
181+ // symbols on those targets.
182+ #[ cfg( any( target_os = "tvos" , target_os = "watchos" ) ) ]
183+ const ERR_APPLE_TV_WATCH_NO_FORK_EXEC : Error = io:: const_io_error!(
184+ ErrorKind :: Unsupported ,
185+ "`fork`+`exec`-based process spawning is not supported on this target" ,
186+ ) ;
187+
188+ #[ cfg( any( target_os = "tvos" , target_os = "watchos" ) ) ]
189+ unsafe fn do_fork ( & mut self ) -> Result < ( pid_t , pid_t ) , io:: Error > {
190+ return Err ( Self :: ERR_APPLE_TV_WATCH_NO_FORK_EXEC ) ;
191+ }
192+
169193 // Attempts to fork the process. If successful, returns Ok((0, -1))
170194 // in the child, and Ok((child_pid, -1)) in the parent.
171- #[ cfg( not( any( target_os = "linux" , all( target_os = "nto" , target_env = "nto71" ) ) ) ) ]
195+ #[ cfg( not( any(
196+ target_os = "linux" ,
197+ target_os = "watchos" ,
198+ target_os = "tvos" ,
199+ all( target_os = "nto" , target_env = "nto71" ) ,
200+ ) ) ) ]
172201 unsafe fn do_fork ( & mut self ) -> Result < ( pid_t , pid_t ) , io:: Error > {
173202 cvt ( libc:: fork ( ) ) . map ( |res| ( res, -1 ) )
174203 }
@@ -339,6 +368,7 @@ impl Command {
339368 // allocation). Instead we just close it manually. This will never
340369 // have the drop glue anyway because this code never returns (the
341370 // child will either exec() or invoke libc::exit)
371+ #[ cfg( not( any( target_os = "tvos" , target_os = "watchos" ) ) ) ]
342372 unsafe fn do_exec (
343373 & mut self ,
344374 stdio : ChildPipes ,
@@ -445,8 +475,19 @@ impl Command {
445475 Err ( io:: Error :: last_os_error ( ) )
446476 }
447477
478+ #[ cfg( any( target_os = "tvos" , target_os = "watchos" ) ) ]
479+ unsafe fn do_exec (
480+ & mut self ,
481+ _stdio : ChildPipes ,
482+ _maybe_envp : Option < & CStringArray > ,
483+ ) -> Result < !, io:: Error > {
484+ return Err ( Self :: ERR_APPLE_TV_WATCH_NO_FORK_EXEC ) ;
485+ }
486+
448487 #[ cfg( not( any(
449488 target_os = "macos" ,
489+ target_os = "tvos" ,
490+ target_os = "watchos" ,
450491 target_os = "freebsd" ,
451492 all( target_os = "linux" , target_env = "gnu" ) ,
452493 all( target_os = "linux" , target_env = "musl" ) ,
@@ -464,6 +505,9 @@ impl Command {
464505 // directly.
465506 #[ cfg( any(
466507 target_os = "macos" ,
508+ // FIXME: `target_os = "ios"`?
509+ target_os = "tvos" ,
510+ target_os = "watchos" ,
467511 target_os = "freebsd" ,
468512 all( target_os = "linux" , target_env = "gnu" ) ,
469513 all( target_os = "linux" , target_env = "musl" ) ,
@@ -550,7 +594,7 @@ impl Command {
550594 }
551595 let addchdir = match self . get_cwd ( ) {
552596 Some ( cwd) => {
553- if cfg ! ( target_os = "macos" ) {
597+ if cfg ! ( any ( target_os = "macos" , target_os = "tvos" , target_os = "watchos" ) ) {
554598 // There is a bug in macOS where a relative executable
555599 // path like "../myprogram" will cause `posix_spawn` to
556600 // successfully launch the program, but erroneously return
0 commit comments