Skip to content

Commit f460d35

Browse files
Rollup merge of rust-lang#124480 - Enselic:on-broken-pipe, r=jieyouxu
Change `SIGPIPE` ui from `#[unix_sigpipe = "..."]` to `-Zon-broken-pipe=...` In the stabilization [attempt](rust-lang#120832) of `#[unix_sigpipe = "sig_dfl"]`, a concern was [raised ](rust-lang#120832 (comment)) related to using a language attribute for the feature: Long term, we want `fn lang_start()` to be definable by any crate, not just libstd. Having a special language attribute in that case becomes awkward. So as a first step towards the next stabilization attempt, this PR changes the `#[unix_sigpipe = "..."]` attribute to a compiler flag `-Zon-broken-pipe=...` to remove that concern, since now the language is not "contaminated" by this feature. Another point was [also raised](rust-lang#120832 (comment)), namely that the ui should not leak **how** it does things, but rather what the **end effect** is. The new flag uses the proposed naming. This is of course something that can be iterated on further before stabilization. Tracking issue: rust-lang#97889
2 parents 0e3b842 + cde0cde commit f460d35

File tree

64 files changed

+203
-372
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+203
-372
lines changed

compiler/rustc/src/main.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(unix_sigpipe)]
2-
31
// A note about jemalloc: rustc uses jemalloc when built for CI and
42
// distribution. The obvious way to do this is with the `#[global_allocator]`
53
// mechanism. However, for complicated reasons (see
@@ -34,7 +32,6 @@
3432
// https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef
3533
// for an example of how to do so.
3634

37-
#[unix_sigpipe = "sig_dfl"]
3835
fn main() {
3936
// See the comment at the top of this file for an explanation of this.
4037
#[cfg(feature = "jemalloc-sys")]

compiler/rustc_feature/src/builtin_attrs.rs

-4
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
396396
),
397397

398398
// Entry point:
399-
gated!(
400-
unix_sigpipe, Normal, template!(NameValueStr: "inherit|sig_ign|sig_dfl"), ErrorFollowing,
401-
EncodeCrossCrate::Yes, experimental!(unix_sigpipe)
402-
),
403399
ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
404400
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
405401
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),

compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,6 @@ declare_features! (
619619
/// Allows creation of instances of a struct by moving fields that have
620620
/// not changed from prior instances of the same struct (RFC #2528)
621621
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
622-
/// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
623-
(unstable, unix_sigpipe, "1.65.0", Some(97889)),
624622
/// Allows unnamed fields of struct and union type
625623
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
626624
/// Allows unsized fn parameters.

compiler/rustc_interface/src/tests.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
2020
use rustc_span::symbol::sym;
2121
use rustc_span::{FileName, SourceFileHashAlgorithm};
2222
use rustc_target::spec::{
23-
CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi,
23+
CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
2424
};
2525
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
2626
use std::collections::{BTreeMap, BTreeSet};
@@ -809,6 +809,7 @@ fn test_unstable_options_tracking_hash() {
809809
tracked!(no_profiler_runtime, true);
810810
tracked!(no_trait_vptr, true);
811811
tracked!(no_unique_section_names, true);
812+
tracked!(on_broken_pipe, OnBrokenPipe::Kill);
812813
tracked!(oom, OomStrategy::Panic);
813814
tracked!(osx_rpath_install_name, true);
814815
tracked!(packed_bundled_libs, true);

compiler/rustc_passes/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -695,9 +695,6 @@ passes_transparent_incompatible =
695695
passes_undefined_naked_function_abi =
696696
Rust ABI is unsupported in naked functions
697697
698-
passes_unix_sigpipe_values =
699-
valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
700-
701698
passes_unknown_external_lang_item =
702699
unknown external lang item: `{$lang_item}`
703700

compiler/rustc_passes/src/check_attr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2523,7 +2523,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
25232523
sym::automatically_derived,
25242524
sym::start,
25252525
sym::rustc_main,
2526-
sym::unix_sigpipe,
25272526
sym::derive,
25282527
sym::test,
25292528
sym::test_case,

compiler/rustc_passes/src/entry.rs

+10-33
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use rustc_span::symbol::sym;
1212
use rustc_span::{Span, Symbol};
1313

1414
use crate::errors::{
15-
AttrOnlyInFunctions, AttrOnlyOnMain, AttrOnlyOnRootMain, ExternMain, MultipleRustcMain,
16-
MultipleStartFunctions, NoMainErr, UnixSigpipeValues,
15+
AttrOnlyInFunctions, ExternMain, MultipleRustcMain, MultipleStartFunctions, NoMainErr,
1716
};
1817

1918
struct EntryContext<'tcx> {
@@ -67,11 +66,7 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
6766
ctxt.tcx.opt_item_name(id.owner_id.to_def_id()),
6867
);
6968
match entry_point_type {
70-
EntryPointType::None => {
71-
if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
72-
ctxt.tcx.dcx().emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
73-
}
74-
}
69+
EntryPointType::None => (),
7570
_ if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) => {
7671
for attr in [sym::start, sym::rustc_main] {
7772
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
@@ -81,9 +76,6 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
8176
}
8277
EntryPointType::MainNamed => (),
8378
EntryPointType::OtherMain => {
84-
if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
85-
ctxt.tcx.dcx().emit_err(AttrOnlyOnRootMain { span, attr: sym::unix_sigpipe });
86-
}
8779
ctxt.non_main_fns.push(ctxt.tcx.def_span(id.owner_id));
8880
}
8981
EntryPointType::RustcMainAttr => {
@@ -98,9 +90,6 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
9890
}
9991
}
10092
EntryPointType::Start => {
101-
if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
102-
ctxt.tcx.dcx().emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
103-
}
10493
if ctxt.start_fn.is_none() {
10594
ctxt.start_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
10695
} else {
@@ -120,7 +109,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
120109
Some((def_id.to_def_id(), EntryFnType::Start))
121110
} else if let Some((local_def_id, _)) = visitor.attr_main_fn {
122111
let def_id = local_def_id.to_def_id();
123-
Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }))
112+
Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
124113
} else {
125114
if let Some(main_def) = tcx.resolutions(()).main_def
126115
&& let Some(def_id) = main_def.opt_fn_def_id()
@@ -133,31 +122,19 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
133122
return None;
134123
}
135124

