Skip to content

Commit cb7cff1

Browse files
committed
Auto merge of #8236 - ehuss:no-panic-output, r=alexcrichton
Ignore broken console output in some situations. If stdout or stderr is closed while Cargo is running, Cargo would panic in some situations (usually with EPIPE). For example, `cargo install --list | grep -q cargo-fuzz`, where `grep` will close stdout once it gets a match. This changes it so that Cargo will ignore output errors in most situations. Failure to output a regular build message still results in an error, which follows the behavior of some tools like `make`. All output, including stdout, now goes through `Shell`. Closes #5234
2 parents 55869de + 5a096da commit cb7cff1

29 files changed

+400
-149
lines changed

src/bin/cargo/cli.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use cargo::core::features;
2-
use cargo::{self, CliResult, Config};
2+
use cargo::{self, drop_print, drop_println, CliResult, Config};
33
use clap::{AppSettings, Arg, ArgMatches};
44

55
use super::commands;
@@ -25,7 +25,8 @@ pub fn main(config: &mut Config) -> CliResult {
2525
};
2626

2727
if args.value_of("unstable-features") == Some("help") {
28-
println!(
28+
drop_println!(
29+
config,
2930
"
3031
Available unstable (nightly-only) flags:
3132
@@ -40,15 +41,17 @@ Available unstable (nightly-only) flags:
4041
Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
4142
);
4243
if !features::nightly_features_allowed() {
43-
println!(
44+
drop_println!(
45+
config,
4446
"\nUnstable flags are only available on the nightly channel \
4547
of Cargo, but this is the `{}` channel.\n\
4648
{}",
4749
features::channel(),
4850
features::SEE_CHANNELS
4951
);
5052
}
51-
println!(
53+
drop_println!(
54+
config,
5255
"\nSee https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \
5356
for more information about these flags."
5457
);
@@ -58,7 +61,7 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
5861
let is_verbose = args.occurrences_of("verbose") > 0;
5962
if args.is_present("version") {
6063
let version = get_version_string(is_verbose);
61-
print!("{}", version);
64+
drop_print!(config, "{}", version);
6265
return Ok(());
6366
}
6467

@@ -69,19 +72,19 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
6972
}
7073

7174
if args.is_present("list") {
72-
println!("Installed Commands:");
75+
drop_println!(config, "Installed Commands:");
7376
for command in list_commands(config) {
7477
match command {
7578
CommandInfo::BuiltIn { name, about } => {
7679
let summary = about.unwrap_or_default();
7780
let summary = summary.lines().next().unwrap_or(&summary); // display only the first line
78-
println!(" {:<20} {}", name, summary)
81+
drop_println!(config, " {:<20} {}", name, summary);
7982
}
8083
CommandInfo::External { name, path } => {
8184
if is_verbose {
82-
println!(" {:<20} {}", name, path.display())
85+
drop_println!(config, " {:<20} {}", name, path.display());
8386
} else {
84-
println!(" {}", name)
87+
drop_println!(config, " {}", name);
8588
}
8689
}
8790
}

src/bin/cargo/commands/locate_project.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use crate::command_prelude::*;
2-
3-
use cargo::print_json;
42
use serde::Serialize;
53

64
pub fn cli() -> App {
@@ -30,6 +28,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
3028

3129
let location = ProjectLocation { root };
3230

33-
print_json(&location);
31+
config.shell().print_json(&location);
3432
Ok(())
3533
}

src/bin/cargo/commands/metadata.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use crate::command_prelude::*;
2-
32
use cargo::ops::{self, OutputMetadataOptions};
4-
use cargo::print_json;
53

64
pub fn cli() -> App {
75
subcommand("metadata")
@@ -54,6 +52,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
5452
};
5553

5654
let result = ops::output_metadata(&ws, &options)?;
57-
print_json(&result);
55+
config.shell().print_json(&result);
5856
Ok(())
5957
}

src/bin/cargo/commands/pkgid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
3737
let ws = args.workspace(config)?;
3838
let spec = args.value_of("spec").or_else(|| args.value_of("package"));
3939
let spec = ops::pkgid(&ws, spec)?;
40-
println!("{}", spec);
40+
cargo::drop_println!(config, "{}", spec);
4141
Ok(())
4242
}

src/bin/cargo/commands/read_manifest.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use crate::command_prelude::*;
22

3-
use cargo::print_json;
4-
53
pub fn cli() -> App {
64
subcommand("read-manifest")
75
.about(
@@ -17,6 +15,6 @@ Deprecated, use `cargo metadata --no-deps` instead.\
1715

1816
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
1917
let ws = args.workspace(config)?;
20-
print_json(&ws.current()?);
18+
config.shell().print_json(&ws.current()?);
2119
Ok(())
2220
}

src/bin/cargo/commands/tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
102102
if args.is_present("version") {
103103
let verbose = args.occurrences_of("verbose") > 0;
104104
let version = cli::get_version_string(verbose);
105-
print!("{}", version);
105+
cargo::drop_print!(config, "{}", version);
106106
return Ok(());
107107
}
108108
let prefix = if args.is_present("no-indent") {

src/bin/cargo/commands/verify_project.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use crate::command_prelude::*;
33
use std::collections::HashMap;
44
use std::process;
55

6-
use cargo::print_json;
7-
86
pub fn cli() -> App {
97
subcommand("verify-project")
108
.about("Check correctness of crate manifest")
@@ -13,19 +11,15 @@ pub fn cli() -> App {
1311
}
1412

1513
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
16-
fn fail(reason: &str, value: &str) -> ! {
14+
if let Err(e) = args.workspace(config) {
1715
let mut h = HashMap::new();
18-
h.insert(reason.to_string(), value.to_string());
19-
print_json(&h);
16+
h.insert("invalid".to_string(), e.to_string());
17+
config.shell().print_json(&h);
2018
process::exit(1)
2119
}
2220

23-
if let Err(e) = args.workspace(config) {
24-
fail("invalid", &e.to_string())
25-
}
26-
2721
let mut h = HashMap::new();
2822
h.insert("success".to_string(), "true".to_string());
29-
print_json(&h);
23+
config.shell().print_json(&h);
3024
Ok(())
3125
}

src/bin/cargo/commands/version.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
use crate::command_prelude::*;
2-
31
use crate::cli;
2+
use crate::command_prelude::*;
43

54
pub fn cli() -> App {
65
subcommand("version")
76
.about("Show version information")
87
.arg(opt("quiet", "No output printed to stdout").short("q"))
98
}
109

11-
pub fn exec(_config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
10+
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
1211
let verbose = args.occurrences_of("verbose") > 0;
1312
let version = cli::get_version_string(verbose);
14-
print!("{}", version);
13+
cargo::drop_print!(config, "{}", version);
1514
Ok(())
1615
}

src/cargo/core/compiler/build_plan.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use serde::Serialize;
1414
use super::context::OutputFile;
1515
use super::{CompileKind, CompileMode, Context, Unit};
1616
use crate::core::TargetKind;
17-
use crate::util::{internal, CargoResult, ProcessBuilder};
17+
use crate::util::{internal, CargoResult, Config, ProcessBuilder};
1818

1919
#[derive(Debug, Serialize)]
2020
struct Invocation {
@@ -146,9 +146,9 @@ impl BuildPlan {
146146
self.plan.inputs = inputs;
147147
}
148148

149-
pub fn output_plan(self) {
149+
pub fn output_plan(self, config: &Config) {
150150
let encoded = serde_json::to_string(&self.plan).unwrap();
151-
println!("{}", encoded);
151+
crate::drop_println!(config, "{}", encoded);
152152
}
153153
}
154154

src/cargo/core/compiler/context/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
157157

158158
if build_plan {
159159
plan.set_inputs(self.build_plan_inputs()?);
160-
plan.output_plan();
160+
plan.output_plan(self.bcx.config);
161161
}
162162

163163
// Collect the result of the build into `self.compilation`.

0 commit comments

Comments
 (0)