Skip to content

Commit 2e119b2

Browse files
committed
std: get rid of sys_common::process
Move the public `CommandEnvs` into the `process` module (and make it a wrapper type for an internal iterator type) and everything else into `sys::process` as per rust-lang#117276.
1 parent ea1da92 commit 2e119b2

File tree

12 files changed

+167
-127
lines changed

12 files changed

+167
-127
lines changed

library/std/src/process.rs

+44-4
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,6 @@ use crate::num::NonZero;
168168
use crate::path::Path;
169169
use crate::sys::pipe::{AnonPipe, read2};
170170
use crate::sys::process as imp;
171-
#[stable(feature = "command_access", since = "1.57.0")]
172-
pub use crate::sys_common::process::CommandEnvs;
173171
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
174172
use crate::{fmt, fs, str};
175173

@@ -1073,7 +1071,7 @@ impl Command {
10731071
/// ```
10741072
#[stable(feature = "process", since = "1.0.0")]
10751073
pub fn output(&mut self) -> io::Result<Output> {
1076-
let (status, stdout, stderr) = self.inner.output()?;
1074+
let (status, stdout, stderr) = imp::output(&mut self.inner)?;
10771075
Ok(Output { status: ExitStatus(status), stdout, stderr })
10781076
}
10791077

@@ -1174,7 +1172,7 @@ impl Command {
11741172
/// ```
11751173
#[stable(feature = "command_access", since = "1.57.0")]
11761174
pub fn get_envs(&self) -> CommandEnvs<'_> {
1177-
self.inner.get_envs()
1175+
CommandEnvs { iter: self.inner.get_envs() }
11781176
}
11791177

11801178
/// Returns the working directory for the child process.
@@ -1264,6 +1262,48 @@ impl<'a> ExactSizeIterator for CommandArgs<'a> {
12641262
}
12651263
}
12661264

1265+
/// An iterator over the command environment variables.
1266+
///
1267+
/// This struct is created by
1268+
/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
1269+
/// documentation for more.
1270+
#[must_use = "iterators are lazy and do nothing unless consumed"]
1271+
#[stable(feature = "command_access", since = "1.57.0")]
1272+
pub struct CommandEnvs<'a> {
1273+
iter: imp::CommandEnvs<'a>,
1274+
}
1275+
1276+
#[stable(feature = "command_access", since = "1.57.0")]
1277+
impl<'a> Iterator for CommandEnvs<'a> {
1278+
type Item = (&'a OsStr, Option<&'a OsStr>);
1279+
1280+
fn next(&mut self) -> Option<Self::Item> {
1281+
self.iter.next()
1282+
}
1283+
1284+
fn size_hint(&self) -> (usize, Option<usize>) {
1285+
self.iter.size_hint()
1286+
}
1287+
}
1288+
1289+
#[stable(feature = "command_access", since = "1.57.0")]
1290+
impl<'a> ExactSizeIterator for CommandEnvs<'a> {
1291+
fn len(&self) -> usize {
1292+
self.iter.len()
1293+
}
1294+
1295+
fn is_empty(&self) -> bool {
1296+
self.iter.is_empty()
1297+
}
1298+
}
1299+
1300+
#[stable(feature = "command_access", since = "1.57.0")]
1301+
impl<'a> fmt::Debug for CommandEnvs<'a> {
1302+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1303+
self.iter.fmt(f)
1304+
}
1305+
}
1306+
12671307
/// The output of a finished process.
12681308
///
12691309
/// This is returned in a Result by either the [`output`] method of a

library/std/src/sys_common/process.rs renamed to library/std/src/sys/process/env.rs

+5-43
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
#![allow(dead_code)]
2-
#![unstable(feature = "process_internals", issue = "none")]
3-
41
use crate::collections::BTreeMap;
52
use crate::ffi::{OsStr, OsString};
6-
use crate::sys::pipe::read2;
7-
use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes};
8-
use crate::{env, fmt, io};
3+
use crate::sys::process::EnvKey;
4+
use crate::{env, fmt};
95

10-
// Stores a set of changes to an environment
6+
/// Stores a set of changes to an environment
117
#[derive(Clone, Default)]
128
pub struct CommandEnv {
139
clear: bool,
@@ -92,30 +88,23 @@ impl CommandEnv {
9288
}
9389
}
9490

95-
/// An iterator over the command environment variables.
96-
///
97-
/// This struct is created by
98-
/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
99-
/// documentation for more.
100-
#[must_use = "iterators are lazy and do nothing unless consumed"]
101-
#[stable(feature = "command_access", since = "1.57.0")]
10291
#[derive(Debug)]
10392
pub struct CommandEnvs<'a> {
10493
iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
10594
}
10695

