Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix panic if stdout disappears #1622

Closed
wants to merge 1 commit into from
Closed

Conversation

NickeZ
Copy link
Contributor

@NickeZ NickeZ commented Jan 23, 2019

Fixes #1621

Copy link
Contributor

@kinnison kinnison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure I'm comfortable with the number of times we have to acquire term2::stdout but I think I understand why it'd have to be this way.

But I don't like how we're swallowing the errors from writeln! I'd rather we just early jump out and allow things to shut down more quickly.

let mut t = term2::stdout();
for it in installed_toolchains {
if default_name == it {
let _ = writeln!(t, "{} (default)", it);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we be using ? rather than ignoring the error returns from writeln!() since this is just informational and so the jump out shouldn't affect matters?

} else {
println!("{}", t);
let _ = writeln!(t, "{}", it);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

}
}
if show_headers {
println!("")
};
let _ = writeln!(t, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And again.

println!(
let mut t = term2::stdout();
for at in active_targets {
let _ = writeln!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And once more

.target
.as_ref()
.expect("rust-std should have a target")
);
}
if show_headers {
println!("")
};
let _ = writeln!(t, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too?

println!("{} (default)", toolchain.name());
println!("{}", common::rustc_version(toolchain));
let _ = writeln!(t, "{} (default)", toolchain.name());
let _ = writeln!(t, "{}", common::rustc_version(toolchain));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

}
None => {
println!("no active toolchain");
let _ = writeln!(t, "no active toolchain");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

}
},
Err(err) => {
if let Some(cause) = err.source() {
println!("(error: {}, {})", err, cause);
let _ = writeln!(t, "(error: {}, {})", err, cause);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too

} else {
println!("(error: {})", err);
let _ = writeln!(t, "(error: {})", err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

}
}
}

if show_headers {
println!("")
};
let _ = writeln!(t, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final one.

@NickeZ
Copy link
Contributor Author

NickeZ commented Jan 30, 2019

Thanks for the review. Is it better to only acquire stout once and to propagate it into for example "print_header"?

@dwijnand
Copy link
Member

What are our chances of being able to simulate this failure in a test? I agree that #1621 is a bug and should be fixed, but I'd prefer to find the minimal solution that swallows the least errors and panics as much as it used to.

@NickeZ
Copy link
Contributor Author

NickeZ commented Jan 30, 2019

Another option is to register a handler to sigpipe and exit gracefully. I guess that is a straightforward solution if rustup already handles signals.

Rust registers the "ignore" signal handler for sigpipe by default:

https://github.com/rust-lang/rust/blob/79d8a0fcefa5134db2a94739b1d18daa01fc6e9f/src/libstd/sys/unix/mod.rs#L63-L81

On the other hand, rust std ignores all other reasonable stdout IO errors such as stdout being closed or read-only. So I'm not sure what other kinds of errors you would like to propagate from write!().

https://github.com/rust-lang/rust/blob/01af12008d63a64446a86d995e772f8a539a4202/src/libstd/io/stdio.rs#L88-L118

@kinnison
Copy link
Contributor

kinnison commented Jan 30, 2019

Mostly I just find let _ = writeln!(...); much less pleasant to see in code than writeln!(...)?; but I'm not going to block things if others disagree with me. I'm still developing my particular Rust aesthetic.

@NickeZ
Copy link
Contributor Author

NickeZ commented Jan 30, 2019

What are our chances of being able to simulate this failure in a test?

The easiest reproducer is below. I don't know if that qualiefies as a "simulation of this failure".

rustup show | head -1

Actually both the current behavior and my PR is the wrong expected behavior. Current behavior exits with error code != 0, and with my PR rustup continues to run even though we technically have received SIGPIPE and should exit asap.

Would you like me to propagate the error all the way up to main and there handle it appropriately? Which is die silently with error code 0.

@kinnison
Copy link
Contributor

kinnison commented Feb 4, 2019

I think that #1630 is a better version of this. and I'd suggest closing this PR in favour of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants