Skip to content

Conversation

@ktock
Copy link
Contributor

@ktock ktock commented Dec 23, 2025

Emrun is a convenient tool for showcasing emscripten-compiled program to other developers on the CLI without requiring manual HTTP server setup.

However, interactive programs don't work because emrun doesn't forward stdin to the client program.

This PR fixes this issue by introducing a new emrun flag --interactive which forwards emrun's stdin to the client program. In this mode, the program's output is sent to emrun character by character to support output without a trailing newline char, such as the prompt characters.

It focuses on the interactive programs that use non-blocking stdin (e.g. select/poll with nonblocking reads) so that the browser's main loop isn't blocked when using this flag.

Example

I've used FireFox 146:

mkdir /tmp/test/
./emcc ./test/test_interactive_emrun.c --emrun -pthread -sPROXY_TO_PTHREAD -o /tmp/test/index.html
echo hi | ./emrun --interactive --browser_args=--headless /tmp/test/index.html

This prints "hi" to the terminal.

@ktock ktock marked this pull request as draft December 23, 2025 17:21
This commit adds the --interactive flag which forwards emrun's stdin to the
client program.

The client program's "emrun_postjs.js" connects to emrun's "/in" endpoint
before starting the program. All stdin input received by emrun are forwarded
to the client as server-side events. The client program can access this
input via `TTY.default_tty_ops.get_char`.

This commit also adds an implementation of `TTY.stream_ops.poll`
implementation so that the client can check whether the input is ready using
the `select` syscall.

To avoid blocking the browser's main loop, --interactive flag enables only
non-blocking stdin. The client program can check input readiness using the
select syscall then perform the read when the input becomes available.

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Currently, emrun receives client output line by line separated by newline
characters. However, interactive programs often needs to display output
without a trailing newline char, such as the prompt characters (e.g. "$" and
"#"). And the current emrun implementation can't display such output
correctly. This commit fixes this issue by sending the client program's
output to emrun character by character when --interactive is enabled.

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
@sbc100
Copy link
Collaborator

sbc100 commented Dec 23, 2025

I'm curious about the use of stdin for programs running on the web. Emscripten doesn't really have good support for stdin on the web right now, but maybe its something we could improbe.

Would it perhaps make sense to instead run these kind of tests under node where stdin and stdout and much better supported?

@ktock
Copy link
Contributor Author

ktock commented Dec 23, 2025

I've been running an emscripten-compiled QEMU targetting browser (https://github.com/ktock/qemu-wasm-sample/tree/tcidev ). I'm using xterm-pty as the terminal layer on browser.

@sbc100
Copy link
Collaborator

sbc100 commented Dec 23, 2025

I'm somewhat hesitant to add more features and complexity to emrun. Right now we have very pretty limited testing of it, and we also don't use it internally do testing of emscripten itself (the test runner has it own builtin webserver).

I wonder if this is the kind of functionality that is best built in top of emscripten rather then within it? I don't feel super strongly here, but just want to push back at least little bit. At least we should improve our emrun testing before we start making it more complicated. It looks like we disabled a bunch of the tests back in #14434 and we should probably fix that first ..

@sbc100
Copy link
Collaborator

sbc100 commented Dec 23, 2025

BTW, have to tried doing some of your testing under node? It makes the debug test cycle a lot faster when the browser is not in the loop :) I'm not suggesting you remove all browser testing, but do some large fraction under node (this is what we do internally in emscripten testing).

@ktock
Copy link
Contributor Author

ktock commented Dec 24, 2025

Thanks for the suggestion. I currently rely on manually running the tools/file_packager.py script because I want to keep the processes of building the emulator binary and packaging the guest images separate. As documented in https://emscripten.org/docs/porting/files/packaging_files.html#packaging-files-file-packager , they can be loaded and run on browsers, however I couldn't find the way for node.js. Does the output of tools/file_packager.py support being loaded to node.js separately from the emcc output, ideally without requiring recompilation?

@sbc100
Copy link
Collaborator

sbc100 commented Dec 24, 2025

Yes, file packager output should work just fine under node.

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.

2 participants