Skip to content

Commit 7cd7605

Browse files
authored
Rollup merge of #140393 - joboet:sys_common_process, r=thomcc
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 #117276. Something went wrong with a force push, so I can't reopen #139020. This is unchanged from that PR, apart from a rebase. r? ```@thomcc```
2 parents 42156bd + 5f14568 commit 7cd7605

File tree

12 files changed

+176
-136
lines changed

12 files changed

+176
-136
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

+58-58
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use r_efi::protocols::{simple_text_input, 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
////////////////////////////////////////////////////////////////////////////////
@@ -139,72 +139,72 @@ impl Command {
139139
Stdio::MakePipe => unsupported(),
140140
}
141141
}
142+
}
142143

143-
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
144-
let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?;
145-
146-
// UEFI adds the bin name by default
147-
if !self.args.is_empty() {
148-
let args = uefi_command_internal::create_args(&self.prog, &self.args);
149-
cmd.set_args(args);
150-
}
151-
152-
// Setup Stdout
153-
let stdout = self.stdout.unwrap_or(Stdio::MakePipe);
154-
let stdout = Self::create_pipe(stdout)?;
155-
if let Some(con) = stdout {
156-
cmd.stdout_init(con)
157-
} else {
158-
cmd.stdout_inherit()
159-
};
160-
161-
// Setup Stderr
162-
let stderr = self.stderr.unwrap_or(Stdio::MakePipe);
163-
let stderr = Self::create_pipe(stderr)?;
164-
if let Some(con) = stderr {
165-
cmd.stderr_init(con)
166-
} else {
167-
cmd.stderr_inherit()
168-
};
169-
170-
// Setup Stdin
171-
let stdin = self.stdin.unwrap_or(Stdio::Null);
172-
let stdin = Self::create_stdin(stdin)?;
173-
if let Some(con) = stdin {
174-
cmd.stdin_init(con)
175-
} else {
176-
cmd.stdin_inherit()
177-
};
178-
179-
let env = env_changes(&self.env);
180-
181-
// Set any new vars
182-
if let Some(e) = &env {
183-
for (k, (_, v)) in e {
184-
match v {
185-
Some(v) => unsafe { crate::env::set_var(k, v) },
186-
None => unsafe { crate::env::remove_var(k) },
187-
}
144+
pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
145+
let mut cmd = uefi_command_internal::Image::load_image(&command.prog)?;
146+
147+
// UEFI adds the bin name by default
148+
if !command.args.is_empty() {
149+
let args = uefi_command_internal::create_args(&command.prog, &command.args);
150+
cmd.set_args(args);
151+
}
152+
153+
// Setup Stdout
154+
let stdout = command.stdout.unwrap_or(Stdio::MakePipe);
155+
let stdout = Command::create_pipe(stdout)?;
156+
if let Some(con) = stdout {
157+
cmd.stdout_init(con)
158+
} else {
159+
cmd.stdout_inherit()
160+
};
161+
162+
// Setup Stderr
163+
let stderr = command.stderr.unwrap_or(Stdio::MakePipe);
164+
let stderr = Command::create_pipe(stderr)?;
165+
if let Some(con) = stderr {
166+
cmd.stderr_init(con)
167+
} else {
168+
cmd.stderr_inherit()
169+
};
170+
171+
// Setup Stdin
172+
let stdin = command.stdin.unwrap_or(Stdio::Null);
173+
let stdin = Command::create_stdin(stdin)?;
174+
if let Some(con) = stdin {
175+
cmd.stdin_init(con)
176+
} else {
177+
cmd.stdin_inherit()
178+
};
179+
180+
let env = env_changes(&command.env);
181+
182+
// Set any new vars
183+
if let Some(e) = &env {
184+
for (k, (_, v)) in e {
185+
match v {
186+
Some(v) => unsafe { crate::env::set_var(k, v) },
187+
None => unsafe { crate::env::remove_var(k) },
188188
}
189189
}
190+
}
190191

191-
let stat = cmd.start_image()?;
192+
let stat = cmd.start_image()?;
192193

193-
// Rollback any env changes
194-
if let Some(e) = env {
195-
for (k, (v, _)) in e {
196-
match v {
197-
Some(v) => unsafe { crate::env::set_var(k, v) },
198-
None => unsafe { crate::env::remove_var(k) },
199-
}
194+
// Rollback any env changes
195+
if let Some(e) = env {
196+
for (k, (v, _)) in e {
197+
match v {
198+
Some(v) => unsafe { crate::env::set_var(k, v) },
199+
None => unsafe { crate::env::remove_var(k) },
200200
}
201201
}
202+
}
202203

203-
let stdout = cmd.stdout()?;
204-
let stderr = cmd.stderr()?;
204+
let stdout = cmd.stdout()?;
205+
let stderr = cmd.stderr()?;
205206

206-
Ok((ExitStatus(stat), stdout, stderr))
207-
}
207+
Ok((ExitStatus(stat), stdout, stderr))
208208
}
209209

210210
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!(

0 commit comments

Comments
 (0)