Skip to content

[WasmFS] Allow reading from char devices in the Node backend#26599

Merged
sbc100 merged 1 commit intoemscripten-core:mainfrom
kleisauke:wasmfs-allow-read-from-char-devices
Apr 2, 2026
Merged

[WasmFS] Allow reading from char devices in the Node backend#26599
sbc100 merged 1 commit intoemscripten-core:mainfrom
kleisauke:wasmfs-allow-read-from-char-devices

Conversation

@kleisauke
Copy link
Copy Markdown
Collaborator

Split out from #24733, this fixes a test failure in other.test_fs_dev_random_wasmfs_rawfs from that PR.

fp = fopen("/dev/urandom", "r");
nread = fread(&data, 1, byte_count, fp);
assert(fp != NULL);
nread = fread(data, 1, byte_count, fp);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

So you are adding an extra assert here? But it seems like if /dev/random was not openable/readable this test should already have been failing, no?

Or does this change not actually fix this test?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Unfortunately, the CI log for this failure has expired. IIRC, it failed with RuntimeError: memory access out of bounds, which I can reproduce using:

--- a/test/fs/test_fs_dev_random.c
+++ b/test/fs/test_fs_dev_random.c
@@ -13,14 +13,12 @@ int main() {
   int nread;
 
   fp = fopen("/dev/random", "r");
-  assert(fp != NULL);
-  nread = fread(data, 1, byte_count, fp);
+  nread = fread(data, 1, byte_count, NULL);
   assert(nread == byte_count);
   fclose(fp);
 
   fp = fopen("/dev/urandom", "r");
-  assert(fp != NULL);
-  nread = fread(data, 1, byte_count, fp);
+  nread = fread(data, 1, byte_count, NULL);
   assert(nread == byte_count);
   fclose(fp);

In other words, previously fp (FILE *) was NULL without the change to node_backend.cpp. The added asserts are intended to provide clearer failure messages.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Oh I see, but other.test_fs_dev_random_wasmfs_rawfs cannot actually be enabled as part of this PR for some reason?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If so that sounds fair enough to me. Still nice to see fixes like this land as separate PRs.

Copy link
Copy Markdown
Collaborator Author

@kleisauke kleisauke Apr 1, 2026

Choose a reason for hiding this comment

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

The other.test_fs_dev_random_wasmfs_rawfs test is enabled in this PR, but it passes because /dev and /tmp are virtualized. This virtualization is also the reason for issue #24836.

lockedDev.mountChild("random", SpecialFiles::getRandom());
lockedDev.mountChild("urandom", SpecialFiles::getURandom());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

But I don't see other.test_fs_dev_random_wasmfs_rawfs being enabled in this PR?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ah, sorry. I meant that it should have already been enabled by this decorator:

@with_all_fs

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

For reference, see the CircleCI log at https://circleci.com/gh/emscripten-core/emscripten/1164689 for the failure.

Details
======================================================================
FAIL [0.001s]: test_fs_dev_random_wasmfs_rawfs (test_other.other)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/root/project/test/common.py", line 377, in resulting_test
    return func(self, *args)
  File "/root/project/test/decorators.py", line 324, in metafunc
    return func(self, *args, **kwargs)
  File "/root/project/test/test_other.py", line 5556, in test_fs_dev_random
    self.do_runf('fs/test_fs_dev_random.c', 'success')
  File "/root/project/test/common.py", line 1408, in do_runf
    return self._build_and_run(filename, expected_output, **kwargs)
  File "/root/project/test/common.py", line 1456, in _build_and_run
    js_output = self.run_js(js_file, engine, args,
  File "/root/project/test/common.py", line 1040, in run_js
    self.fail('JS subprocess failed (%s): %s (expected=%s).  Output:\n%s' % (error.cmd, error.returncode, assert_returncode, ret))
AssertionError: JS subprocess failed (/root/emsdk/node/22.16.0_64bit/bin/node --stack-trace-limit=50 --trace-uncaught /tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js): 1 (expected=0).  Output:
wasm://wasm/00058602:1


RuntimeError: memory access out of bounds
    at wasm://wasm/00058602:wasm-function[51]:0x1449
    at wasm://wasm/00058602:wasm-function[53]:0x1589
    at wasm://wasm/00058602:wasm-function[34]:0x913
    at wasm://wasm/00058602:wasm-function[35]:0x9f3
    at /tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:592:12
    at callMain (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:2117:15)
    at doRun (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:2170:24)
    at run (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:2183:5)
    at removeRunDependency (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:823:11)
    at receiveInstance (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:696:5)
    at receiveInstantiationResult (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:713:12)
    at createWasm (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:739:17)
Thrown at:
    at $func51 (wasm://wasm/00058602:1:5194)
    at $func53 (wasm://wasm/00058602:1:5514)
    at $func34 (wasm://wasm/00058602:1:2324)
    at $main (wasm://wasm/00058602:1:2548)
    at /tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:592:12
    at callMain (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:2117:15)
    at doRun (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:2170:24)
    at run (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:2183:5)
    at removeRunDependency (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:823:11)
    at receiveInstance (/tmp/emtest_aitqg_pq/emscripten_test_other_piipb_5p/test_fs_dev_random.js:696:5)


Node.js v22.16.0


----------------------------------------------------------------------
Ran 1661 tests in 1227.050s

FAILED (failures=1, skipped=92)

sbc100
sbc100 approved these changes Apr 1, 2026
@sbc100 sbc100 merged commit bc56904 into emscripten-core:main Apr 2, 2026
38 checks passed
@kleisauke kleisauke deleted the wasmfs-allow-read-from-char-devices branch April 2, 2026 16:02
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