Change:
reset_sigpipe(); } <ins> // In the case when all file descriptors are open, the poll has been // observed to perform better than fcntl (on GNU/Linux). #[cfg(not(any( miri, target_os = "emscripten", target_os = "fuchsia", // The poll on Darwin doesn't set POLLNVAL for closed fds. target_os = "macos", target_os = "ios", target_os = "redox", )))] unsafe fn sanitize_standard_fds() { use crate::sys::os::errno; let pfds: &mut [_] = &mut [ libc::pollfd { fd: 0, events: 0, revents: 0 }, libc::pollfd { fd: 1, events: 0, revents: 0 }, libc::pollfd { fd: 2, events: 0, revents: 0 }, ]; while libc::poll(pfds.as_mut_ptr(), 3, 0) == -1 { if errno() == libc::EINTR { continue; } libc::abort(); } for pfd in pfds { if pfd.revents & libc::POLLNVAL == 0 { continue; } if libc::open("/dev/null0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or // Stderr. libc::abort(); } } } #[cfg(any(target_os = "macos", target_os = "ios", target_os = "redox"))] unsafe fn sanitize_standard_fds() { use crate::sys::os::errno; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { if libc::open("/dev/null0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { libc::abort(); } } } } #[cfg(any( // The standard fds are always available in Miri. miri, target_os = "emscripten", target_os = "fuchsia"))] unsafe fn sanitize_standard_fds() {} </ins> #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))] unsafe fn reset_sigpipe() { assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);

Discussion:
How to reproduce Actual Result Actual Result with full backtrace rustc --version --verbose Expected result Additional details Please note that the issue will go away once you succeed in building the project (probably thanks due to some compiler caching, sorry, not sure here). A is enough to get the error back :) Thank you.
triage: P-medium due to niche nature of bug. Leaving nominated to try to increase its visibility in short term in case T-compiler members want to attack it.
I'm not asking you to re-prio. I'd just like to say I don't think the issue is so niche, as seems to exhibit the very same behaviour, and I can easily see myself trying: Thank you and again for looking at the ticket :+1:
briefly at T-compiler meeting. un-nominating.
I inadvertently ran into this bug today when trying to do with my project with closed to see how my project would behave. I wasted quite a bit of time trying to find the ICE by reducing my program then I found this issue.
I am unable to reproduce this anymore and WSL:
The problem is still present for me on macOS even on nightly:
I wonder if this is related to ? By the way, for that reason, don't run Rust things with .

For example, if a program is started with (stdout closed, stdin and stderr open), s fail silently (despite showing that clearly returns and ). If a file is opened and then a is attempted, it silently writes into the file (which is probably not what was intended). Example 1: Invocation: Expected result: panic, with an error message relating to being unable to write to stdout, exit code 101 Observed result: nothing (no output on stderr, exit code 0) Example 2: Invocation: Expected result: panic (as before), empty file Observed result: no panic, contains Rust version: 1.30.0 Platform: x86_64-unknown-linux-gnu It looks like any Rust program which is started with one or more closed stdio streams, opens a file (or socket, or…), and subsequently tries to readwrite the file instead (messing up the seek position, not to mention causing data corruption). This seems like terribly bad behavior. ;-;
it appears that this is the conventional expectation of OS kernels. While I don't believe this should be allowed by the OS kernels, making Rust ensure that it doesn't use "reserved" file descriptors would break programs that rely on this corner-case. As this really is an OS level behavior, I think this needs input from OS Security architecture (SELinux, AppArmor, etc.)
Kernel compliance or no, it doesn't seem okay to me that a program can open a , try to write to , and, through no fault of its own, inadvertently corrupt the file.
This seems to be a known problem of the C/POSIX platforms at least as described in
I don't think there's anything we can do here. On Unix platforms, stdout is by definition file descriptor 2.
We could check at startup whether FD 0/1/2 are open using (which returns if the FD is closed). I am not sure what we can do with this information, but I am not very familiar with the I/O parts of the standard library.
If during startup we discover that any of those streams are closed, we can set a flag in the relevant structures to indicate that all accesses should return without attempting a syscall.
As a data point, (GNU on my Ubuntu system) doesn't have this issue As I've just realized and as Amanieu has pointed out, is not how you close stdout.

