@@ -15,6 +15,8 @@ use crate::sys::weak::raw_syscall;
15
15
16
16
#[ cfg( any(
17
17
target_os = "macos" ,
18
+ target_os = "watchos" ,
19
+ target_os = "tvos" ,
18
20
target_os = "freebsd" ,
19
21
all( target_os = "linux" , target_env = "gnu" ) ,
20
22
all( target_os = "linux" , target_env = "musl" ) ,
@@ -28,7 +30,12 @@ use libc::RTP_ID as pid_t;
28
30
#[ cfg( not( target_os = "vxworks" ) ) ]
29
31
use libc:: { c_int, pid_t} ;
30
32
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
+ ) ) ) ]
32
39
use libc:: { gid_t, uid_t} ;
33
40
34
41
cfg_if:: cfg_if! {
@@ -84,7 +91,6 @@ impl Command {
84
91
if let Some ( ret) = self . posix_spawn ( & theirs, envp. as_ref ( ) ) ? {
85
92
return Ok ( ( ret, ours) ) ;
86
93
}
87
-
88
94
let ( input, output) = sys:: pipe:: anon_pipe ( ) ?;
89
95
90
96
// Whatever happens after the fork is almost for sure going to touch or
@@ -166,9 +172,32 @@ impl Command {
166
172
crate :: sys_common:: process:: wait_with_output ( proc, pipes)
167
173
}
168
174
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
+
169
193
// Attempts to fork the process. If successful, returns Ok((0, -1))
170
194
// 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
+ ) ) ) ]
172
201
unsafe fn do_fork ( & mut self ) -> Result < ( pid_t , pid_t ) , io:: Error > {
173
202
cvt ( libc:: fork ( ) ) . map ( |res| ( res, -1 ) )
174
203
}
@@ -339,6 +368,7 @@ impl Command {
339
368
// allocation). Instead we just close it manually. This will never
340
369
// have the drop glue anyway because this code never returns (the
341
370
// child will either exec() or invoke libc::exit)
371
+ #[ cfg( not( any( target_os = "tvos" , target_os = "watchos" ) ) ) ]
342
372
unsafe fn do_exec (
343
373
& mut self ,
344
374
stdio : ChildPipes ,
@@ -445,8 +475,19 @@ impl Command {
445
475
Err ( io:: Error :: last_os_error ( ) )
446
476
}
447
477
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
+
448
487
#[ cfg( not( any(
449
488
target_os = "macos" ,
489
+ target_os = "tvos" ,
490
+ target_os = "watchos" ,
450
491
target_os = "freebsd" ,
451
492
all( target_os = "linux" , target_env = "gnu" ) ,
452
493
all( target_os = "linux" , target_env = "musl" ) ,
@@ -464,6 +505,9 @@ impl Command {
464
505
// directly.
465
506
#[ cfg( any(
466
507
target_os = "macos" ,
508
+ // FIXME: `target_os = "ios"`?
509
+ target_os = "tvos" ,
510
+ target_os = "watchos" ,
467
511
target_os = "freebsd" ,
468
512
all( target_os = "linux" , target_env = "gnu" ) ,
469
513
all( target_os = "linux" , target_env = "musl" ) ,
@@ -550,7 +594,7 @@ impl Command {
550
594
}
551
595
let addchdir = match self . get_cwd ( ) {
552
596
Some ( cwd) => {
553
- if cfg ! ( target_os = "macos" ) {
597
+ if cfg ! ( any ( target_os = "macos" , target_os = "tvos" , target_os = "watchos" ) ) {
554
598
// There is a bug in macOS where a relative executable
555
599
// path like "../myprogram" will cause `posix_spawn` to
556
600
// successfully launch the program, but erroneously return
0 commit comments