107-
#[stable(feature = "command_access", since = "1.57.0")]
10896
impl<'a> Iterator for CommandEnvs<'a> {
10997
type Item = (&'a OsStr, Option<&'a OsStr>);
98+
11099
fn next(&mut self) -> Option<Self::Item> {
111100
self.iter.next().map(|(key, value)| (key.as_ref(), value.as_deref()))
112101
}
102+
113103
fn size_hint(&self) -> (usize, Option<usize>) {
114104
self.iter.size_hint()
115105
}
116106
}
117107

118-
#[stable(feature = "command_access", since = "1.57.0")]
119108
impl<'a> ExactSizeIterator for CommandEnvs<'a> {
120109
fn len(&self) -> usize {
121110
self.iter.len()
@@ -124,30 +113,3 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> {
124113
self.iter.is_empty()
125114
}
126115
}
127-
128-
pub fn wait_with_output(
129-
mut process: Process,
130-
mut pipes: StdioPipes,
131-
) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
132-
drop(pipes.stdin.take());
133-
134-
let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
135-
match (pipes.stdout.take(), pipes.stderr.take()) {
136-
(None, None) => {}
137-
(Some(out), None) => {
138-
let res = out.read_to_end(&mut stdout);
139-
res.unwrap();
140-
}
141-
(None, Some(err)) => {
142-
let res = err.read_to_end(&mut stderr);
143-
res.unwrap();
144-
}
145-
(Some(out), Some(err)) => {
146-
let res = read2(out, &mut stdout, err, &mut stderr);
147-
res.unwrap();
148-
}
149-
}
150-
151-
let status = process.wait()?;
152-
Ok((status, stdout, stderr))
153-
}

library/std/src/sys/process/mod.rs

+59
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,65 @@ cfg_if::cfg_if! {
1414
}
1515
}
1616

17+
// This module is shared by all platforms, but nearly all platforms except for
18+
// the "normal" UNIX ones leave some of this code unused.
19+
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
20+
mod env;
21+
22+
pub use env::CommandEnvs;
1723
pub use imp::{
1824
Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes,
1925
};
26+
27+
#[cfg(any(
28+
all(
29+
target_family = "unix",
30+
not(any(
31+
target_os = "espidf",
32+
target_os = "horizon",
33+
target_os = "vita",
34+
target_os = "nuttx"
35+
))
36+
),
37+
target_os = "windows",
38+
))]
39+
pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
40+
use crate::sys::pipe::read2;
41+
42+
let (mut process, mut pipes) = cmd.spawn(Stdio::MakePipe, false)?;
43+
44+
drop(pipes.stdin.take());
45+
let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
46+
match (pipes.stdout.take(), pipes.stderr.take()) {
47+
(None, None) => {}
48+
(Some(out), None) => {
49+
let res = out.read_to_end(&mut stdout);
50+
res.unwrap();
51+
}
52+
(None, Some(err)) => {
53+
let res = err.read_to_end(&mut stderr);
54+
res.unwrap();
55+
}
56+
(Some(out), Some(err)) => {
57+
let res = read2(out, &mut stdout, err, &mut stderr);
58+
res.unwrap();
59+
}
60+
}
61+
62+
let status = process.wait()?;
63+
Ok((status, stdout, stderr))
64+
}
65+
66+
#[cfg(not(any(
67+
all(
68+
target_family = "unix",
69+
not(any(
70+
target_os = "espidf",
71+
target_os = "horizon",
72+
target_os = "vita",
73+
target_os = "nuttx"
74+
))
75+
),
76+
target_os = "windows",
77+
)))]
78+
pub use imp::output;

library/std/src/sys/process/uefi.rs

+49-49
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use r_efi::protocols::simple_text_output;
22

3+
use super::env::{CommandEnv, CommandEnvs};
34
use crate::collections::BTreeMap;
45
pub use crate::ffi::OsString as EnvKey;
56
use crate::ffi::{OsStr, OsString};
@@ -10,7 +11,6 @@ use crate::sys::pal::helpers;
1011
use crate::sys::pal::os::error_string;
1112
use crate::sys::pipe::AnonPipe;
1213
use crate::sys::unsupported;
13-
use crate::sys_common::process::{CommandEnv, CommandEnvs};
1414
use crate::{fmt, io};
1515

1616
////////////////////////////////////////////////////////////////////////////////
@@ -121,63 +121,63 @@ impl Command {
121121
Stdio::Inherit => Ok(None),
122122
}
123123
}
124+
}
124125

