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

stdin redirection hangs on macOS #10080

Open
alexkornitzer opened this issue Apr 8, 2024 · 1 comment
Open

stdin redirection hangs on macOS #10080

alexkornitzer opened this issue Apr 8, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@alexkornitzer
Copy link

alexkornitzer commented Apr 8, 2024

Since Bun v1.0.31 which had the major IO rework, talking to Bun via an Erlang Port (https://www.erlang.org/doc/tutorial/c_port) has resulted in hangs on macOS. After investigation the issue appears to come from assumptions that Bun makes in its FileReader (https://github.com/oven-sh/bun/blob/main/src/bun.js/webcore/streams.zig#L3441), resulting in it setting the reader as non blocking when the file descriptor is not. This then results in a hang as the PosixBufferedReader handles reads in a non blocking way while the read syscall is blocking, thus EAGAIN is never raised.

I have used a rather forceful approach in local testing to fix the issue which just ensures the file descriptor is non blocking (using the already present but what appears to be unused function).

diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig
index 7703efa21..201d21a83 100644
--- a/src/bun.js/webcore/streams.zig
+++ b/src/bun.js/webcore/streams.zig
@@ -3525,6 +3525,11 @@ pub const FileReader = struct {
                 if (this.nonblocking and this.file_type == .pipe) {
                     this.file_type = .nonblocking_pipe;
                 }
+
+                // ensure non blocking otherwise hangs will occur
+                if (this.nonblocking) {
+                    bun.ensureNonBlocking(fd.int());
+                }
             }

             this.fd = fd;

I have not raised a PR for this as I understand the fix might be to handle the broken assumptions for macOS builds rather than forcing the descriptor to be non blocking.

The following was used to reproduce the error:

test.js

for await (const line of console) {
  console.log(`line: ${line}`);
}

wrapper.sh

#!/usr/bin/env bash

exec &> >(./build/bun-debug ./test.js)

echo "I printed...!"

while read -r line; do echo $line; done
@Electroid Electroid added the bug Something isn't working label Apr 8, 2024
alexkornitzer added a commit to alexkornitzer/bun that referenced this issue Apr 16, 2024
…h#10080)

The FileReader is responsible for deciding what sort of file descriptor
has been passed to it. On MacOS, when stdin is provided to it the
FileReader assumes that it is nonblocking even if the descriptor is not,
this resulted in hangs as the socket would never raise the `EAGAIN`
error. There are a couple of ways to fix this but the one that seemed to
make the most sense was to set the fd to be nonblocking when the
FileReader deemed it so.
alexkornitzer added a commit to alexkornitzer/bun that referenced this issue Apr 16, 2024
The FileReader is responsible for deciding what sort of file descriptor
has been passed to it. On MacOS, when stdin is provided to it the
FileReader assumes that it is nonblocking even if the descriptor is not
as it passes the pollable and not a tty check, this then results in
hangs as the reader expects `EAGAIN`.

To fix this we now check the file descriptor to see if it is nonblocking
rather than using assumptions.
alexkornitzer added a commit to alexkornitzer/bun that referenced this issue Apr 16, 2024
The FileReader is responsible for deciding what sort of file descriptor
has been passed to it. On MacOS, when stdin is provided to it the
FileReader assumes that it is nonblocking even if the descriptor is not
as it passes the pollable and not a tty check, this then results in
hangs as the reader expects `EAGAIN`.

To fix this we now check the file descriptor to see if it is nonblocking
rather than using assumptions.
alexkornitzer added a commit to alexkornitzer/bun that referenced this issue May 2, 2024
The FileReader is responsible for deciding what sort of file descriptor
has been passed to it. On MacOS, when stdin is provided to it the
FileReader assumes that it is nonblocking even if the descriptor is not
as it passes the pollable and not a tty check, this then results in
hangs as the reader expects `EAGAIN`.

To fix this we now check the file descriptor to see if it is nonblocking
rather than using assumptions.
alexkornitzer added a commit to alexkornitzer/bun that referenced this issue May 31, 2024
The FileReader is responsible for deciding what sort of file descriptor
has been passed to it. On MacOS, when stdin is provided to it the
FileReader assumes that it is nonblocking even if the descriptor is not
as it passes the pollable and not a tty check, this then results in
hangs as the reader expects `EAGAIN`.

To fix this we now check the file descriptor to see if it is nonblocking
rather than using assumptions.
@postnerd
Copy link

I can also reproduce this behavior using Bun as the runtime for my chess engine, postbot.

Since Bun v1.0.31, the engine has stopped working with BanksiaGUI or the lichess-bot wrapper. According to the logs, it appears that stdin stops working after the first input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants