wip [ci skip]
diff --git a/emcc.py b/emcc.py
index 7b656f9..690b14b 100755
--- a/emcc.py
+++ b/emcc.py
@@ -865,7 +865,7 @@
# configure tests want a more shell-like style, where we emit return codes on exit()
cmd += ['-s', 'EXIT_RUNTIME=1']
# use node.js raw filesystem access, to behave just like a native executable
- cmd += ['-s', 'NODERAWFS=1']
+ cmd += ['-s', 'RAW_OS=1']
logger.debug('just configuring: ' + ' '.join(cmd))
if debug_configure:
@@ -1570,8 +1570,8 @@
shared.Settings.PROXY_TO_WORKER = 1
if options.use_preload_plugins or len(options.preload_files) or len(options.embed_files):
- if shared.Settings.NODERAWFS:
- exit_with_error('--preload-file and --embed-file cannot be used with NODERAWFS which disables virtual filesystem')
+ if shared.Settings.RAW_OS:
+ exit_with_error('--preload-file and --embed-file cannot be used with RAW_OS which disables virtual filesystem')
# if we include any files, or intend to use preload plugins, then we definitely need filesystem support
shared.Settings.FORCE_FILESYSTEM = 1
diff --git a/src/modules.js b/src/modules.js
index 9f1c796..dc83488 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -106,8 +106,8 @@
'library_sockfs.js', // ok to include it by default since it's only used if the syscall is used
]);
- if (NODERAWFS) {
- // NODERAWFS requires NODEFS
+ if (RAW_OS) {
+ // Enable NODERAWFS, which also requires NODEFS
if (SYSTEM_JS_LIBRARIES.indexOf('library_nodefs.js') < 0) {
libraries.push('library_nodefs.js');
}
diff --git a/src/settings.js b/src/settings.js
index dd6a629..5a0bb7d 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -824,8 +824,11 @@
// some JS that does, you might need this.
var FORCE_FILESYSTEM = 0;
-// Enables support for the NODERAWFS filesystem backend. This is a special
-// backend as it replaces all normal filesystem access with direct Node.js
+// Enables direct OS access. This matters in a *non*-Web environment (as on
+// the Web, OS access is always indirect), where it allows directly accessing
+// local files and so forth.
+// Specifically, on Node.js this enables the NODERAWFS filesystem, a special
+// backend that replaces all normal filesystem access with direct Node.js
// operations, without the need to do `FS.mount()`, and this backend only
// works with Node.js. The initial working directory will be same as
// process.cwd() instead of VFS root directory. Because this mode directly uses
@@ -834,7 +837,11 @@
// program would be, which means that differences in how the underlying OS
// handles permissions and errors and so forth may be noticeable. This has
// mostly been tested on Linux so far.
-var NODERAWFS = 0;
+// With wasm2c this also enables direct file access, allowing an executable
+// built from the C code to behave like a normal C program would. As with
+// NODERAWFS, this will be as portable as a C program would be in general -
+// underlying OS differences may be noticeable.
+var RAW_OS = 0;
// This saves the compiled wasm module in a file with name
// $WASM_BINARY_NAME.$V8_VERSION.cached
@@ -1814,4 +1821,5 @@
['BINARYEN_MEM_MAX', 'MAXIMUM_MEMORY'],
['BINARYEN_PASSES', [''], 'Use BINARYEN_EXTRA_PASSES to add additional passes'],
['SWAPPABLE_ASM_MODULE', [0], 'Fully swappable asm modules are no longer supported'],
+ ['NODERAWFS', 'RAW_OS'],
];
diff --git a/tests/test_core.py b/tests/test_core.py
index edf19cc..7e34b6b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -133,7 +133,7 @@
orig_args = self.emcc_args[:]
func(self)
print('noderawfs')
- self.emcc_args = orig_args + ['-s', 'NODERAWFS=1', '-DNODERAWFS']
+ self.emcc_args = orig_args + ['-s', 'RAW_OS', '-DNODERAWFS']
with js_engines_modify([NODE_JS]):
func(self)
return decorated
@@ -5391,7 +5391,7 @@
# Node.js fs.chmod is nearly no-op on Windows
if not WINDOWS:
self.emcc_args = orig_compiler_opts
- self.emcc_args += ['-s', 'NODERAWFS=1']
+ self.emcc_args += ['-s', 'RAW_OS']
self.do_run_in_out_file_test('tests', 'unistd', 'access', js_engines=[NODE_JS])
def test_unistd_curdir(self):
@@ -5447,7 +5447,7 @@
# FIXME
self.skipTest('fails on some node versions and OSes, e.g. 10.13.0 on linux')
- self.emcc_args += ['-s', 'NODERAWFS=1']
+ self.emcc_args += ['-s', 'RAW_OS']
self.do_run_in_out_file_test('tests', 'unistd', 'truncate', js_engines=[NODE_JS])
def test_unistd_swab(self):
@@ -5495,7 +5495,7 @@
# 0 if root user
if os.geteuid() == 0:
self.emcc_args += ['-DSKIP_ACCESS_TESTS']
- self.emcc_args += ['-s', 'NODERAWFS=1']
+ self.emcc_args += ['-s', 'RAW_OS']
self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
def test_unistd_links(self):
diff --git a/tests/test_other.py b/tests/test_other.py
index 2f321ed..8abac23 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -8484,18 +8484,18 @@
# replaced subprocess functions should not cause errors
run_process([EMCC, path_from_root('tests', 'hello_world.c')], env=environ)
- def test_noderawfs(self):
+ def test_RAW_OS(self):
fopen_write = open(path_from_root('tests', 'asmfs', 'fopen_write.cpp')).read()
create_test_file('main.cpp', fopen_write)
- run_process([EMCC, 'main.cpp', '-s', 'NODERAWFS=1'])
+ run_process([EMCC, 'main.cpp', '-s', 'RAW_OS=1'])
self.assertContained("read 11 bytes. Result: Hello data!", run_js('a.out.js'))
- # NODERAWFS should directly write on OS file system
+ # RAW_OS should directly write on OS file system
self.assertEqual("Hello data!", open('hello_file.txt').read())
- def test_noderawfs_disables_embedding(self):
- expected = '--preload-file and --embed-file cannot be used with NODERAWFS which disables virtual filesystem'
- base = [EMCC, path_from_root('tests', 'hello_world.c'), '-s', 'NODERAWFS=1']
+ def test_RAW_OS_disables_embedding(self):
+ expected = '--preload-file and --embed-file cannot be used with RAW_OS which disables virtual filesystem'
+ base = [EMCC, path_from_root('tests', 'hello_world.c'), '-s', 'RAW_OS']
err = self.expect_fail(base + ['--preload-file', 'somefile'])
self.assertContained(expected, err)
err = self.expect_fail(base + ['--embed-file', 'somefile'])
@@ -10270,6 +10270,29 @@
with open(path_from_root('tests', 'other', 'wasm2c', 'output.txt')) as f:
self.assertEqual(output, f.read())
+ @no_windows('TODO: fix setjmp.h on clang on windows on ci')
+ def test_wasm2c_RAW_OS(self):
+ create_test_file('data.txt', 'hello')
+ create_test_file('main.cpp', r'''
+ #include <stdio.h>
+ int main() {
+ FILE *f = fopen("data.dat", "r");
+ if (!f) {
+ puts("failed to open file");
+ return 1;
+ }
+ char buf[6];
+ fread(buf, 1, 5, f);
+ buf[5] = 0;
+ fclose(f);
+ printf("read |%s|\n", buf);
+ }
+ ''')
+ run_process([EMCC, 'main.cpp', '-s', 'WASM2C', '-o', 'main.wasm'])
+ run_process([CLANG_CC, 'main.wasm.c', '-o', 'program.exe'])
+ output = run_process([os.path.abspath('program.exe')], stdout=PIPE).stdout
+ self.assertContained('|hello|', output)
+
@parameterized({
'wasm2js': (['-s', 'WASM=0'], ''),
'modularize': (['-s', 'MODULARIZE'], 'Module()'),
diff --git a/tools/wasm2c.py b/tools/wasm2c.py
index 5b0a3c6..761730a 100644
--- a/tools/wasm2c.py
+++ b/tools/wasm2c.py
@@ -49,13 +49,13 @@
support_files = ['base']
if Settings.AUTODEBUG:
support_files.append('autodebug')
- if Settings.EXPECT_MAIN:
- # TODO: add an option for direct OS access. For now, do that when building
- # an executable with main, as opposed to a library
+ if Settings.RAW_OS:
support_files.append('os')
- support_files.append('main')
else:
support_files.append('os_sandboxed')
+ if Settings.EXPECT_MAIN:
+ support_files.append('main')
+ else:
support_files.append('reactor')
# for a reactor, also append wasmbox_* API definitions
with open(h_file, 'a') as f:
diff --git a/tools/wasm2c/os_sandboxed.c b/tools/wasm2c/os_sandboxed.c
index 728d713..0edb708 100644
--- a/tools/wasm2c/os_sandboxed.c
+++ b/tools/wasm2c/os_sandboxed.c
@@ -20,3 +20,6 @@
STUB_IMPORT_IMPL(u32, Z_envZ___sys_accessZ_iii, (u32 pathname, u32 mode), EM_EACCES);
STUB_IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_clock_time_getZ_iiji, (u32 clock_id, u64 max_lag, u32 out), WASI_EINVAL);
STUB_IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_clock_res_getZ_iii, (u32 clock_id, u32 out), WASI_EINVAL);
+
+// called by main() if main() exists
+static void init_fds() {}