@@ -52,30 +52,45 @@ impl Command {
52
52
None => ptr:: null ( ) ,
53
53
} ;
54
54
55
- let make_action = |local_io : & ChildStdio , target_fd| if let Some ( local_fd) = local_io. fd ( ) {
56
- fdio_spawn_action_t {
57
- action : FDIO_SPAWN_ACTION_TRANSFER_FD ,
58
- local_fd,
59
- target_fd,
60
- ..Default :: default ( )
61
- }
62
- } else {
63
- if let ChildStdio :: Null = local_io {
64
- // acts as no-op
65
- return Default :: default ( ) ;
66
- }
67
- fdio_spawn_action_t {
68
- action : FDIO_SPAWN_ACTION_CLONE_FD ,
69
- local_fd : target_fd,
70
- target_fd,
71
- ..Default :: default ( )
55
+ let make_action = |local_io : & ChildStdio , target_fd| -> io:: Result < fdio_spawn_action_t > {
56
+ if let Some ( local_fd) = local_io. fd ( ) {
57
+ Ok ( fdio_spawn_action_t {
58
+ action : FDIO_SPAWN_ACTION_TRANSFER_FD ,
59
+ local_fd,
60
+ target_fd,
61
+ ..Default :: default ( )
62
+ } )
63
+ } else {
64
+ if let ChildStdio :: Null = local_io {
65
+ // acts as no-op
66
+ return Ok ( Default :: default ( ) ) ;
67
+ }
68
+
69
+ let mut handle = ZX_HANDLE_INVALID ;
70
+ let status = fdio_fd_clone ( target_fd, & mut handle) ;
71
+ if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
72
+ // This descriptor is closed; skip it rather than generating an
73
+ // error.
74
+ return Ok ( Default :: default ( ) ) ;
75
+ }
76
+ zx_cvt ( status) ?;
77
+
78
+ let mut cloned_fd = 0 ;
79
+ zx_cvt ( fdio_fd_create ( handle, & mut cloned_fd) ) ?;
80
+
81
+ Ok ( fdio_spawn_action_t {
82
+ action : FDIO_SPAWN_ACTION_TRANSFER_FD ,
83
+ local_fd : cloned_fd as i32 ,
84
+ target_fd,
85
+ ..Default :: default ( )
86
+ } )
72
87
}
73
88
} ;
74
89
75
90
// Clone stdin, stdout, and stderr
76
- let action1 = make_action ( & stdio. stdin , 0 ) ;
77
- let action2 = make_action ( & stdio. stdout , 1 ) ;
78
- let action3 = make_action ( & stdio. stderr , 2 ) ;
91
+ let action1 = make_action ( & stdio. stdin , 0 ) ? ;
92
+ let action2 = make_action ( & stdio. stdout , 1 ) ? ;
93
+ let action3 = make_action ( & stdio. stderr , 2 ) ? ;
79
94
let actions = [ action1, action2, action3] ;
80
95
81
96
// We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
@@ -88,7 +103,7 @@ impl Command {
88
103
89
104
let mut process_handle: zx_handle_t = 0 ;
90
105
zx_cvt ( fdio_spawn_etc (
91
- 0 ,
106
+ ZX_HANDLE_INVALID ,
92
107
FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE ,
93
108
self . get_argv ( ) [ 0 ] , self . get_argv ( ) . as_ptr ( ) , envp,
94
109
actions. len ( ) as size_t , actions. as_ptr ( ) ,
0 commit comments