From 9c9893d79c95a9ea6fef2b9dd4ba4d61c89af749 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 10 Jan 2025 11:10:12 +0100 Subject: [PATCH 1/4] Make fstat work on file descriptors with no name in node rawfs This fixes fstat on "anonymous" file descriptors in node rawfs. It is split off from #23058. --- src/library_fs.js | 3 +++ src/library_noderawfs.js | 4 ++++ src/library_syscall.js | 3 +-- test/fs/test_stat_unnamed_file_descriptor.c | 20 ++++++++++++++++++++ test/test_core.py | 10 ++++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/fs/test_stat_unnamed_file_descriptor.c diff --git a/src/library_fs.js b/src/library_fs.js index 7ba5ebec5aa9f..1abafb227eecc 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -956,6 +956,9 @@ FS.staticInit(); } return node.node_ops.getattr(node); }, + fstat(fd) { + return FS.stat(FS.getStreamChecked(fd).node); + }, lstat(path) { return FS.stat(path, true); }, diff --git a/src/library_noderawfs.js b/src/library_noderawfs.js index 81ab16962a89c..a6d38afdce744 100644 --- a/src/library_noderawfs.js +++ b/src/library_noderawfs.js @@ -79,6 +79,10 @@ addToLibrary({ } return stat; }, + fstat(fd) { + var stream = FS.getStreamChecked(fd); + return fs.fstatSync(stream.nfd); + }, chmod(path, mode, dontFollow) { mode &= {{{ cDefs.S_IALLUGO }}}; if (NODEFS.isWindows) { diff --git a/src/library_syscall.js b/src/library_syscall.js index 6acb166b457b8..94ccc495d4fcb 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -678,8 +678,7 @@ var SyscallsLibrary = { return SYSCALLS.writeStat(buf, FS.lstat(path)); }, __syscall_fstat64: (fd, buf) => { - var stream = SYSCALLS.getStreamFromFD(fd); - return SYSCALLS.writeStat(buf, FS.stat(stream.path)); + return SYSCALLS.writeStat(buf, FS.fstat(fd)); }, __syscall_fchown32: (fd, owner, group) => { FS.fchown(fd, owner, group); diff --git a/test/fs/test_stat_unnamed_file_descriptor.c b/test/fs/test_stat_unnamed_file_descriptor.c new file mode 100644 index 0000000000000..a1d92f5cbaba7 --- /dev/null +++ b/test/fs/test_stat_unnamed_file_descriptor.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include "stdio.h" + +int main() { + int fd = open("file.txt", O_RDWR | O_CREAT, 0666); + unlink("file.txt"); + int res; + struct stat buf; + res = fstat(fd, &buf); + assert(res == 0); + assert(buf.st_atime > 1000000000); + res = fchmod(fd, 0777); + assert(res == 0); + res = ftruncate(fd, 10); + assert(res == 0); + printf("success\n"); +} diff --git a/test/test_core.py b/test/test_core.py index f22252f32ce66..b770fe4607f0e 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5847,6 +5847,16 @@ def test_fs_64bit(self): self.set_setting('FORCE_FILESYSTEM') self.do_runf('fs/test_64bit.c', 'success') + @crossplatform + @also_with_noderawfs + def test_fs_stat_unnamed_file_descriptor(self): + nodefs = '-DNODEFS' in self.emcc_args or '-DNODERAWFS' in self.emcc_args + if self.get_setting('WASMFS'): + if nodefs: + self.skipTest('NODEFS in WasmFS') + self.set_setting('FORCE_FILESYSTEM') + self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success') + @requires_node @crossplatform @with_all_fs From 165ac3bd9d18dac719039d0926bcf44b49bdf324 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 10 Jan 2025 11:19:46 +0100 Subject: [PATCH 2/4] Clean up test --- test/test_core.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/test_core.py b/test/test_core.py index b770fe4607f0e..702339bcd7104 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5850,11 +5850,6 @@ def test_fs_64bit(self): @crossplatform @also_with_noderawfs def test_fs_stat_unnamed_file_descriptor(self): - nodefs = '-DNODEFS' in self.emcc_args or '-DNODERAWFS' in self.emcc_args - if self.get_setting('WASMFS'): - if nodefs: - self.skipTest('NODEFS in WasmFS') - self.set_setting('FORCE_FILESYSTEM') self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success') @requires_node From 71878574fae6bc4dbc29cdb6752c2d9b415570f5 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 10 Jan 2025 15:55:34 +0100 Subject: [PATCH 3/4] fix --- src/library_fs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library_fs.js b/src/library_fs.js index 1abafb227eecc..b35cf501215c4 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -957,7 +957,7 @@ FS.staticInit(); return node.node_ops.getattr(node); }, fstat(fd) { - return FS.stat(FS.getStreamChecked(fd).node); + return FS.stat(FS.getStreamChecked(fd).path); }, lstat(path) { return FS.stat(path, true); From eeee049b058e905c44dc8567eaf993c2370e9d51 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 10 Jan 2025 16:49:55 +0100 Subject: [PATCH 4/4] Skip test except in noderawfs --- test/test_core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/test_core.py b/test/test_core.py index 702339bcd7104..e6eeac4f415f2 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5848,8 +5848,11 @@ def test_fs_64bit(self): self.do_runf('fs/test_64bit.c', 'success') @crossplatform - @also_with_noderawfs + @also_with_nodefs_both def test_fs_stat_unnamed_file_descriptor(self): + noderawfs = '-DNODERAWFS' in self.emcc_args + if not noderawfs: + self.skipTest('TODO: only works in noderawfs for now') self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success') @requires_node