125-
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
126-
let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?;
127-
128-
// UEFI adds the bin name by default
129-
if !self.args.is_empty() {
130-
let args = uefi_command_internal::create_args(&self.prog, &self.args);
131-
cmd.set_args(args);
132-
}
133-
134-
// Setup Stdout
135-
let stdout = self.stdout.unwrap_or(Stdio::MakePipe);
136-
let stdout = Self::create_pipe(stdout)?;
137-
if let Some(con) = stdout {
138-
cmd.stdout_init(con)
139-
} else {
140-
cmd.stdout_inherit()
141-
};
142-
143-
// Setup Stderr
144-
let stderr = self.stderr.unwrap_or(Stdio::MakePipe);
145-
let stderr = Self::create_pipe(stderr)?;
146-
if let Some(con) = stderr {
147-
cmd.stderr_init(con)
148-
} else {
149-
cmd.stderr_inherit()
150-
};
151-
152-
let env = env_changes(&self.env);
153-
154-
// Set any new vars
155-
if let Some(e) = &env {
156-
for (k, (_, v)) in e {
157-
match v {
158-
Some(v) => unsafe { crate::env::set_var(k, v) },
159-
None => unsafe { crate::env::remove_var(k) },
160-
}
126+
pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
127+
let mut cmd = uefi_command_internal::Image::load_image(&command.prog)?;
128+
129+
// UEFI adds the bin name by default
130+
if !command.args.is_empty() {
131+
let args = uefi_command_internal::create_args(&command.prog, &command.args);
132+
cmd.set_args(args);
133+
}
134+
135+
// Setup Stdout
136+
let stdout = command.stdout.unwrap_or(Stdio::MakePipe);
137+
let stdout = Command::create_pipe(stdout)?;
138+
if let Some(con) = stdout {
139+
cmd.stdout_init(con)
140+
} else {
141+
cmd.stdout_inherit()
142+
};
143+
144+
// Setup Stderr
145+
let stderr = command.stderr.unwrap_or(Stdio::MakePipe);
146+
let stderr = Command::create_pipe(stderr)?;
147+
if let Some(con) = stderr {
148+
cmd.stderr_init(con)
149+
} else {
150+
cmd.stderr_inherit()
151+
};
152+
153+
let env = env_changes(&command.env);
154+
155+
// Set any new vars
156+
if let Some(e) = &env {
157+
for (k, (_, v)) in e {
158+
match v {
159+
Some(v) => unsafe { crate::env::set_var(k, v) },
160+
None => unsafe { crate::env::remove_var(k) },
161161
}
162162
}
163+
}
163164

164-
let stat = cmd.start_image()?;
165+
let stat = cmd.start_image()?;
165166

166-
// Rollback any env changes
167-
if let Some(e) = env {
168-
for (k, (v, _)) in e {
169-
match v {
170-
Some(v) => unsafe { crate::env::set_var(k, v) },
171-
None => unsafe { crate::env::remove_var(k) },
172-
}
167+
// Rollback any env changes
168+
if let Some(e) = env {
169+
for (k, (v, _)) in e {
170+
match v {
171+
Some(v) => unsafe { crate::env::set_var(k, v) },
172+
None => unsafe { crate::env::remove_var(k) },
173173
}
174174
}
175+
}
175176

176-
let stdout = cmd.stdout()?;
177-
let stderr = cmd.stderr()?;
177+
let stdout = cmd.stdout()?;
178+
let stderr = cmd.stderr()?;
178179

179-
Ok((ExitStatus(stat), stdout, stderr))
180-
}
180+
Ok((ExitStatus(stat), stdout, stderr))
181181
}
182182

183183
impl From<AnonPipe> for Stdio {

library/std/src/sys/process/unix/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::sys::fs::File;
1212
#[cfg(not(target_os = "fuchsia"))]
1313
use crate::sys::fs::OpenOptions;
1414
use crate::sys::pipe::{self, AnonPipe};
15-
use crate::sys_common::process::{CommandEnv, CommandEnvs};
15+
use crate::sys::process::env::{CommandEnv, CommandEnvs};
1616
use crate::sys_common::{FromInner, IntoInner};
1717
use crate::{fmt, io, ptr};
1818

library/std/src/sys/process/unix/fuchsia.rs

-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ impl Command {
3131
Ok((Process { handle: Handle::new(process_handle) }, ours))
3232
}
3333

34-
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
35-
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
36-
crate::sys_common::process::wait_with_output(proc, pipes)
37-
}
38-
3934
pub fn exec(&mut self, default: Stdio) -> io::Error {
4035
if self.saw_nul() {
4136
return io::const_error!(

library/std/src/sys/process/unix/unix.rs

-5
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,6 @@ impl Command {
162162
}
163163
}
164164

165-
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
166-
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
167-
crate::sys_common::process::wait_with_output(proc, pipes)
168-
}
169-
170165
// WatchOS and TVOS headers mark the `fork`/`exec*` functions with
171166
// `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, and indicate that the
172167
// `posix_spawn*` functions should be used instead. It isn't entirely clear

0 commit comments

Comments
 (0)