Skip to content

Commit a2fbdd3

Browse files
committed
implement std::process::Command::args_clear()
see #87379 Only unix implementation yet.
1 parent 11fb21f commit a2fbdd3

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

library/std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@
306306
#![feature(min_specialization)]
307307
#![feature(mixed_integer_ops)]
308308
#![feature(must_not_suspend)]
309+
#![feature(mutate_command_args)]
309310
#![feature(needs_panic_runtime)]
310311
#![feature(negative_impls)]
311312
#![feature(never_type)]

library/std/src/process.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,38 @@ impl Command {
648648
self
649649
}
650650

651+
/// Clears the argument array.
652+
///
653+
/// When one wants to restart a Command again with different
654+
/// arguments the argument list can to be cleared first.
655+
///
656+
/// # Examples
657+
///
658+
/// Basic usage:
659+
///
660+
/// ```no_run
661+
/// #![feature(mutate_command_args)]
662+
/// use std::process::Command;
663+
///
664+
/// let mut lsdir = Command::new("ls");
665+
///
666+
/// lsdir
667+
/// .arg("target")
668+
/// .spawn()
669+
/// .expect("ls command failed to start");
670+
///
671+
/// lsdir
672+
/// .args_clear()
673+
/// .arg("tests")
674+
/// .spawn()
675+
/// .expect("ls command failed to start");
676+
/// ```
677+
#[unstable(feature = "mutate_command_args", issue = "87379")]
678+
pub fn args_clear(&mut self) -> &mut Command {
679+
self.inner.args_clear();
680+
self
681+
}
682+
651683
/// Inserts or updates an environment variable mapping.
652684
///
653685
/// Note that environment variable names are case-insensitive (but case-preserving) on Windows,

library/std/src/process/tests.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,32 @@ fn test_wait_with_output_once() {
211211
assert_eq!(stderr, Vec::new());
212212
}
213213

214+
#[test]
215+
fn test_args_clear() {
216+
let mut prog = Command::new("echo");
217+
218+
if cfg!(target_os = "windows") {
219+
prog.args(&["/C", "echo reset_me"])
220+
} else {
221+
prog.arg("reset_me")
222+
};
223+
224+
prog.args_clear();
225+
226+
if cfg!(target_os = "windows") {
227+
prog.args(&["/C", "echo hello"]);
228+
} else {
229+
prog.arg("hello");
230+
};
231+
232+
let Output { status, stdout, stderr } = prog.output().unwrap();
233+
let output_str = str::from_utf8(&stdout).unwrap();
234+
235+
assert!(status.success());
236+
assert_eq!(output_str.trim().to_string(), "hello");
237+
assert_eq!(stderr, Vec::new());
238+
}
239+
214240
#[cfg(all(unix, not(target_os = "android")))]
215241
pub fn env_cmd() -> Command {
216242
Command::new("env")

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,15 @@ impl Command {
190190
self.args.push(arg);
191191
}
192192

193+
pub fn args_clear(&mut self) {
194+
// resize `argv` to 2 (argv[0] and NULL).
195+
self.argv.0.truncate(2);
196+
self.argv.0[1] = ptr::null();
197+
198+
// drop all excess args.
199+
self.args.truncate(1);
200+
}
201+
193202
pub fn cwd(&mut self, dir: &OsStr) {
194203
self.cwd = Some(os2c(dir, &mut self.saw_nul));
195204
}

0 commit comments

Comments
 (0)