136-
return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }));
125+
return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }));
137126
}
138127
no_main_err(tcx, visitor);
139128
None
140129
}
141130
}
142131

143-
fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
144-
if let Some(attr) = tcx.get_attr(def_id, sym::unix_sigpipe) {
145-
match (attr.value_str(), attr.meta_item_list()) {
146-
(Some(sym::inherit), None) => sigpipe::INHERIT,
147-
(Some(sym::sig_ign), None) => sigpipe::SIG_IGN,
148-
(Some(sym::sig_dfl), None) => sigpipe::SIG_DFL,
149-
(Some(_), None) => {
150-
tcx.dcx().emit_err(UnixSigpipeValues { span: attr.span });
151-
sigpipe::DEFAULT
152-
}
153-
_ => {
154-
// Keep going so that `fn emit_malformed_attribute()` can print
155-
// an excellent error message
156-
sigpipe::DEFAULT
157-
}
158-
}
159-
} else {
160-
sigpipe::DEFAULT
132+
fn sigpipe(tcx: TyCtxt<'_>) -> u8 {
133+
match tcx.sess.opts.unstable_opts.on_broken_pipe {
134+
rustc_target::spec::OnBrokenPipe::Default => sigpipe::DEFAULT,
135+
rustc_target::spec::OnBrokenPipe::Kill => sigpipe::SIG_DFL,
136+
rustc_target::spec::OnBrokenPipe::Error => sigpipe::SIG_IGN,
137+
rustc_target::spec::OnBrokenPipe::Inherit => sigpipe::INHERIT,
161138
}
162139
}
163140

compiler/rustc_passes/src/errors.rs

-7
Original file line numberDiff line numberDiff line change
@@ -1259,13 +1259,6 @@ pub struct ExternMain {
12591259
pub span: Span,
12601260
}
12611261

1262-
#[derive(Diagnostic)]
1263-
#[diag(passes_unix_sigpipe_values)]
1264-
pub struct UnixSigpipeValues {
1265-
#[primary_span]
1266-
pub span: Span,
1267-
}
1268-
12691262
pub struct NoMainErr {
12701263
pub sp: Span,
12711264
pub crate_name: Symbol,

compiler/rustc_session/src/config.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2909,7 +2909,9 @@ pub(crate) mod dep_tracking {
29092909
use rustc_feature::UnstableFeatures;
29102910
use rustc_span::edition::Edition;
29112911
use rustc_span::RealFileName;
2912-
use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi};
2912+
use rustc_target::spec::{
2913+
CodeModel, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
2914+
};
29132915
use rustc_target::spec::{
29142916
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
29152917
};
@@ -2973,6 +2975,7 @@ pub(crate) mod dep_tracking {
29732975
InstrumentXRay,
29742976
CrateType,
29752977
MergeFunctions,
2978+
OnBrokenPipe,
29762979
PanicStrategy,
29772980
RelroLevel,
29782981
OptLevel,

compiler/rustc_session/src/config/sigpipe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! NOTE: Keep these constants in sync with `library/std/src/sys/pal/unix/mod.rs`!
22
3-
/// The default value if `#[unix_sigpipe]` is not specified. This resolves
3+
/// The default value if `-Zon-broken-pipe=...` is not specified. This resolves
44
/// to `SIG_IGN` in `library/std/src/sys/pal/unix/mod.rs`.
55
///
66
/// Note that `SIG_IGN` has been the Rust default since 2014. See

compiler/rustc_session/src/options.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_span::edition::Edition;
1212
use rustc_span::RealFileName;
1313
use rustc_span::SourceFileHashAlgorithm;
1414
use rustc_target::spec::{
15-
CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet, WasmCAbi,
15+
CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, SanitizerSet, WasmCAbi,
1616
};
1717
use rustc_target::spec::{
1818
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
@@ -378,6 +378,7 @@ mod desc {
378378
pub const parse_time_passes_format: &str = "`text` (default) or `json`";
379379
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
380380
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
381+
pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
381382
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
382383
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
383384
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
@@ -708,6 +709,17 @@ mod parse {
708709
true
709710
}
710711

712+
pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool {
713+
match v {
714+
// OnBrokenPipe::Default can't be explicitly specified
715+
Some("kill") => *slot = OnBrokenPipe::Kill,
716+
Some("error") => *slot = OnBrokenPipe::Error,
717+
Some("inherit") => *slot = OnBrokenPipe::Inherit,
718+
_ => return false,
719+
}
720+
true
721+
}
722+
711723
pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
712724
match v {
713725
Some("panic") => *slot = OomStrategy::Panic,
@@ -1833,6 +1845,8 @@ options! {
18331845
"do not use unique names for text and data sections when -Z function-sections is used"),
18341846
normalize_docs: bool = (false, parse_bool, [TRACKED],
18351847
"normalize associated items in rustdoc when generating documentation"),
1848+
on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED],
1849+
"behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"),
18361850
oom: OomStrategy = (OomStrategy::Abort, parse_oom_strategy, [TRACKED],
18371851
"panic strategy for out-of-memory handling"),
18381852
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],

compiler/rustc_span/src/symbol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1936,7 +1936,6 @@ symbols! {
19361936
unit,
19371937
universal_impl_trait,
19381938
unix,
1939-
unix_sigpipe,
19401939
unlikely,
19411940
unmarked_api,
19421941
unnamed_fields,

compiler/rustc_target/src/spec/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,14 @@ pub enum PanicStrategy {
778778
Abort,
779779
}
780780

781+
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
782+
pub enum OnBrokenPipe {
783+
Default,
784+
Kill,
785+
Error,
786+
Inherit,
787+
}
788+
781789
impl PanicStrategy {
782790
pub fn desc(&self) -> &str {
783791
match *self {

library/std/src/rt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ macro_rules! rtunwrap {
7474
//
7575
// Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to
7676
// `SIG_IGN`. Applications have good reasons to want a different behavior
77-
// though, so there is a `#[unix_sigpipe = "..."]` attribute on `fn main()` that
77+
// though, so there is a `-Zon-broken-pipe` compiler flag that
7878
// can be used to select how `SIGPIPE` shall be setup (if changed at all) before
7979
// `fn main()` is called. See <https://github.com/rust-lang/rust/issues/97889>
8080
// for more info.

library/std/src/sys/pal/unix/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
5555
// want!
5656
//
5757
// Hence, we set SIGPIPE to ignore when the program starts up in order
58-
// to prevent this problem. Add `#[unix_sigpipe = "..."]` above `fn main()` to
59-
// alter this behavior.
58+
// to prevent this problem. Use `-Zon-broken-pipe=...` to alter this
59+
// behavior.
6060
reset_sigpipe(sigpipe);
6161

6262
stack_overflow::init();
@@ -190,7 +190,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
190190
_ => unreachable!(),
191191
};
192192
if sigpipe_attr_specified {
193-
UNIX_SIGPIPE_ATTR_SPECIFIED.store(true, crate::sync::atomic::Ordering::Relaxed);
193+
ON_BROKEN_PIPE_FLAG_USED.store(true, crate::sync::atomic::Ordering::Relaxed);
194194
}
195195
if let Some(handler) = handler {
196196
rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR);
@@ -210,7 +210,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
210210
target_os = "fuchsia",
211211
target_os = "horizon",
212212
)))]
213-
static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool =
213+
static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
214214
crate::sync::atomic::AtomicBool::new(false);
215215

216216
#[cfg(not(any(
@@ -219,8 +219,8 @@ static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool =
219219
target_os = "fuchsia",
220220
target_os = "horizon",
221221
)))]
222-
pub(crate) fn unix_sigpipe_attr_specified() -> bool {
223-
UNIX_SIGPIPE_ATTR_SPECIFIED.load(crate::sync::atomic::Ordering::Relaxed)
222+
pub(crate) fn on_broken_pipe_flag_used() -> bool {
223+
ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
224224
}
225225

226226
// SAFETY: must be called only once during runtime cleanup.

library/std/src/sys/pal/unix/process/process_unix.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -353,11 +353,11 @@ impl Command {
353353
// Inherit the signal mask from the parent rather than resetting it (i.e. do not call
354354
// pthread_sigmask).
355355

356-
// If #[unix_sigpipe] is specified, don't reset SIGPIPE to SIG_DFL.
357-
// If #[unix_sigpipe] is not specified, reset SIGPIPE to SIG_DFL for backward compatibility.
356+
// If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
357+
// If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
358358
//
359-
// #[unix_sigpipe] is an opportunity to change the default here.
360-
if !crate::sys::pal::unix_sigpipe_attr_specified() {
359+
// -Zon-broken-pipe is an opportunity to change the default here.
360+
if !crate::sys::pal::on_broken_pipe_flag_used() {
361361
#[cfg(target_os = "android")] // see issue #88585
362362
{
363363
let mut action: libc::sigaction = mem::zeroed();
@@ -450,7 +450,7 @@ impl Command {
450450
) -> io::Result<Option<Process>> {
451451
use crate::mem::MaybeUninit;
452452
use crate::sys::weak::weak;
453-
use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified};
453+
use crate::sys::{self, cvt_nz, on_broken_pipe_flag_used};
454454

455455
if self.get_gid().is_some()
456456
|| self.get_uid().is_some()
@@ -612,11 +612,11 @@ impl Command {
612612
// Inherit the signal mask from this process rather than resetting it (i.e. do not call
613613
// posix_spawnattr_setsigmask).
614614

615-
// If #[unix_sigpipe] is specified, don't reset SIGPIPE to SIG_DFL.
616-
// If #[unix_sigpipe] is not specified, reset SIGPIPE to SIG_DFL for backward compatibility.
615+
// If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
616+
// If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
617617
//
618-
// #[unix_sigpipe] is an opportunity to change the default here.
619-
if !unix_sigpipe_attr_specified() {
618+
// -Zon-broken-pipe is an opportunity to change the default here.
619+
if !on_broken_pipe_flag_used() {
620620
let mut default_set = MaybeUninit::<libc::sigset_t>::uninit();
621621
cvt(sigemptyset(default_set.as_mut_ptr()))?;
622622
cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGPIPE))?;

src/bootstrap/src/core/build_steps/compile.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,13 @@ pub fn rustc_cargo(
10061006

10071007
cargo.rustdocflag("-Zcrate-attr=warn(rust_2018_idioms)");
10081008

1009+
// If the rustc output is piped to e.g. `head -n1` we want the process to be
1010+
// killed, rather than having an error bubble up and cause a panic.
1011+
// FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it.
1012+
if compiler.stage != 0 {
1013+
cargo.rustflag("-Zon-broken-pipe=kill");
1014+
}
1015+
10091016
// We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary
10101017
// and may just be a time sink.
10111018
if compiler.stage != 0 {

src/bootstrap/src/core/build_steps/tool.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ impl Step for Rustdoc {
471471
features.push("jemalloc".to_string());
472472
}
473473

474-
let cargo = prepare_tool_cargo(
474+
let mut cargo = prepare_tool_cargo(
475475
builder,
476476
build_compiler,
477477
Mode::ToolRustc,
@@ -482,6 +482,14 @@ impl Step for Rustdoc {
482482
features.as_slice(),
483483
);
484484

485+
// If the rustdoc output is piped to e.g. `head -n1` we want the process
486+
// to be killed, rather than having an error bubble up and cause a
487+
// panic.
488+
// FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it.
489+
if build_compiler.stage > 0 {
490+
cargo.rustflag("-Zon-broken-pipe=kill");
491+
}
492+
485493
let _guard = builder.msg_tool(
486494
Kind::Build,
487495
Mode::ToolRustc,

0 commit comments

Comments
 (0)