Skip to content

Commit

Permalink
Ensure that stdin/stdout/stderr are not mapped 1:1 under NODERAWFS
Browse files Browse the repository at this point in the history
Previously, when linking with -sNODERAWFS, the stdin, stdout and
stderr streams were respectively attached to file descriptors 0, 1
and 2 of the running Node process.

This implicitly means that overriding the print, printErr, stdin,
stdout and stderr handlers on the incoming module wasn't possible.

This commit ensures that stdin/stdout/stderr uses the library_tty.js
implementation for its printing, which leverages the console object,
whenever the above handlers weren't overriden. This matches what is
done when filesystem support isn't included.

Resolves: #17688.
Resolves: #22264.
  • Loading branch information
kleisauke committed Aug 7, 2024
1 parent 03fca01 commit a369c4f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 13 deletions.
31 changes: 18 additions & 13 deletions src/library_noderawfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@
addToLibrary({
$NODERAWFS__deps: ['$ERRNO_CODES', '$FS', '$NODEFS', '$mmapAlloc', '$FS_modeStringToFlags'],
$NODERAWFS__postset: `
if (ENVIRONMENT_IS_NODE) {
if (!ENVIRONMENT_IS_NODE) {
throw new Error("NODERAWFS is currently only supported on Node.js environment.")
}
// Use this to reference our in-memory filesystem
var VFS = Object.assign({}, FS);
// Override the init function with our own
FS.init = NODERAWFS.init;`,
$NODERAWFS: {
init(input, output, error) {
// Call the original FS.init, this will setup the
// stdin, stdout and stderr devices
VFS.init(input, output, error);

var _wrapNodeError = function(func) {
return function(...args) {
try {
Expand All @@ -20,15 +32,14 @@ addToLibrary({
}
}
};
/** @suppress {partialAlias} */
var VFS = Object.assign({}, FS);

// Wrap the whole in-memory filesystem API with
// our Node.js based functions
for (var _key in NODERAWFS) {
/** @suppress {partialAlias} */
FS[_key] = _wrapNodeError(NODERAWFS[_key]);
}
} else {
throw new Error("NODERAWFS is currently only supported on Node.js environment.")
}`,
$NODERAWFS: {
},
lookup(parent, name) {
#if ASSERTIONS
assert(parent)
Expand All @@ -44,12 +55,6 @@ addToLibrary({
var mode = NODEFS.getMode(path);
return { path, node: { id: st.ino, mode, node_ops: NODERAWFS, path }};
},
createStandardStreams() {
FS.createStream({ nfd: 0, position: 0, path: '', flags: 0, tty: true, seekable: false }, 0);
for (var i = 1; i < 3; i++) {
FS.createStream({ nfd: i, position: 0, path: '', flags: 577, tty: true, seekable: false }, i);
}
},
// generic function for all node creation
cwd() { return process.cwd(); },
chdir(...args) { process.chdir(...args); },
Expand Down
34 changes: 34 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,7 @@ def test_export_all_and_exported_functions(self):
'closure': (['-O2', '--closure=1'],),
})
@also_with_wasmfs
@also_with_noderawfs
@crossplatform
def test_stdin(self, args):
create_file('in.txt', 'abcdef\nghijkl\n')
Expand Down Expand Up @@ -13439,6 +13440,7 @@ def test_unistd_pathconf(self):
def test_unistd_swab(self):
self.do_run_in_out_file_test('unistd/swab.c')

@also_with_noderawfs
def test_unistd_isatty(self):
self.do_runf('unistd/isatty.c', 'success')

Expand Down Expand Up @@ -13476,6 +13478,38 @@ def test_unistd_close_noderawfs(self):
self.emcc_args += ['--pre-js', 'pre.js']
self.do_run_in_out_file_test('unistd/close.c')

@requires_node
def test_noderawfs_override_standard_streams(self):
self.set_setting('NODERAWFS')
self.set_setting('FORCE_FILESYSTEM')
create_file('pre.js', '''
let stdout = '';
let stderr = '';

Module['print'] = (text) => stdout += text;
Module['printErr'] = (text) => stderr += text;
Module['postRun'] = () => {
assert(stderr == '', 'stderr should be empty. \\n' +
'stderr: \\n' + stderr);
assert(stdout.startsWith('hello, world!'), 'stdout should start with the famous greeting. \\n' +
'stdout: \\n' + stdout);
}
''')
self.emcc_args += ['--pre-js', 'pre.js']
self.do_runf(test_file('hello_world.c'))

@requires_node
def test_noderawfs_override_stdin(self):
self.set_setting('NODERAWFS')
self.set_setting('FORCE_FILESYSTEM')
self.set_setting('EXIT_RUNTIME')
create_file('pre.js', '''
const data = 'hello, world!\\n'.split('').map(c => c.charCodeAt(0));
Module['stdin'] = () => data.shift() || null;
''')
self.emcc_args += ['--pre-js', 'pre.js']
self.do_runf(test_file('module/test_stdin.c'), 'hello, world!')

# WASMFS tests

# TODO: This test will only work with the new file system.
Expand Down
4 changes: 4 additions & 0 deletions test/unistd/isatty.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ int main() {
assert(errno == EBADF);

err = isatty(open("/dev/stdin", O_RDONLY));
#ifdef NODERAWFS
assert(!err);
#else
assert(err == 1);
#endif

err = isatty(open("/dev/null", O_RDONLY));
assert(!err);
Expand Down

0 comments on commit a369c4f

Please sign in to comment.