5 use crate::sys
::process
::zircon
::{Handle, zx_handle_t}
;
6 use crate::sys
::process
::process_common
::*;
10 ////////////////////////////////////////////////////////////////////////////////
12 ////////////////////////////////////////////////////////////////////////////////
15 pub fn spawn(&mut self, default: Stdio
, needs_stdin
: bool
)
16 -> io
::Result
<(Process
, StdioPipes
)> {
17 let envp
= self.capture_env();
20 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
21 "nul byte found in provided data"));
24 let (ours
, theirs
) = self.setup_io(default, needs_stdin
)?
;
26 let process_handle
= unsafe { self.do_exec(theirs, envp.as_ref())? }
;
28 Ok((Process { handle: Handle::new(process_handle) }
, ours
))
31 pub fn exec(&mut self, default: Stdio
) -> io
::Error
{
33 return io
::Error
::new(io
::ErrorKind
::InvalidInput
,
34 "nul byte found in provided data")
37 match self.setup_io(default, true) {
39 // FIXME: This is tough because we don't support the exec syscalls
46 unsafe fn do_exec(&mut self, stdio
: ChildPipes
, maybe_envp
: Option
<&CStringArray
>)
47 -> io
::Result
<zx_handle_t
> {
48 use crate::sys
::process
::zircon
::*;
50 let envp
= match maybe_envp
{
51 Some(envp
) => envp
.as_ptr(),
55 let transfer_or_clone
= |opt_fd
, target_fd
| if let Some(local_fd
) = opt_fd
{
57 action
: FDIO_SPAWN_ACTION_TRANSFER_FD
,
64 action
: FDIO_SPAWN_ACTION_CLONE_FD
,
71 // Clone stdin, stdout, and stderr
72 let action1
= transfer_or_clone(stdio
.stdin
.fd(), 0);
73 let action2
= transfer_or_clone(stdio
.stdout
.fd(), 1);
74 let action3
= transfer_or_clone(stdio
.stderr
.fd(), 2);
75 let actions
= [action1
, action2
, action3
];
77 // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
78 // always consumes transferred file descriptors.
81 for callback
in self.get_closures().iter_mut() {
85 let mut process_handle
: zx_handle_t
= 0;
86 zx_cvt(fdio_spawn_etc(
88 FDIO_SPAWN_CLONE_JOB
| FDIO_SPAWN_CLONE_LDSVC
| FDIO_SPAWN_CLONE_NAMESPACE
,
89 self.get_argv()[0], self.get_argv().as_ptr(), envp
, 3, actions
.as_ptr(),
93 // FIXME: See if we want to do something with that err_msg
99 ////////////////////////////////////////////////////////////////////////////////
101 ////////////////////////////////////////////////////////////////////////////////
108 pub fn id(&self) -> u32 {
109 self.handle
.raw() as u32
112 pub fn kill(&mut self) -> io
::Result
<()> {
113 use crate::sys
::process
::zircon
::*;
115 unsafe { zx_cvt(zx_task_kill(self.handle.raw()))?; }
120 pub fn wait(&mut self) -> io
::Result
<ExitStatus
> {
121 use crate::default::Default
;
122 use crate::sys
::process
::zircon
::*;
124 let mut proc_info
: zx_info_process_t
= Default
::default();
125 let mut actual
: size_t
= 0;
126 let mut avail
: size_t
= 0;
129 zx_cvt(zx_object_wait_one(self.handle
.raw(), ZX_TASK_TERMINATED
,
130 ZX_TIME_INFINITE
, ptr
::null_mut()))?
;
131 zx_cvt(zx_object_get_info(self.handle
.raw(), ZX_INFO_PROCESS
,
132 &mut proc_info
as *mut _
as *mut libc
::c_void
,
133 mem
::size_of
::<zx_info_process_t
>(), &mut actual
,
137 return Err(io
::Error
::new(io
::ErrorKind
::InvalidData
,
138 "Failed to get exit status of process"));
140 Ok(ExitStatus
::new(proc_info
.rec
.return_code
))
143 pub fn try_wait(&mut self) -> io
::Result
<Option
<ExitStatus
>> {
144 use crate::default::Default
;
145 use crate::sys
::process
::zircon
::*;
147 let mut proc_info
: zx_info_process_t
= Default
::default();
148 let mut actual
: size_t
= 0;
149 let mut avail
: size_t
= 0;
152 let status
= zx_object_wait_one(self.handle
.raw(), ZX_TASK_TERMINATED
,
156 x
if x
== ERR_TIMED_OUT
=> {
159 _
=> { panic!("Failed to wait on process handle: {}
", status); },
161 zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
162 &mut proc_info as *mut _ as *mut libc::c_void,
163 mem::size_of::<zx_info_process_t>(), &mut actual,
167 return Err(io::Error::new(io::ErrorKind::InvalidData,
168 "Failed to get exit status of process
"));
170 Ok(Some(ExitStatus::new(proc_info.rec.return_code)))