diff --git a/src/library_noderawfs.js b/src/library_noderawfs.js index 8a4ddcd599a43..b43f196f67e5a 100644 --- a/src/library_noderawfs.js +++ b/src/library_noderawfs.js @@ -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 { @@ -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) @@ -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); }, diff --git a/test/test_other.py b/test/test_other.py index 9e7b94a51ede3..0a508201648ac 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1689,6 +1689,38 @@ def test_stdin(self, args): os.system(f'cat in.txt | {cmd} > out.txt') self.assertContained('abcdef\nghijkl\neof', read_file('out.txt')) + @also_with_noderawfs + @crossplatform + def test_module_stdin(self): + 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('module/test_stdin.c', 'hello, world!') + + @also_with_noderawfs + @crossplatform + def test_module_stdout_stderr(self): + 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('hello_world.c') + def test_ungetc_fscanf(self): create_file('main.c', r''' #include @@ -9778,6 +9810,7 @@ def test_ioctl(self): # ioctl requires filesystem self.do_other_test('test_ioctl.c', emcc_args=['-sFORCE_FILESYSTEM']) + @also_with_noderawfs def test_ioctl_termios(self): # ioctl requires filesystem self.do_other_test('test_ioctl_termios.c', emcc_args=['-sFORCE_FILESYSTEM'])