Skip to content

Commit c614fa5

Browse files
authored
Ensure that stdin/stdout/stderr are not mapped 1:1 under NODERAWFS (#18163)
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. https://github.com/emscripten-core/emscripten/blob/52e380517269b9e2d9341ff80f54e0b6f7398898/src/library_noderawfs.js#L47-L52 This implicitly means that overriding the print, printErr, stdin, stdout and stderr handlers on the incoming module wasn't possible. https://github.com/emscripten-core/emscripten/blob/52e380517269b9e2d9341ff80f54e0b6f7398898/src/shell.js#L431-L432 https://github.com/emscripten-core/emscripten/blob/52e380517269b9e2d9341ff80f54e0b6f7398898/src/library_fs.js#L1496-L1499 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.
1 parent 80d2150 commit c614fa5

File tree

2 files changed

+51
-13
lines changed

2 files changed

+51
-13
lines changed

src/library_noderawfs.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@
77
addToLibrary({
88
$NODERAWFS__deps: ['$ERRNO_CODES', '$FS', '$NODEFS', '$mmapAlloc', '$FS_modeStringToFlags'],
99
$NODERAWFS__postset: `
10-
if (ENVIRONMENT_IS_NODE) {
10+
if (!ENVIRONMENT_IS_NODE) {
11+
throw new Error("NODERAWFS is currently only supported on Node.js environment.")
12+
}
13+
// Use this to reference our in-memory filesystem
14+
var VFS = Object.assign({}, FS);
15+
// Override the init function with our own
16+
FS.init = NODERAWFS.init;`,
17+
$NODERAWFS: {
18+
init(input, output, error) {
19+
// Call the original FS.init, this will setup the
20+
// stdin, stdout and stderr devices
21+
VFS.init(input, output, error);
22+
1123
var _wrapNodeError = function(func) {
1224
return function(...args) {
1325
try {
@@ -20,15 +32,14 @@ addToLibrary({
2032
}
2133
}
2234
};
23-
/** @suppress {partialAlias} */
24-
var VFS = Object.assign({}, FS);
35+
36+
// Wrap the whole in-memory filesystem API with
37+
// our Node.js based functions
2538
for (var _key in NODERAWFS) {
39+
/** @suppress {partialAlias} */
2640
FS[_key] = _wrapNodeError(NODERAWFS[_key]);
2741
}
28-
} else {
29-
throw new Error("NODERAWFS is currently only supported on Node.js environment.")
30-
}`,
31-
$NODERAWFS: {
42+
},
3243
lookup(parent, name) {
3344
#if ASSERTIONS
3445
assert(parent)
@@ -44,12 +55,6 @@ addToLibrary({
4455
var mode = NODEFS.getMode(path);
4556
return { path, node: { id: st.ino, mode, node_ops: NODERAWFS, path }};
4657
},
47-
createStandardStreams() {
48-
FS.createStream({ nfd: 0, position: 0, path: '', flags: 0, tty: true, seekable: false }, 0);
49-
for (var i = 1; i < 3; i++) {
50-
FS.createStream({ nfd: i, position: 0, path: '', flags: 577, tty: true, seekable: false }, i);
51-
}
52-
},
5358
// generic function for all node creation
5459
cwd() { return process.cwd(); },
5560
chdir(...args) { process.chdir(...args); },

test/test_other.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,38 @@ def test_stdin(self, args):
16891689
os.system(f'cat in.txt | {cmd} > out.txt')
16901690
self.assertContained('abcdef\nghijkl\neof', read_file('out.txt'))
16911691

1692+
@also_with_noderawfs
1693+
@crossplatform
1694+
def test_module_stdin(self):
1695+
self.set_setting('FORCE_FILESYSTEM')
1696+
self.set_setting('EXIT_RUNTIME')
1697+
create_file('pre.js', '''
1698+
const data = 'hello, world!\\n'.split('').map(c => c.charCodeAt(0));
1699+
Module['stdin'] = () => data.shift() || null;
1700+
''')
1701+
self.emcc_args += ['--pre-js', 'pre.js']
1702+
self.do_runf('module/test_stdin.c', 'hello, world!')
1703+
1704+
@also_with_noderawfs
1705+
@crossplatform
1706+
def test_module_stdout_stderr(self):
1707+
self.set_setting('FORCE_FILESYSTEM')
1708+
create_file('pre.js', '''
1709+
let stdout = '';
1710+
let stderr = '';
1711+
1712+
Module['print'] = (text) => stdout += text;
1713+
Module['printErr'] = (text) => stderr += text;
1714+
Module['postRun'] = () => {
1715+
assert(stderr == '', 'stderr should be empty. \\n' +
1716+
'stderr: \\n' + stderr);
1717+
assert(stdout.startsWith('hello, world!'), 'stdout should start with the famous greeting. \\n' +
1718+
'stdout: \\n' + stdout);
1719+
}
1720+
''')
1721+
self.emcc_args += ['--pre-js', 'pre.js']
1722+
self.do_runf('hello_world.c')
1723+
16921724
def test_ungetc_fscanf(self):
16931725
create_file('main.c', r'''
16941726
#include <stdio.h>
@@ -9693,6 +9725,7 @@ def test_ioctl(self):
96939725
# ioctl requires filesystem
96949726
self.do_other_test('test_ioctl.c', emcc_args=['-sFORCE_FILESYSTEM'])
96959727

9728+
@also_with_noderawfs
96969729
def test_ioctl_termios(self):
96979730
# ioctl requires filesystem
96989731
self.do_other_test('test_ioctl_termios.c', emcc_args=['-sFORCE_FILESYSTEM'])

0 commit comments

Comments
 (0)