Skip to content

Commit add59bd

Browse files
committed
Propagate io and terminal errors to main
This commit solves the problem where rustup panics when the stdout is a pipe that has been closed. Rustup will now ignore EPIPE on write and instead quit with status code 0.
1 parent 7ff14e4 commit add59bd

File tree

3 files changed

+52
-36
lines changed

3 files changed

+52
-36
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rustup-cli/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ error_chain! {
1818
foreign_links {
1919
Temp(temp::Error);
2020
Io(io::Error);
21+
Term(term::Error);
2122
}
2223

2324
errors {

src/rustup-cli/rustup_mode.rs

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ use std::iter;
1515
use std::path::Path;
1616
use std::process::{self, Command};
1717

18+
fn handle_epipe(res: Result<()>) -> Result<()> {
19+
match res {
20+
Err(Error(ErrorKind::Io(ref err), _)) if err.kind() == std::io::ErrorKind::BrokenPipe => {
21+
Ok(())
22+
}
23+
res => res,
24+
}
25+
}
26+
1827
pub fn main() -> Result<()> {
1928
crate::self_update::cleanup_self_updater()?;
2029

@@ -30,8 +39,8 @@ pub fn main() -> Result<()> {
3039

3140
match matches.subcommand() {
3241
("show", Some(c)) => match c.subcommand() {
33-
("active-toolchain", Some(_)) => show_active_toolchain(cfg)?,
34-
(_, _) => show(cfg)?,
42+
("active-toolchain", Some(_)) => handle_epipe(show_active_toolchain(cfg))?,
43+
(_, _) => handle_epipe(show(cfg))?,
3544
},
3645
("install", Some(m)) => update(cfg, m)?,
3746
("update", Some(m)) => update(cfg, m)?,
@@ -653,11 +662,11 @@ fn show(cfg: &Cfg) -> Result<()> {
653662
// Print host triple
654663
{
655664
let mut t = term2::stdout();
656-
let _ = t.attr(term2::Attr::Bold);
657-
let _ = write!(t, "Default host: ");
658-
let _ = t.reset();
659-
println!("{}", cfg.get_default_host_triple()?);
660-
println!();
665+
t.attr(term2::Attr::Bold)?;
666+
write!(t, "Default host: ")?;
667+
t.reset()?;
668+
writeln!(t, "{}", cfg.get_default_host_triple()?)?;
669+
writeln!(t)?;
661670
}
662671

663672
let ref cwd = utils::current_dir()?;
@@ -698,80 +707,84 @@ fn show(cfg: &Cfg) -> Result<()> {
698707
> 1;
699708

700709
if show_installed_toolchains {
710+
let mut t = term2::stdout();
701711
if show_headers {
702-
print_header("installed toolchains")
712+
print_header(&mut t, "installed toolchains")?;
703713
}
704714
let default_name = cfg.get_default()?;
705-
for t in installed_toolchains {
706-
if default_name == t {
707-
println!("{} (default)", t);
715+
for it in installed_toolchains {
716+
if default_name == it {
717+
writeln!(t, "{} (default)", it)?;
708718
} else {
709-
println!("{}", t);
719+
writeln!(t, "{}", it)?;
710720
}
711721
}
712722
if show_headers {
713-
println!()
723+
writeln!(t)?
714724
};
715725
}
716726

717727
if show_active_targets {
728+
let mut t = term2::stdout();
718729
if show_headers {
719-
print_header("installed targets for active toolchain");
730+
print_header(&mut t, "installed targets for active toolchain")?;
720731
}
721-
for t in active_targets {
722-
println!(
732+
for at in active_targets {
733+
writeln!(
734+
t,
723735
"{}",
724-
t.component
736+
at.component
725737
.target
726738
.as_ref()
727739
.expect("rust-std should have a target")
728-
);
740+
)?;
729741
}
730742
if show_headers {
731-
println!()
743+
writeln!(t)?;
732744
};
733745
}
734746

735747
if show_active_toolchain {
748+
let mut t = term2::stdout();
736749
if show_headers {
737-
print_header("active toolchain")
750+
print_header(&mut t, "active toolchain")?;
738751
}
739752

740753
match active_toolchain {
741754
Ok(atc) => match atc {
742755
Some((ref toolchain, Some(ref reason))) => {
743-
println!("{} ({})", toolchain.name(), reason);
744-
println!("{}", common::rustc_version(toolchain));
756+
writeln!(t, "{} ({})", toolchain.name(), reason)?;
757+
writeln!(t, "{}", common::rustc_version(toolchain))?;
745758
}
746759
Some((ref toolchain, None)) => {
747-
println!("{} (default)", toolchain.name());
748-
println!("{}", common::rustc_version(toolchain));
760+
writeln!(t, "{} (default)", toolchain.name())?;
761+
writeln!(t, "{}", common::rustc_version(toolchain))?;
749762
}
750763
None => {
751-
println!("no active toolchain");
764+
writeln!(t, "no active toolchain")?;
752765
}
753766
},
754767
Err(err) => {
755768
if let Some(cause) = err.source() {
756-
println!("(error: {}, {})", err, cause);
769+
writeln!(t, "(error: {}, {})", err, cause)?;
757770
} else {
758-
println!("(error: {})", err);
771+
writeln!(t, "(error: {})", err)?;
759772
}
760773
}
761774
}
762775

763776
if show_headers {
764-
println!()
765-
};
777+
writeln!(t)?
778+
}
766779
}
767780

768-
fn print_header(s: &str) {
769-
let mut t = term2::stdout();
770-
let _ = t.attr(term2::Attr::Bold);
771-
let _ = writeln!(t, "{}", s);
772-
let _ = writeln!(t, "{}", iter::repeat("-").take(s.len()).collect::<String>());
773-
let _ = writeln!(t, "");
774-
let _ = t.reset();
781+
fn print_header(t: &mut term2::Terminal<std::io::Stdout>, s: &str) -> Result<()> {
782+
t.attr(term2::Attr::Bold)?;
783+
writeln!(t, "{}", s)?;
784+
writeln!(t, "{}", iter::repeat("-").take(s.len()).collect::<String>())?;
785+
writeln!(t)?;
786+
t.reset()?;
787+
Ok(())
775788
}
776789

777790
Ok(())

0 commit comments

Comments
 (0)