Skip to content

Commit b7294e1

Browse files
committed
auto merge of #6433 : Dretch/rust/run-refactor, r=thestinger
...mentioned in #2625. This change makes the module more oriented around Process values instead of having to deal with process ids directly. Apart from issues mentioned in #2625, other changes include: - Changing the naming to be more consistent - Process/process is now used instead of a mixture of Program/program and Process/process. - More docs/tests. Some io/scheduler related issues remain (mentioned in #2625). I am not sure how best to address these.
2 parents d577eaf + 04a3935 commit b7294e1

File tree

12 files changed

+695
-483
lines changed

12 files changed

+695
-483
lines changed

src/compiletest/procsrv.rs

+16-69
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
use core::prelude::*;
1212

13-
use core::libc::c_int;
14-
use core::run::spawn_process;
1513
use core::run;
1614

1715
#[cfg(target_os = "win32")]
@@ -38,86 +36,35 @@ fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] {
3836
#[cfg(target_os = "macos")]
3937
#[cfg(target_os = "freebsd")]
4038
fn target_env(_lib_path: &str, _prog: &str) -> ~[(~str,~str)] {
41-
~[]
39+
os::env()
4240
}
4341

4442
pub struct Result {status: int, out: ~str, err: ~str}
4543

46-
// FIXME (#2659): This code is duplicated in core::run::program_output
4744
pub fn run(lib_path: &str,
4845
prog: &str,
4946
args: &[~str],
5047
env: ~[(~str, ~str)],
5148
input: Option<~str>) -> Result {
52-
let pipe_in = os::pipe();
53-
let pipe_out = os::pipe();
54-
let pipe_err = os::pipe();
55-
let pid = spawn_process(prog, args,
56-
&Some(env + target_env(lib_path, prog)),
57-
&None, pipe_in.in, pipe_out.out, pipe_err.out);
58-
59-
os::close(pipe_in.in);
60-
os::close(pipe_out.out);
61-
os::close(pipe_err.out);
62-
if pid == -1i32 {
63-
os::close(pipe_in.out);
64-
os::close(pipe_out.in);
65-
os::close(pipe_err.in);
66-
fail!();
67-
}
6849

50+
let env = env + target_env(lib_path, prog);
51+
let mut proc = run::Process::new(prog, args, run::ProcessOptions {
52+
env: Some(env.slice(0, env.len())),
53+
dir: None,
54+
in_fd: None,
55+
out_fd: None,
56+
err_fd: None
57+
});
6958

70-
writeclose(pipe_in.out, input);
71-
let p = comm::PortSet::new();
72-
let ch = p.chan();
73-
do task::spawn_sched(task::SingleThreaded) || {
74-
let errput = readclose(pipe_err.in);
75-
ch.send((2, errput));
59+
for input.each |input| {
60+
proc.input().write_str(*input);
7661
}
77-
let ch = p.chan();
78-
do task::spawn_sched(task::SingleThreaded) || {
79-
let output = readclose(pipe_out.in);
80-
ch.send((1, output));
81-
}
82-
let status = run::waitpid(pid);
83-
let mut errs = ~"";
84-
let mut outs = ~"";
85-
let mut count = 2;
86-
while count > 0 {
87-
match p.recv() {
88-
(1, s) => {
89-
outs = s;
90-
}
91-
(2, s) => {
92-
errs = s;
93-
}
94-
_ => { fail!() }
95-
};
96-
count -= 1;
97-
};
98-
return Result {status: status, out: outs, err: errs};
99-
}
62+
let output = proc.finish_with_output();
10063

101-
fn writeclose(fd: c_int, s: Option<~str>) {
102-
if s.is_some() {
103-
let writer = io::fd_writer(fd, false);
104-
writer.write_str(s.get());
64+
Result {
65+
status: output.status,
66+
out: str::from_bytes(output.output),
67+
err: str::from_bytes(output.error)
10568
}
106-
107-
os::close(fd);
10869
}
10970

110-
fn readclose(fd: c_int) -> ~str {
111-
unsafe {
112-
// Copied from run::program_output
113-
let file = os::fdopen(fd);
114-
let reader = io::FILE_reader(file, false);
115-
let mut buf = ~"";
116-
while !reader.eof() {
117-
let bytes = reader.read_bytes(4096u);
118-
str::push_str(&mut buf, str::from_bytes(bytes));
119-
}
120-
os::fclose(file);
121-
return buf;
122-
}
123-
}

src/libextra/workcache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ fn test() {
415415
prep.declare_input("file", pth.to_str(), digest_file(&pth));
416416
do prep.exec |_exe| {
417417
let out = Path("foo.o");
418-
run::run_program("gcc", [~"foo.c", ~"-o", out.to_str()]);
418+
run::process_status("gcc", [~"foo.c", ~"-o", out.to_str()]);
419419
out.to_str()
420420
}
421421
};

src/libfuzzer/fuzzer.rc

+19-19
Original file line numberDiff line numberDiff line change
@@ -412,20 +412,20 @@ pub fn check_whole_compiler(code: &str,
412412
pub fn removeIfExists(filename: &Path) {
413413
// So sketchy!
414414
assert!(!contains(filename.to_str(), " "));
415-
run::program_output("bash", [~"-c", ~"rm " + filename.to_str()]);
415+
run::process_status("bash", [~"-c", ~"rm " + filename.to_str()]);
416416
}
417417

418418
pub fn removeDirIfExists(filename: &Path) {
419419
// So sketchy!
420420
assert!(!contains(filename.to_str(), " "));
421-
run::program_output("bash", [~"-c", ~"rm -r " + filename.to_str()]);
421+
run::process_status("bash", [~"-c", ~"rm -r " + filename.to_str()]);
422422
}
423423

424424
pub fn check_running(exe_filename: &Path) -> happiness {
425-
let p = run::program_output(
425+
let p = run::process_output(
426426
"/Users/jruderman/scripts/timed_run_rust_program.py",
427427
[exe_filename.to_str()]);
428-
let comb = p.out + ~"\n" + p.err;
428+
let comb = str::from_bytes(p.output) + ~"\n" + str::from_bytes(p.error);
429429
if str::len(comb) > 1u {
430430
error!("comb comb comb: %?", comb);
431431
}
@@ -461,33 +461,35 @@ pub fn check_running(exe_filename: &Path) -> happiness {
461461
}
462462

463463
pub fn check_compiling(filename: &Path) -> happiness {
464-
let p = run::program_output(
465-
"/Users/jruderman/code/rust/build/x86_64-apple-darwin/\
466-
stage1/bin/rustc",
464+
let p = run::process_output(
465+
"/Users/jruderman/code/rust/build/x86_64-apple-darwin/stage1/bin/rustc",
467466
[filename.to_str()]);
468467

468+
let out = str::from_bytes(p.output);
469+
let err = str::from_bytes(p.error);
470+
469471
//error!("Status: %d", p.status);
470472
if p.status == 0 {
471473
passed
472-
} else if p.err != ~"" {
473-
if contains(p.err, "error:") {
474+
} else if !err.is_empty() {
475+
if err.contains("error:") {
474476
cleanly_rejected(~"rejected with span_error")
475477
} else {
476-
error!("Stderr: %?", p.err);
478+
error!("Stderr: %?", err);
477479
failed(~"Unfamiliar error message")
478480
}
479-
} else if contains(p.out, "Assertion") && contains(p.out, "failed") {
480-
error!("Stdout: %?", p.out);
481+
} else if out.contains("Assertion") && out.contains("failed") {
482+
error!("Stdout: %?", out);
481483
failed(~"Looks like an llvm assertion failure")
482-
} else if contains(p.out, "internal compiler error unimplemented") {
484+
} else if out.contains("internal compiler error unimplemented") {
483485
known_bug(~"Something unimplemented")
484-
} else if contains(p.out, "internal compiler error") {
485-
error!("Stdout: %?", p.out);
486+
} else if out.contains("internal compiler error") {
487+
error!("Stdout: %?", out);
486488
failed(~"internal compiler error")
487489

488490
} else {
489491
error!("%?", p.status);
490-
error!("!Stdout: %?", p.out);
492+
error!("!Stdout: %?", out);
491493
failed(~"What happened?")
492494
}
493495
}
@@ -608,9 +610,7 @@ pub fn check_roundtrip_convergence(code: @~str, maxIters: uint) {
608610
error!("Did not converge after %u iterations!", i);
609611
write_file(&Path("round-trip-a.rs"), *oldv);
610612
write_file(&Path("round-trip-b.rs"), *newv);
611-
run::run_program("diff",
612-
[~"-w", ~"-u", ~"round-trip-a.rs",
613-
~"round-trip-b.rs"]);
613+
run::process_status("diff", [~"-w", ~"-u", ~"round-trip-a.rs", ~"round-trip-b.rs"]);
614614
fail!("Mismatch");
615615
}
616616
}

src/librust/rust.rc

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ fn cmd_test(args: &[~str]) -> ValidUsage {
163163
let test_exec = Path(filename).filestem().unwrap() + "test~";
164164
invoke("rustc", &[~"--test", filename.to_owned(),
165165
~"-o", test_exec.to_owned()], rustc::main);
166-
let exit_code = run::run_program(~"./" + test_exec, []);
166+
let exit_code = run::process_status(~"./" + test_exec, []);
167167
Valid(exit_code)
168168
}
169169
_ => Invalid
@@ -176,7 +176,7 @@ fn cmd_run(args: &[~str]) -> ValidUsage {
176176
let exec = Path(filename).filestem().unwrap() + "~";
177177
invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
178178
rustc::main);
179-
let exit_code = run::run_program(~"./"+exec, prog_args);
179+
let exit_code = run::process_status(~"./"+exec, prog_args);
180180
Valid(exit_code)
181181
}
182182
_ => Invalid

src/librustc/back/link.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -403,14 +403,14 @@ pub mod write {
403403
cc_args.push(object.to_str());
404404
cc_args.push(assembly.to_str());
405405

406-
let prog = run::program_output(cc_prog, cc_args);
406+
let prog = run::process_output(cc_prog, cc_args);
407407

408408
if prog.status != 0 {
409409
sess.err(fmt!("building with `%s` failed with code %d",
410410
cc_prog, prog.status));
411411
sess.note(fmt!("%s arguments: %s",
412412
cc_prog, str::connect(cc_args, " ")));
413-
sess.note(prog.err + prog.out);
413+
sess.note(str::from_bytes(prog.error + prog.output));
414414
sess.abort_if_errors();
415415
}
416416
}
@@ -817,19 +817,19 @@ pub fn link_binary(sess: Session,
817817
let cc_args = link_args(sess, obj_filename, out_filename, lm);
818818
debug!("%s link args: %s", cc_prog, str::connect(cc_args, " "));
819819
// We run 'cc' here
820-
let prog = run::program_output(cc_prog, cc_args);
820+
let prog = run::process_output(cc_prog, cc_args);
821821
if 0 != prog.status {
822822
sess.err(fmt!("linking with `%s` failed with code %d",
823823
cc_prog, prog.status));
824824
sess.note(fmt!("%s arguments: %s",
825825
cc_prog, str::connect(cc_args, " ")));
826-
sess.note(prog.err + prog.out);
826+
sess.note(str::from_bytes(prog.error + prog.output));
827827
sess.abort_if_errors();
828828
}
829829

830830
// Clean up on Darwin
831831
if sess.targ_cfg.os == session::os_macos {
832-
run::run_program("dsymutil", [output.to_str()]);
832+
run::process_status("dsymutil", [output.to_str()]);
833833
}
834834

835835
// Remove the temporary object file if we aren't saving temps

src/librustdoc/config.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::prelude::*;
1212

1313
use core::cell::Cell;
1414
use core::run;
15-
use core::run::ProgramOutput;
15+
use core::run::ProcessOutput;
1616
use core::result::Result;
1717
use extra::getopts;
1818

@@ -89,35 +89,35 @@ pub fn default_config(input_crate: &Path) -> Config {
8989
}
9090
}
9191

92-
type Process = ~fn((&str), (&[~str])) -> ProgramOutput;
92+
type Process = ~fn((&str), (&[~str])) -> ProcessOutput;
9393

94-
pub fn mock_program_output(_prog: &str, _args: &[~str]) -> ProgramOutput {
95-
ProgramOutput {
94+
pub fn mock_process_output(_prog: &str, _args: &[~str]) -> ProcessOutput {
95+
ProcessOutput {
9696
status: 0,
97-
out: ~"",
98-
err: ~""
97+
output: ~[],
98+
error: ~[]
9999
}
100100
}
101101

102-
pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput {
103-
run::program_output(prog, args)
102+
pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
103+
run::process_output(prog, args)
104104
}
105105

106106
pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
107-
parse_config_(args, program_output)
107+
parse_config_(args, process_output)
108108
}
109109

110110
pub fn parse_config_(
111111
args: &[~str],
112-
program_output: Process
112+
process_output: Process
113113
) -> Result<Config, ~str> {
114114
let args = args.tail();
115115
let opts = vec::unzip(opts()).first();
116116
match getopts::getopts(args, opts) {
117117
Ok(matches) => {
118118
if matches.free.len() == 1 {
119119
let input_crate = Path(*matches.free.head());
120-
config_from_opts(&input_crate, &matches, program_output)
120+
config_from_opts(&input_crate, &matches, process_output)
121121
} else if matches.free.is_empty() {
122122
Err(~"no crates specified")
123123
} else {
@@ -133,7 +133,7 @@ pub fn parse_config_(
133133
fn config_from_opts(
134134
input_crate: &Path,
135135
matches: &getopts::Matches,
136-
program_output: Process
136+
process_output: Process
137137
) -> Result<Config, ~str> {
138138

139139
let config = default_config(input_crate);
@@ -175,11 +175,11 @@ fn config_from_opts(
175175
}
176176
}
177177
};
178-
let program_output = Cell(program_output);
178+
let process_output = Cell(process_output);
179179
let result = do result::chain(result) |config| {
180180
let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
181181
let pandoc_cmd = maybe_find_pandoc(
182-
&config, pandoc_cmd, program_output.take());
182+
&config, pandoc_cmd, process_output.take());
183183
do result::chain(pandoc_cmd) |pandoc_cmd| {
184184
result::Ok(Config {
185185
pandoc_cmd: pandoc_cmd,
@@ -209,7 +209,7 @@ fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
209209
pub fn maybe_find_pandoc(
210210
config: &Config,
211211
maybe_pandoc_cmd: Option<~str>,
212-
program_output: Process
212+
process_output: Process
213213
) -> Result<Option<~str>, ~str> {
214214
if config.output_format != PandocHtml {
215215
return result::Ok(maybe_pandoc_cmd);
@@ -228,7 +228,7 @@ pub fn maybe_find_pandoc(
228228
};
229229

230230
let pandoc = do vec::find(possible_pandocs) |pandoc| {
231-
let output = program_output(*pandoc, [~"--version"]);
231+
let output = process_output(*pandoc, [~"--version"]);
232232
debug!("testing pandoc cmd %s: %?", *pandoc, output);
233233
output.status == 0
234234
};
@@ -244,10 +244,10 @@ pub fn maybe_find_pandoc(
244244
mod test {
245245
use core::prelude::*;
246246
use config::*;
247-
use core::run::ProgramOutput;
247+
use core::run::ProcessOutput;
248248

249249
fn parse_config(args: &[~str]) -> Result<Config, ~str> {
250-
parse_config_(args, mock_program_output)
250+
parse_config_(args, mock_process_output)
251251
}
252252

253253
#[test]
@@ -256,10 +256,10 @@ mod test {
256256
output_format: PandocHtml,
257257
.. default_config(&Path("test"))
258258
};
259-
let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
260-
ProgramOutput { status: 0, out: ~"pandoc 1.8.2.1", err: ~"" }
259+
let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
260+
ProcessOutput { status: 0, output: "pandoc 1.8.2.1".to_bytes(), error: ~[] }
261261
};
262-
let result = maybe_find_pandoc(&config, None, mock_program_output);
262+
let result = maybe_find_pandoc(&config, None, mock_process_output);
263263
assert!(result == result::Ok(Some(~"pandoc")));
264264
}
265265
@@ -269,10 +269,10 @@ mod test {
269269
output_format: PandocHtml,
270270
.. default_config(&Path("test"))
271271
};
272-
let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
273-
ProgramOutput { status: 1, out: ~"", err: ~"" }
272+
let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
273+
ProcessOutput { status: 1, output: ~[], error: ~[] }
274274
};
275-
let result = maybe_find_pandoc(&config, None, mock_program_output);
275+
let result = maybe_find_pandoc(&config, None, mock_process_output);
276276
assert!(result == result::Err(~"couldn't find pandoc"));
277277
}
278278

0 commit comments

Comments
 (0)