is still unaffected; on my system produces . It looks like it just detects that by doing . Not sure how useful that is to us.
You need to use , not .

This seems to be related to , though not entirely the same. I am in the process of ing my crate (multiple crates in a workspace project) v0.5.0 (from ). Instead of a normal compile process, I got this: :
I experienced this error now multiple times. Maybe it is a good idea to include the complete build output here:
With I get this error in a different form:
For the record: works on all crates where this bug was triggered (though I did not test all of them, just some).
For whatever reason, this is making it effectively impossible for me to package projects with lots of dependencies for Nix.
I can reliably hit this bug when compiling my project () with Nix
I believe this is a bug in our rustc package in nixpkgs, we appear to build it against which is bugged: https://nix- Maybe it would be a good idea to have a hard dependency on for rustc?
There is an issue here: rustc version 1.22.1 has in its lockfile, and the nix build appears to reliably trigger this bug while compiling . So we have a problem in nixpkgs that we cannot bootstrap using the binary distribution from rust- you are the author of , is there something we could do to workaround this bug for bootstrapping ? Or is it necessary to use a patched for compiling ?
the workaround would be to remove any ambient jobservers and let cargo/rustc manage it, if any
Can't we bootstrap using 1.23.0 binaries?
I can reliably hit this bug as well in nix
I can reliably hit this bug using . As far as I am aware I don't have any jobservers running.
I realized that the following issue was only occurring on nightly. However after the latest update this is now occurring on stable as well.
still persists using seems to happen because of this:
Can you please take another look at this. It appears that your diagnosis is wrong and many people are experiencing this issue. There is no workaround as far as I can tell and this is seriously workflow disrupting.
A misconfigured jobserver can still cause issues in rustc, and this error is indicative of a misconfigured jobserver in one way or another. This indicates an environmental problem rather than a problem in rustc AFAIK.

If someone else manages to fix rustc we can of course merge, but I don't personally believe there's much we can do in rustc for this.
There is no other jobserver in my environment. I have checked numerous ways and am highly confident.
I am also getting the same error as when running entr with the reload flag. Throws the following error: According to the entr documentation whats happening is : 1) immediately start the server 2) block until any of the listed files change 3) terminate the background process 4) wait for the server to exit before restarting
I created an upstream issue for as well - it surrounds closing STDIN, which was in later versions for compatibility with some programs reasons - seems it then breaks with .
It sounds like the underlying issue is
A workaround for those using : It works for me with and 1.40.0 on Linux.
This is no longer happening for me. I don't know what has changed but I don't see this anymore.
It still happens for me with and . Just tested it with and got a panic starting with the same bit.
So, I've found an entirely legitimate way to trigger this error (the "early EOF on jobserver pipe" case) on new versions of , without having stdin closed or anything other exotic setup. If you call from an outer -based build system then will receive file descriptors for the jobserver pipe through an env var called . Except that new versions of will mark those descriptors as so they will be either dead or, worse, replaced with other random files when tries to access them :D The solution is to prevent from closing the pipe by using string anywhere in the command. (Yep, that's how works - ) This is silly, but it seems like doesn't leave any other way to inherit jobserver (at least not readily available from higher level makefile generators).
was recently facing similar issue while trying to run cargo build inside a makefile with buildroot was facing this everytime when i run cargo build Build fails: error: failed to acquire jobserver token: Bad file descriptor (os error 9) This worked for me. MAKEFLAGS= JOBS= cargo build
If you are actually running cargo inside of make you are hitting a different problem and I recommend opening a different issue. This issue was about a bug where no job server was running. This issue was fixed.