Skip to content

Commit 8bee18b

Browse files
authored
Rollup merge of rust-lang#64023 - tmandry:libstd-fuchsia-fixes, r=cramertj
libstd fuchsia fixes This fixes two bugs in libstd on Fuchsia: - `zx_time_t` was changed to an `i64`, but this never made it into libstd - When spawning processes where any of the stdio were null, libstd attempts to open `/dev/null`, which doesn't exist on Fuchsia r? @cramertj
2 parents ef54f57 + 5f91ad0 commit 8bee18b

File tree

3 files changed

+76
-27
lines changed

3 files changed

+76
-27
lines changed

src/libstd/sys/unix/process/process_common.rs

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
use crate::os::unix::prelude::*;
22

3-
use crate::ffi::{OsString, OsStr, CString, CStr};
3+
use crate::ffi::{OsString, OsStr, CString};
44
use crate::fmt;
55
use crate::io;
66
use crate::ptr;
77
use crate::sys::fd::FileDesc;
8-
use crate::sys::fs::{File, OpenOptions};
8+
use crate::sys::fs::File;
99
use crate::sys::pipe::{self, AnonPipe};
1010
use crate::sys_common::process::CommandEnv;
1111
use crate::collections::BTreeMap;
1212

13+
#[cfg(not(target_os = "fuchsia"))]
14+
use {
15+
crate::ffi::CStr,
16+
crate::sys::fs::OpenOptions,
17+
};
18+
1319
use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
1420

1521
cfg_if::cfg_if! {
16-
if #[cfg(target_os = "redox")] {
22+
if #[cfg(target_os = "fuchsia")] {
23+
// fuchsia doesn't have /dev/null
24+
} else if #[cfg(target_os = "redox")] {
1725
const DEV_NULL: &'static str = "null:\0";
1826
} else {
1927
const DEV_NULL: &'static str = "/dev/null\0";
@@ -107,6 +115,11 @@ pub enum ChildStdio {
107115
Inherit,
108116
Explicit(c_int),
109117
Owned(FileDesc),
118+
119+
// On Fuchsia, null stdio is the default, so we simply don't specify
120+
// any actions at the time of spawning.
121+
#[cfg(target_os = "fuchsia")]
122+
Null,
110123
}
111124

112125
pub enum Stdio {
@@ -325,6 +338,7 @@ impl Stdio {
325338
Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
326339
}
327340

341+
#[cfg(not(target_os = "fuchsia"))]
328342
Stdio::Null => {
329343
let mut opts = OpenOptions::new();
330344
opts.read(readable);
@@ -335,6 +349,11 @@ impl Stdio {
335349
let fd = File::open_c(&path, &opts)?;
336350
Ok((ChildStdio::Owned(fd.into_fd()), None))
337351
}
352+
353+
#[cfg(target_os = "fuchsia")]
354+
Stdio::Null => {
355+
Ok((ChildStdio::Null, None))
356+
}
338357
}
339358
}
340359
}
@@ -357,6 +376,9 @@ impl ChildStdio {
357376
ChildStdio::Inherit => None,
358377
ChildStdio::Explicit(fd) => Some(fd),
359378
ChildStdio::Owned(ref fd) => Some(fd.raw()),
379+
380+
#[cfg(target_os = "fuchsia")]
381+
ChildStdio::Null => None,
360382
}
361383
}
362384
}

src/libstd/sys/unix/process/process_fuchsia.rs

+43-20
Original file line numberDiff line numberDiff line change
@@ -48,30 +48,51 @@ impl Command {
4848
use crate::sys::process::zircon::*;
4949

5050
let envp = match maybe_envp {
51-
Some(envp) => envp.as_ptr(),
51+
// None means to clone the current environment, which is done in the
52+
// flags below.
5253
None => ptr::null(),
54+
Some(envp) => envp.as_ptr(),
5355
};
5456

55-
let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_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-
fdio_spawn_action_t {
64-
action: FDIO_SPAWN_ACTION_CLONE_FD,
65-
local_fd: target_fd,
66-
target_fd,
67-
..Default::default()
57+
let make_action = |local_io: &ChildStdio, target_fd| -> io::Result<fdio_spawn_action_t> {
58+
if let Some(local_fd) = local_io.fd() {
59+
Ok(fdio_spawn_action_t {
60+
action: FDIO_SPAWN_ACTION_TRANSFER_FD,
61+
local_fd,
62+
target_fd,
63+
..Default::default()
64+
})
65+
} else {
66+
if let ChildStdio::Null = local_io {
67+
// acts as no-op
68+
return Ok(Default::default());
69+
}
70+
71+
let mut handle = ZX_HANDLE_INVALID;
72+
let status = fdio_fd_clone(target_fd, &mut handle);
73+
if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
74+
// This descriptor is closed; skip it rather than generating an
75+
// error.
76+
return Ok(Default::default());
77+
}
78+
zx_cvt(status)?;
79+
80+
let mut cloned_fd = 0;
81+
zx_cvt(fdio_fd_create(handle, &mut cloned_fd))?;
82+
83+
Ok(fdio_spawn_action_t {
84+
action: FDIO_SPAWN_ACTION_TRANSFER_FD,
85+
local_fd: cloned_fd as i32,
86+
target_fd,
87+
..Default::default()
88+
})
6889
}
6990
};
7091

7192
// 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);
93+
let action1 = make_action(&stdio.stdin, 0)?;
94+
let action2 = make_action(&stdio.stdout, 1)?;
95+
let action3 = make_action(&stdio.stderr, 2)?;
7596
let actions = [action1, action2, action3];
7697

7798
// We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
@@ -84,9 +105,11 @@ impl Command {
84105

85106
let mut process_handle: zx_handle_t = 0;
86107
zx_cvt(fdio_spawn_etc(
87-
0,
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(),
108+
ZX_HANDLE_INVALID,
109+
FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE
110+
| FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null
111+
self.get_argv()[0], self.get_argv().as_ptr(), envp,
112+
actions.len() as size_t, actions.as_ptr(),
90113
&mut process_handle,
91114
ptr::null_mut(),
92115
))?;

src/libstd/sys/unix/process/zircon.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
use crate::convert::TryInto;
44
use crate::io;
5+
use crate::i64;
6+
use crate::mem::MaybeUninit;
57
use crate::os::raw::c_char;
6-
use crate::u64;
78

89
use libc::{c_int, c_void, size_t};
910

@@ -14,8 +15,8 @@ pub type zx_status_t = i32;
1415

1516
pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
1617

17-
pub type zx_time_t = u64;
18-
pub const ZX_TIME_INFINITE : zx_time_t = u64::MAX;
18+
pub type zx_time_t = i64;
19+
pub const ZX_TIME_INFINITE : zx_time_t = i64::MAX;
1920

2021
pub type zx_signals_t = u32;
2122

@@ -120,8 +121,11 @@ pub struct fdio_spawn_action_t {
120121
extern {
121122
pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char,
122123
argv: *const *const c_char, envp: *const *const c_char,
123-
action_count: u64, actions: *const fdio_spawn_action_t,
124+
action_count: size_t, actions: *const fdio_spawn_action_t,
124125
process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
126+
127+
pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
128+
pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
125129
}
126130

127131
// fdio_spawn_etc flags

0 commit comments

Comments
 (0)