From f3f36d586a2535ff7a2e8b68c303ee10c990fe90 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 3 Dec 2024 16:39:34 +0100 Subject: [PATCH 01/31] Make fstat work on file descriptor with no name --- src/library_syscall.js | 2 +- test/fs/test_stat_unnamed_file_descriptor.c | 16 ++++++++++++++++ test/test_core.py | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/fs/test_stat_unnamed_file_descriptor.c diff --git a/src/library_syscall.js b/src/library_syscall.js index fde42e8a48428..96108049bdd66 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -680,7 +680,7 @@ var SyscallsLibrary = { }, __syscall_fstat64: (fd, buf) => { var stream = SYSCALLS.getStreamFromFD(fd); - return SYSCALLS.doStat(FS.stat, stream.path, buf); + return SYSCALLS.doStat(stream.node.node_ops.getattr, stream.node, buf); }, __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..2df54f75fd5dc --- /dev/null +++ b/test/fs/test_stat_unnamed_file_descriptor.c @@ -0,0 +1,16 @@ +#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); + printf("success\n"); +} diff --git a/test/test_core.py b/test/test_core.py index f3a2297e73194..d31cd0f5ffee1 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5921,6 +5921,11 @@ def test_fs_64bit(self): self.set_setting('FORCE_FILESYSTEM') self.do_runf('fs/test_64bit.c', 'success') + def test_fs_stat_unnamed_file_descriptor(self): + if self.get_setting('WASMFS'): + self.set_setting('FORCE_FILESYSTEM') + self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success') + def test_sigalrm(self): self.do_runf('test_sigalrm.c', 'Received alarm!') self.set_setting('EXIT_RUNTIME') From 260278fb316915afecd008350bceadcac7df8470 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 3 Dec 2024 17:12:35 +0100 Subject: [PATCH 02/31] Fix node rawfs --- src/library_fs.js | 4 ++++ src/library_noderawfs.js | 4 ++++ src/library_syscall.js | 3 +-- test/test_core.py | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 98e575e549fc4..8f1eda174a030 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -938,6 +938,10 @@ FS.staticInit(); } return node.node_ops.getattr(node); }, + fstat(fd) { + var stream = SYSCALLS.getStreamFromFD(fd); + return stream.node.node_ops.getattr(stream.node); + }, lstat(path) { return FS.stat(path, true); }, diff --git a/src/library_noderawfs.js b/src/library_noderawfs.js index 55b9e97a4c716..104a9ade968bd 100644 --- a/src/library_noderawfs.js +++ b/src/library_noderawfs.js @@ -79,6 +79,10 @@ addToLibrary({ } return stat; }, + fstat(fd) { + var stream = SYSCALLS.getStreamFromFD(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 96108049bdd66..ad294fce787c1 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -679,8 +679,7 @@ var SyscallsLibrary = { return SYSCALLS.doStat(FS.lstat, path, buf); }, __syscall_fstat64: (fd, buf) => { - var stream = SYSCALLS.getStreamFromFD(fd); - return SYSCALLS.doStat(stream.node.node_ops.getattr, stream.node, buf); + return SYSCALLS.doStat(FS.fstat, fd, buf); }, __syscall_fchown32: (fd, owner, group) => { FS.fchown(fd, owner, group); diff --git a/test/test_core.py b/test/test_core.py index d31cd0f5ffee1..5650e72b72669 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5921,6 +5921,7 @@ def test_fs_64bit(self): self.set_setting('FORCE_FILESYSTEM') self.do_runf('fs/test_64bit.c', 'success') + @also_with_noderawfs def test_fs_stat_unnamed_file_descriptor(self): if self.get_setting('WASMFS'): self.set_setting('FORCE_FILESYSTEM') From f865bdbca5eb8ac42b98b945f381de93bd9a4575 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 3 Dec 2024 17:39:18 +0100 Subject: [PATCH 03/31] Cleanup --- src/library_fs.js | 2 +- src/library_noderawfs.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 8f1eda174a030..964b3014056ff 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -939,7 +939,7 @@ FS.staticInit(); return node.node_ops.getattr(node); }, fstat(fd) { - var stream = SYSCALLS.getStreamFromFD(fd); + var stream = FS.getStreamChecked(fd); return stream.node.node_ops.getattr(stream.node); }, lstat(path) { diff --git a/src/library_noderawfs.js b/src/library_noderawfs.js index 104a9ade968bd..f728bd72f78ac 100644 --- a/src/library_noderawfs.js +++ b/src/library_noderawfs.js @@ -80,7 +80,7 @@ addToLibrary({ return stat; }, fstat(fd) { - var stream = SYSCALLS.getStreamFromFD(fd); + var stream = FS.getStreamChecked(fd); return fs.fstatSync(stream.nfd); }, chmod(path, mode, dontFollow) { From cac8b191134a43dd9cfa286f16964362fdefa96c Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 3 Dec 2024 17:35:38 +0100 Subject: [PATCH 04/31] Fix nodefs handling of unnamed file descriptors --- src/library_fs.js | 56 +++++++++- src/library_nodefs.js | 114 +++++++++++--------- test/fs/test_stat_unnamed_file_descriptor.c | 24 +++++ test/test_core.py | 13 ++- 4 files changed, 149 insertions(+), 58 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 964b3014056ff..2edf9758c2db8 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -940,7 +940,13 @@ FS.staticInit(); }, fstat(fd) { var stream = FS.getStreamChecked(fd); - return stream.node.node_ops.getattr(stream.node); + var node = stream.node; + if (stream.stream_ops.getattr) { + return stream.stream_ops.getattr(stream); + } else if (node.node_ops.getattr) { + return node.node_ops.getattr(node); + } + throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, lstat(path) { return FS.stat(path, true); @@ -966,7 +972,17 @@ FS.staticInit(); }, fchmod(fd, mode) { var stream = FS.getStreamChecked(fd); - FS.chmod(stream.node, mode); + var node = stream.node; + var attrs = { + mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (node.mode & ~{{{ cDefs.S_IALLUGO }}}), + timestamp: Date.now() + }; + if (stream.stream_ops.getattr) { + return stream.stream_ops.setattr(stream, attrs); + } else if (node.node_ops.getattr) { + return node.node_ops.setattr(node, attrs); + } + throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, chown(path, uid, gid, dontFollow) { var node; @@ -989,7 +1005,17 @@ FS.staticInit(); }, fchown(fd, uid, gid) { var stream = FS.getStreamChecked(fd); - FS.chown(stream.node, uid, gid); + var node = stream.node; + var attrs = { + timestamp: Date.now() + // we ignore the uid / gid for now + }; + if (stream.stream_ops.getattr) { + return stream.stream_ops.setattr(stream, attrs); + } else if (node.node_ops.getattr) { + return node.node_ops.setattr(node, attrs); + } + throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, truncate(path, len) { if (len < 0) { @@ -1022,10 +1048,32 @@ FS.staticInit(); }, ftruncate(fd, len) { var stream = FS.getStreamChecked(fd); + var node = stream.node; if ((stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } - FS.truncate(stream.node, len); + if (!node.node_ops.setattr && !stream.stream_ops.setattr) { + throw new FS.ErrnoError({{{ cDefs.EPERM }}}); + } + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError({{{ cDefs.EISDIR }}}); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); + } + var errCode = FS.nodePermissions(node, 'w'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + var attrs = { + size: len, + timestamp: Date.now() + }; + if (stream.stream_ops.setattr) { + stream.stream_ops.setattr(stream, attrs); + } else { + node.node_ops.setattr(node, attrs); + } }, utime(path, atime, mtime) { var lookup = FS.lookupPath(path, { follow: true }); diff --git a/src/library_nodefs.js b/src/library_nodefs.js index 6d0544c8527cc..f8a263cf7cd58 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -116,64 +116,68 @@ addToLibrary({ } return newFlags; }, - - node_ops: { - getattr(node) { - var path = NODEFS.realPath(node); - var stat; - NODEFS.tryFSOperation(() => stat = fs.lstatSync(path)); + getattr(func) { + var stat = NODEFS.tryFSOperation(func); if (NODEFS.isWindows) { - // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake - // them with default blksize of 4096. - // See http://support.microsoft.com/kb/140365 - if (!stat.blksize) { - stat.blksize = 4096; - } - if (!stat.blocks) { - stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0; + // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake + // them with default blksize of 4096. + // See http://support.microsoft.com/kb/140365 + if (!stat.blksize) { + stat.blksize = 4096; + } + if (!stat.blocks) { + stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0; + } + // Windows does not report the 'x' permission bit, so propagate read + // bits to execute bits. + stat.mode |= (stat.mode & {{{ cDefs.S_IRUGO }}}) >> 2; + } + return { + dev: stat.dev, + ino: stat.ino, + mode: stat.mode, + nlink: stat.nlink, + uid: stat.uid, + gid: stat.gid, + rdev: stat.rdev, + size: stat.size, + atime: stat.atime, + mtime: stat.mtime, + ctime: stat.ctime, + blksize: stat.blksize, + blocks: stat.blocks + }; + }, + setattr(path, node, attr, chmod, utimes, truncate) { + NODEFS.tryFSOperation(() => { + if (attr.mode !== undefined) { + var mode = attr.mode; + if (NODEFS.isWindows) { + // Windows only supports S_IREAD / S_IWRITE (S_IRUSR / S_IWUSR) + // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/chmod-wchmod + mode &= {{{ cDefs.S_IRUSR | cDefs.S_IWUSR }}}; } - // Windows does not report the 'x' permission bit, so propagate read - // bits to execute bits. - stat.mode |= (stat.mode & {{{ cDefs.S_IRUGO }}}) >> 2; + chmod(path, mode); + // update the common node structure mode as well + node.mode = attr.mode; + } + if (attr.timestamp !== undefined) { + var date = new Date(attr.timestamp); + utimes(path, date, date); } - return { - dev: stat.dev, - ino: stat.ino, - mode: stat.mode, - nlink: stat.nlink, - uid: stat.uid, - gid: stat.gid, - rdev: stat.rdev, - size: stat.size, - atime: stat.atime, - mtime: stat.mtime, - ctime: stat.ctime, - blksize: stat.blksize, - blocks: stat.blocks - }; + if (attr.size !== undefined) { + truncate(path, attr.size); + } + }); + }, + node_ops: { + getattr(node) { + var path = NODEFS.realPath(node); + return NODEFS.getattr(() => fs.lstatSync(path)); }, setattr(node, attr) { var path = NODEFS.realPath(node); - NODEFS.tryFSOperation(() => { - if (attr.mode !== undefined) { - var mode = attr.mode; - if (NODEFS.isWindows) { - // Windows only supports S_IREAD / S_IWRITE (S_IRUSR / S_IWUSR) - // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/chmod-wchmod - mode &= {{{ cDefs.S_IRUSR | cDefs.S_IWUSR }}}; - } - fs.chmodSync(path, mode); - // update the common node structure mode as well - node.mode = attr.mode; - } - if (attr.timestamp !== undefined) { - var date = new Date(attr.timestamp); - fs.utimesSync(path, date, date); - } - if (attr.size !== undefined) { - fs.truncateSync(path, attr.size); - } - }); + NODEFS.setattr(path, node, attr, fs.chmodSync, fs.utimesSync, fs.truncateSync); }, lookup(parent, name) { var path = PATH.join2(NODEFS.realPath(parent), name); @@ -228,6 +232,12 @@ addToLibrary({ } }, stream_ops: { + getattr(stream) { + return NODEFS.getattr(() => fs.fstatSync(stream.nfd)); + }, + setattr(stream, attr) { + NODEFS.setattr(stream.nfd, stream.node, attr, fs.fchmodSync, fs.futimesSync, fs.ftruncateSync); + }, open(stream) { var path = NODEFS.realPath(stream.node); NODEFS.tryFSOperation(() => { diff --git a/test/fs/test_stat_unnamed_file_descriptor.c b/test/fs/test_stat_unnamed_file_descriptor.c index 2df54f75fd5dc..eb31cded85b7f 100644 --- a/test/fs/test_stat_unnamed_file_descriptor.c +++ b/test/fs/test_stat_unnamed_file_descriptor.c @@ -4,7 +4,27 @@ #include #include "stdio.h" +#ifdef __EMSCRIPTEN__ +#include +#endif + +void makedir(const char *dir) { + int rtn = mkdir(dir, 0777); + assert(rtn == 0); +} + +void changedir(const char *dir) { + int rtn = chdir(dir); + assert(rtn == 0); +} + + int main() { + makedir("working"); +#if defined(__EMSCRIPTEN__) && defined(NODEFS) + EM_ASM(FS.mount(NODEFS, { root: '.' }, 'working')); +#endif + changedir("working"); int fd = open("file.txt", O_RDWR | O_CREAT, 0666); unlink("file.txt"); int res; @@ -12,5 +32,9 @@ int main() { 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 5650e72b72669..8df04c202c7a8 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5921,9 +5921,18 @@ def test_fs_64bit(self): self.set_setting('FORCE_FILESYSTEM') self.do_runf('fs/test_64bit.c', 'success') - @also_with_noderawfs - def test_fs_stat_unnamed_file_descriptor(self): + @requires_node + @parameterized({ + '': ([],), + 'nodefs': (['-DNODEFS', '-lnodefs.js'],), + 'noderawfs':(['-sNODERAWFS'],), + }) + def test_fs_stat_unnamed_file_descriptor(self, args): + self.emcc_args += args + nodefs = '-DNODEFS' in args or '-DNODERAWFS' in 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') From cad0ddfa8fbf35c782d4202dc51dc620f048e25b Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 10:19:49 +0100 Subject: [PATCH 05/31] Fix indentation --- src/library_nodefs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_nodefs.js b/src/library_nodefs.js index f8a263cf7cd58..e67a96c10cb6b 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -117,8 +117,8 @@ addToLibrary({ return newFlags; }, getattr(func) { - var stat = NODEFS.tryFSOperation(func); - if (NODEFS.isWindows) { + var stat = NODEFS.tryFSOperation(func); + if (NODEFS.isWindows) { // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake // them with default blksize of 4096. // See http://support.microsoft.com/kb/140365 From 8b1711e3ac382679bd813dc513c85aae3cb4f7aa Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 10:25:36 +0100 Subject: [PATCH 06/31] Apply review comments to test --- test/fs/test_stat_unnamed_file_descriptor.c | 38 ++++++++++++--------- test/test_core.py | 3 +- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/test/fs/test_stat_unnamed_file_descriptor.c b/test/fs/test_stat_unnamed_file_descriptor.c index eb31cded85b7f..07afb54c5769e 100644 --- a/test/fs/test_stat_unnamed_file_descriptor.c +++ b/test/fs/test_stat_unnamed_file_descriptor.c @@ -18,23 +18,27 @@ void changedir(const char *dir) { assert(rtn == 0); } - -int main() { - makedir("working"); +void setup() { #if defined(__EMSCRIPTEN__) && defined(NODEFS) - EM_ASM(FS.mount(NODEFS, { root: '.' }, 'working')); + makedir("working"); + EM_ASM(FS.mount(NODEFS, { root: '.' }, 'working')); + changedir("working"); #endif - changedir("working"); - 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"); +} + + +int main() { + setup(); + 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 8df04c202c7a8..c2206542ea6fe 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5928,13 +5928,12 @@ def test_fs_64bit(self): 'noderawfs':(['-sNODERAWFS'],), }) def test_fs_stat_unnamed_file_descriptor(self, args): - self.emcc_args += args nodefs = '-DNODEFS' in args or '-DNODERAWFS' in 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') + self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success', emcc_args=args) def test_sigalrm(self): self.do_runf('test_sigalrm.c', 'Received alarm!') From c961354b6ea4cd585ac473787c6094783ea1eb6c Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 10:31:28 +0100 Subject: [PATCH 07/31] Fix flake8 --- test/test_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_core.py b/test/test_core.py index c2206542ea6fe..8960fa3eb641a 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5925,7 +5925,7 @@ def test_fs_64bit(self): @parameterized({ '': ([],), 'nodefs': (['-DNODEFS', '-lnodefs.js'],), - 'noderawfs':(['-sNODERAWFS'],), + 'noderawfs': (['-sNODERAWFS'],), }) def test_fs_stat_unnamed_file_descriptor(self, args): nodefs = '-DNODEFS' in args or '-DNODERAWFS' in args From bebfc6bd61870a0803bbb3c0b43c7a36b83e52e7 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 10:36:23 +0100 Subject: [PATCH 08/31] Better argment names and comments --- src/library_nodefs.js | 15 +++++++++++---- src/library_syscall.js | 7 ++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/library_nodefs.js b/src/library_nodefs.js index e67a96c10cb6b..85b5139bfcab6 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -148,7 +148,14 @@ addToLibrary({ blocks: stat.blocks }; }, - setattr(path, node, attr, chmod, utimes, truncate) { + // Common code for both node and stream setattr + // For node getatrr: + // - arg is a native path + // - chmod, utimes, truncate are fs.chmodSync, fs.utimesSync, fs.truncateSync + // For stream getatrr: + // - arg is a native file descriptor + // - chmod, utimes, truncate are fs.fchmodSync, fs.futimesSync, fs.ftruncateSync + setattr(arg, node, attr, chmod, utimes, truncate) { NODEFS.tryFSOperation(() => { if (attr.mode !== undefined) { var mode = attr.mode; @@ -157,16 +164,16 @@ addToLibrary({ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/chmod-wchmod mode &= {{{ cDefs.S_IRUSR | cDefs.S_IWUSR }}}; } - chmod(path, mode); + chmod(arg, mode); // update the common node structure mode as well node.mode = attr.mode; } if (attr.timestamp !== undefined) { var date = new Date(attr.timestamp); - utimes(path, date, date); + utimes(arg, date, date); } if (attr.size !== undefined) { - truncate(path, attr.size); + truncate(arg, attr.size); } }); }, diff --git a/src/library_syscall.js b/src/library_syscall.js index ad294fce787c1..e30be1cc36556 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -40,9 +40,10 @@ var SyscallsLibrary = { } return PATH.join2(dir, path); }, - - doStat(func, path, buf) { - var stat = func(path); + // When called by stat, arg is a path. When called by fstat, arg is a file + // descriptor. + doStat(func, arg, buf) { + var stat = func(arg); {{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', SIZE_TYPE) }}}; From 7f4533ec9b42024e244194c89c35130532d066a9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 14:09:39 +0100 Subject: [PATCH 09/31] Fix ftruncate --- src/library_fs.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/library_fs.js b/src/library_fs.js index 2edf9758c2db8..9faee73ea0388 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1047,6 +1047,9 @@ FS.staticInit(); }); }, ftruncate(fd, len) { + if (len < 0) { + throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); + } var stream = FS.getStreamChecked(fd); var node = stream.node; if ((stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { From 2c415714d8a3b8df5d78bdabd41e99b695c66d9a Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 21:28:02 +0100 Subject: [PATCH 10/31] Fix directory fds for nameless file patch --- src/library_nodefs.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/library_nodefs.js b/src/library_nodefs.js index 85b5139bfcab6..ced3d877e6148 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -248,15 +248,13 @@ addToLibrary({ open(stream) { var path = NODEFS.realPath(stream.node); NODEFS.tryFSOperation(() => { - if (FS.isFile(stream.node.mode)) { - stream.shared.refcount = 1; - stream.nfd = fs.openSync(path, NODEFS.flagsForNode(stream.flags)); - } + stream.shared.refcount = 1; + stream.nfd = fs.openSync(path, NODEFS.flagsForNode(stream.flags)); }); }, close(stream) { NODEFS.tryFSOperation(() => { - if (FS.isFile(stream.node.mode) && stream.nfd && --stream.shared.refcount === 0) { + if (stream.nfd && --stream.shared.refcount === 0) { fs.closeSync(stream.nfd); } }); From 6a4dfc2bb2ddd8e24b42d694dbe0d7155e19a757 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 21:45:09 +0100 Subject: [PATCH 11/31] Implement both truncate and ftruncate via truncateCommon --- src/library_fs.js | 52 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 9faee73ea0388..553a846291876 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1017,45 +1017,25 @@ FS.staticInit(); } throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, - truncate(path, len) { + truncateCommon(arg, len, ftruncate) { if (len < 0) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: true }); + var stream; + if (ftruncate) { + stream = FS.getStreamChecked(arg); + if ((stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { + throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); + } + node = stream.node; + } else if (typeof arg == 'string') { + var lookup = FS.lookupPath(arg, { follow: true }); node = lookup.node; } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError({{{ cDefs.EPERM }}}); - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError({{{ cDefs.EISDIR }}}); - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); - } - var errCode = FS.nodePermissions(node, 'w'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - node.node_ops.setattr(node, { - size: len, - timestamp: Date.now() - }); - }, - ftruncate(fd, len) { - if (len < 0) { - throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); + node = arg; } - var stream = FS.getStreamChecked(fd); - var node = stream.node; - if ((stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { - throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); - } - if (!node.node_ops.setattr && !stream.stream_ops.setattr) { + if (!node.node_ops.setattr && !stream?.stream_ops.setattr) { throw new FS.ErrnoError({{{ cDefs.EPERM }}}); } if (FS.isDir(node.mode)) { @@ -1072,12 +1052,18 @@ FS.staticInit(); size: len, timestamp: Date.now() }; - if (stream.stream_ops.setattr) { + if (stream?.stream_ops.setattr) { stream.stream_ops.setattr(stream, attrs); } else { node.node_ops.setattr(node, attrs); } }, + truncate(path, len) { + FS.truncateCommon(path, len, false); + }, + ftruncate(fd, len) { + FS.truncateCommon(fd, len, true); + }, utime(path, atime, mtime) { var lookup = FS.lookupPath(path, { follow: true }); var node = lookup.node; From 3aa358f91ede440265ae112ee529260946c288cc Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 6 Dec 2024 13:10:15 +0100 Subject: [PATCH 12/31] Fix merge --- 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 21a0c27fb49ff..a843fcabace66 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -975,7 +975,7 @@ FS.staticInit(); var node = stream.node; var attrs = { mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (node.mode & ~{{{ cDefs.S_IALLUGO }}}), - timestamp: Date.now() + ctime: Date.now() }; if (stream.stream_ops.getattr) { return stream.stream_ops.setattr(stream, attrs); From 989cf22b8aa5080ad0ec2f2dfa76b2eeac1cbbb9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 9 Dec 2024 19:00:56 +0100 Subject: [PATCH 13/31] Refactor things a bit more --- src/library_fs.js | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index c230def49becf..18acfd725648d 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1028,24 +1028,7 @@ FS.staticInit(); } throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, - truncateCommon(arg, len, ftruncate) { - if (len < 0) { - throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); - } - var node; - var stream; - if (ftruncate) { - stream = FS.getStreamChecked(arg); - if ((stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { - throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); - } - node = stream.node; - } else if (typeof arg == 'string') { - var lookup = FS.lookupPath(arg, { follow: true }); - node = lookup.node; - } else { - node = arg; - } + truncateCommon(node, stream, len) { if (!node.node_ops.setattr && !stream?.stream_ops.setattr) { throw new FS.ErrnoError({{{ cDefs.EPERM }}}); } @@ -1070,10 +1053,24 @@ FS.staticInit(); } }, truncate(path, len) { - FS.truncateCommon(path, len, false); + if (len < 0) { + throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); + } + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: true }); + node = lookup.node; + } else { + node = path; + } + FS.truncateCommon(node, undefined, len, false); }, ftruncate(fd, len) { - FS.truncateCommon(fd, len, true); + if (len < 0) { + throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); + } + stream = FS.getStreamChecked(fd); + FS.truncateCommon(stream.node, stream, len); }, utime(path, atime, mtime) { var lookup = FS.lookupPath(path, { follow: true }); From ad024029bc2ad66b11a7cec4b0779338c8850d2d Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 9 Dec 2024 19:05:42 +0100 Subject: [PATCH 14/31] Change doStat to writeStat --- src/library_syscall.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/library_syscall.js b/src/library_syscall.js index 7d548c36ca3d7..0eca3b0f10fc3 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -42,8 +42,7 @@ var SyscallsLibrary = { }, // When called by stat, arg is a path. When called by fstat, arg is a file // descriptor. - doStat(func, arg, buf) { - var stat = func(arg); + writeStat(buf, statResult) { {{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', SIZE_TYPE) }}}; @@ -673,14 +672,14 @@ var SyscallsLibrary = { }, __syscall_stat64: (path, buf) => { path = SYSCALLS.getStr(path); - return SYSCALLS.doStat(FS.stat, path, buf); + return SYSCALLS.writeStat(buf, FS.stat(path)); }, __syscall_lstat64: (path, buf) => { path = SYSCALLS.getStr(path); - return SYSCALLS.doStat(FS.lstat, path, buf); + return SYSCALLS.writeStat(buf, FS.lstat(path)); }, __syscall_fstat64: (fd, buf) => { - return SYSCALLS.doStat(FS.fstat, fd, buf); + return SYSCALLS.writeStat(buf, FS.fstat(fd)); }, __syscall_fchown32: (fd, owner, group) => { FS.fchown(fd, owner, group); @@ -872,7 +871,7 @@ var SyscallsLibrary = { assert(!flags, `unknown flags in __syscall_newfstatat: ${flags}`); #endif path = SYSCALLS.calculateAt(dirfd, path, allowEmpty); - return SYSCALLS.doStat(nofollow ? FS.lstat : FS.stat, path, buf); + return SYSCALLS.writeStat(buf, nofollow ? FS.lstat(path) : FS.stat(path)); }, __syscall_unlinkat: (dirfd, path, flags) => { path = SYSCALLS.getStr(path); From 84bcf309bfc4396d417baccc1196a128da98b808 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 9 Dec 2024 20:11:34 +0100 Subject: [PATCH 15/31] Fix tests --- src/library_syscall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library_syscall.js b/src/library_syscall.js index 0eca3b0f10fc3..ddc6627e215a8 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -42,7 +42,7 @@ var SyscallsLibrary = { }, // When called by stat, arg is a path. When called by fstat, arg is a file // descriptor. - writeStat(buf, statResult) { + writeStat(buf, stat) { {{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', SIZE_TYPE) }}}; From ba3573084b283c526b38f8dbe106b79030708632 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 9 Dec 2024 20:22:28 +0100 Subject: [PATCH 16/31] Fix reference error --- src/library_nodefs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library_nodefs.js b/src/library_nodefs.js index e749df107de3a..0e5948318906f 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -171,7 +171,7 @@ addToLibrary({ if (attr.atime || attr.mtime) { var atime = attr.atime && new Date(attr.atime); var mtime = attr.mtime && new Date(attr.mtime); - fs.utimesSync(path, atime, mtime); + fs.utimesSync(arg, atime, mtime); } if (attr.size !== undefined) { truncate(arg, attr.size); From 4e67e7ff0d5b86d76da0147bfcdb10babca6a0b0 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 10 Dec 2024 16:26:58 +0100 Subject: [PATCH 17/31] Fix test --- src/library_fs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 18acfd725648d..e105c1091d7c4 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1066,10 +1066,10 @@ FS.staticInit(); FS.truncateCommon(node, undefined, len, false); }, ftruncate(fd, len) { - if (len < 0) { + stream = FS.getStreamChecked(fd); + if (len < 0 || (stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } - stream = FS.getStreamChecked(fd); FS.truncateCommon(stream.node, stream, len); }, utime(path, atime, mtime) { From 9399402484ef32a3962c1c067184dca4aef8301c Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 10 Dec 2024 17:44:15 +0100 Subject: [PATCH 18/31] Declare stream variable --- 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 e105c1091d7c4..6ee5e1b153fa6 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1066,7 +1066,7 @@ FS.staticInit(); FS.truncateCommon(node, undefined, len, false); }, ftruncate(fd, len) { - stream = FS.getStreamChecked(fd); + var stream = FS.getStreamChecked(fd); if (len < 0 || (stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } From e83ac75a7eeb09b08ebbe1cff83da5e893275e8a Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 19 Dec 2024 17:23:23 +0100 Subject: [PATCH 19/31] Remove incorrect comment --- src/library_syscall.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/library_syscall.js b/src/library_syscall.js index ddc6627e215a8..e8498517ea048 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -40,8 +40,6 @@ var SyscallsLibrary = { } return dir + '/' + path; }, - // When called by stat, arg is a path. When called by fstat, arg is a file - // descriptor. writeStat(buf, stat) { {{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}}; From b509358211ede56f53af27edb479a6e0d8f28956 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 19 Dec 2024 18:15:37 +0100 Subject: [PATCH 20/31] Fix merge --- src/library_nodefs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library_nodefs.js b/src/library_nodefs.js index 2300b59962647..66294b79387e6 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -134,7 +134,7 @@ addToLibrary({ } return { dev: stat.dev, - ino: node.ino, + ino: node.id, mode: stat.mode, nlink: stat.nlink, uid: stat.uid, From 8c556c8ca0e54ab14ff35534a9ee843b04e61a16 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 19 Dec 2024 19:16:42 +0100 Subject: [PATCH 21/31] Address review comment --- test/fs/test_stat_unnamed_file_descriptor.c | 23 --------------------- test/test_core.py | 8 ++----- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/test/fs/test_stat_unnamed_file_descriptor.c b/test/fs/test_stat_unnamed_file_descriptor.c index 07afb54c5769e..aa6653e0cacb1 100644 --- a/test/fs/test_stat_unnamed_file_descriptor.c +++ b/test/fs/test_stat_unnamed_file_descriptor.c @@ -4,29 +4,6 @@ #include #include "stdio.h" -#ifdef __EMSCRIPTEN__ -#include -#endif - -void makedir(const char *dir) { - int rtn = mkdir(dir, 0777); - assert(rtn == 0); -} - -void changedir(const char *dir) { - int rtn = chdir(dir); - assert(rtn == 0); -} - -void setup() { -#if defined(__EMSCRIPTEN__) && defined(NODEFS) - makedir("working"); - EM_ASM(FS.mount(NODEFS, { root: '.' }, 'working')); - changedir("working"); -#endif -} - - int main() { setup(); int fd = open("file.txt", O_RDWR | O_CREAT, 0666); diff --git a/test/test_core.py b/test/test_core.py index 64f435f8cf971..6e241290c0021 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5839,12 +5839,8 @@ def test_fs_64bit(self): self.set_setting('FORCE_FILESYSTEM') self.do_runf('fs/test_64bit.c', 'success') - @requires_node - @parameterized({ - '': ([],), - 'nodefs': (['-DNODEFS', '-lnodefs.js'],), - 'noderawfs': (['-sNODERAWFS'],), - }) + @crossplatform + @also_with_nodefs_both def test_fs_stat_unnamed_file_descriptor(self, args): nodefs = '-DNODEFS' in args or '-DNODERAWFS' in args if self.get_setting('WASMFS'): From bdfca8339541bcee595df17f9022286ea4318366 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 6 Jan 2025 23:01:27 +0100 Subject: [PATCH 22/31] Fix test --- test/test_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_core.py b/test/test_core.py index bdcfdc9dd782b..d8952dbff4bac 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5844,8 +5844,8 @@ def test_fs_64bit(self): @crossplatform @also_with_nodefs_both - def test_fs_stat_unnamed_file_descriptor(self, args): - nodefs = '-DNODEFS' in args or '-DNODERAWFS' in args + 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') From 4fdc681ca3b544b94d39e397063d3dc88cf0e86c Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 8 Jan 2025 21:13:40 +0100 Subject: [PATCH 23/31] Fix test --- test/test_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_core.py b/test/test_core.py index d8952dbff4bac..3bbcb1d071de6 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5850,7 +5850,7 @@ def test_fs_stat_unnamed_file_descriptor(self): if nodefs: self.skipTest('NODEFS in WasmFS') self.set_setting('FORCE_FILESYSTEM') - self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success', emcc_args=args) + self.do_runf('fs/test_stat_unnamed_file_descriptor.c', 'success') @requires_node @crossplatform From bfd07c70dc41c28c66584d837b431ca11d69fe54 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 15:45:45 +0100 Subject: [PATCH 24/31] Fix test --- test/fs/test_stat_unnamed_file_descriptor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/test/fs/test_stat_unnamed_file_descriptor.c b/test/fs/test_stat_unnamed_file_descriptor.c index aa6653e0cacb1..a1d92f5cbaba7 100644 --- a/test/fs/test_stat_unnamed_file_descriptor.c +++ b/test/fs/test_stat_unnamed_file_descriptor.c @@ -5,7 +5,6 @@ #include "stdio.h" int main() { - setup(); int fd = open("file.txt", O_RDWR | O_CREAT, 0666); unlink("file.txt"); int res; From ac100ab7476ed1e7e245cc9a3a8b677a444e4396 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:13:04 +0100 Subject: [PATCH 25/31] Move stream ops access to streamGetAttr and streamSetAttr --- src/library_fs.js | 61 +++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 24eb6776dbb3e..e540f54028cf2 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -479,6 +479,26 @@ FS.staticInit(); stream.stream_ops?.dup?.(stream); return stream; }, + streamGetAttr(stream) { + var node = stream.node; + var get; + if (get = stream.stream_ops.getattr) { + return get(stream); + } else if (get = node.node_ops.getattr) { + return get(node); + } + throw new FS.ErrnoError({{{ cDefs.EPERM }}}); + }, + streamSetAttr(stream, attr) { + var node = stream.node; + var set; + if (set = stream.stream_ops.setattr) { + return set(stream, attr); + } else if (set = node.node_ops.setattr) { + return set(node, attr); + } + throw new FS.ErrnoError({{{ cDefs.EPERM }}}); + } // // devices @@ -958,13 +978,7 @@ FS.staticInit(); }, fstat(fd) { var stream = FS.getStreamChecked(fd); - var node = stream.node; - if (stream.stream_ops.getattr) { - return stream.stream_ops.getattr(stream); - } else if (node.node_ops.getattr) { - return node.node_ops.getattr(node); - } - throw new FS.ErrnoError({{{ cDefs.EPERM }}}); + return FS.streamGetAttr(stream); }, lstat(path) { return FS.stat(path, true); @@ -991,16 +1005,10 @@ FS.staticInit(); }, fchmod(fd, mode) { var stream = FS.getStreamChecked(fd); - var node = stream.node; - var attrs = { + FS.streamSetAttr(stream, { mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (node.mode & ~{{{ cDefs.S_IALLUGO }}}), ctime: Date.now() - }; - if (stream.stream_ops.getattr) { - return stream.stream_ops.setattr(stream, attrs); - } else if (node.node_ops.getattr) { - return node.node_ops.setattr(node, attrs); - } + }); throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, chown(path, uid, gid, dontFollow) { @@ -1025,22 +1033,12 @@ FS.staticInit(); }, fchown(fd, uid, gid) { var stream = FS.getStreamChecked(fd); - var node = stream.node; - var attrs = { + FS.streamSetAttr(stream, { timestamp: Date.now() // we ignore the uid / gid for now - }; - if (stream.stream_ops.getattr) { - return stream.stream_ops.setattr(stream, attrs); - } else if (node.node_ops.getattr) { - return node.node_ops.setattr(node, attrs); - } - throw new FS.ErrnoError({{{ cDefs.EPERM }}}); + };); }, truncateCommon(node, stream, len) { - if (!node.node_ops.setattr && !stream?.stream_ops.setattr) { - throw new FS.ErrnoError({{{ cDefs.EPERM }}}); - } if (FS.isDir(node.mode)) { throw new FS.ErrnoError({{{ cDefs.EISDIR }}}); } @@ -1051,15 +1049,10 @@ FS.staticInit(); if (errCode) { throw new FS.ErrnoError(errCode); } - var attrs = { + FS.streamSetAttr(stream, { size: len, timestamp: Date.now() - }; - if (stream?.stream_ops.setattr) { - stream.stream_ops.setattr(stream, attrs); - } else { - node.node_ops.setattr(node, attrs); - } + }); }, truncate(path, len) { if (len < 0) { From d1f1962dba720a029f84a07ea0ca29eabe53fe8e Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:16:11 +0100 Subject: [PATCH 26/31] Fix syntax error --- 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 e540f54028cf2..14dedb524a1c8 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -498,7 +498,7 @@ FS.staticInit(); return set(node, attr); } throw new FS.ErrnoError({{{ cDefs.EPERM }}}); - } + }, // // devices From 02e0b69d76ac6f37fc55eae4d228495415914daa Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:18:53 +0100 Subject: [PATCH 27/31] Slightly shorter --- src/library_fs.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 14dedb524a1c8..0bd722309f886 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -481,11 +481,11 @@ FS.staticInit(); }, streamGetAttr(stream) { var node = stream.node; - var get; - if (get = stream.stream_ops.getattr) { - return get(stream); - } else if (get = node.node_ops.getattr) { - return get(node); + var res; + if (res = stream.stream_ops?.getattr?.(stream)) { + return res; + } else if (res = node.node_ops?.getattr?.(node)) { + return res; } throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, From 910b824429b78377091b305c6316fa53a0c3e86b Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:20:04 +0100 Subject: [PATCH 28/31] Slightly shorter --- src/library_fs.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 0bd722309f886..5e2079941b085 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -481,10 +481,8 @@ FS.staticInit(); }, streamGetAttr(stream) { var node = stream.node; - var res; - if (res = stream.stream_ops?.getattr?.(stream)) { - return res; - } else if (res = node.node_ops?.getattr?.(node)) { + var res = stream.stream_ops?.getattr?.(stream) ?? node.node_ops?.getattr?.(node); + if (res) { return res; } throw new FS.ErrnoError({{{ cDefs.EPERM }}}); From 37f8ee99fa703c23d549deea0f9cc0b795693ef3 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:25:42 +0100 Subject: [PATCH 29/31] Some fixes --- src/library_fs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 5e2079941b085..e5947ad9943e8 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1004,7 +1004,7 @@ FS.staticInit(); fchmod(fd, mode) { var stream = FS.getStreamChecked(fd); FS.streamSetAttr(stream, { - mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (node.mode & ~{{{ cDefs.S_IALLUGO }}}), + mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (stream.node.mode & ~{{{ cDefs.S_IALLUGO }}}), ctime: Date.now() }); throw new FS.ErrnoError({{{ cDefs.EPERM }}}); @@ -1034,7 +1034,7 @@ FS.staticInit(); FS.streamSetAttr(stream, { timestamp: Date.now() // we ignore the uid / gid for now - };); + }); }, truncateCommon(node, stream, len) { if (FS.isDir(node.mode)) { From 5eef321e88912fd2c7b675d31247c8a4a178f6d3 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:26:47 +0100 Subject: [PATCH 30/31] Fix more --- src/library_fs.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/library_fs.js b/src/library_fs.js index e5947ad9943e8..2a45cc77fcf14 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1007,7 +1007,6 @@ FS.staticInit(); mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (stream.node.mode & ~{{{ cDefs.S_IALLUGO }}}), ctime: Date.now() }); - throw new FS.ErrnoError({{{ cDefs.EPERM }}}); }, chown(path, uid, gid, dontFollow) { var node; From ad6f42a08d86f6ea1fa2c87e0e8cecfd2e3f65b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 9 Jan 2025 21:30:29 +0100 Subject: [PATCH 31/31] More fixes --- src/library_fs.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 2a45cc77fcf14..0df60d410a511 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1035,7 +1035,7 @@ FS.staticInit(); // we ignore the uid / gid for now }); }, - truncateCommon(node, stream, len) { + truncateChecks(node) { if (FS.isDir(node.mode)) { throw new FS.ErrnoError({{{ cDefs.EISDIR }}}); } @@ -1046,10 +1046,6 @@ FS.staticInit(); if (errCode) { throw new FS.ErrnoError(errCode); } - FS.streamSetAttr(stream, { - size: len, - timestamp: Date.now() - }); }, truncate(path, len) { if (len < 0) { @@ -1062,14 +1058,21 @@ FS.staticInit(); } else { node = path; } - FS.truncateCommon(node, undefined, len, false); + node.node_ops.setattr(node, { + size: len, + timestamp: Date.now() + }); }, ftruncate(fd, len) { var stream = FS.getStreamChecked(fd); if (len < 0 || (stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } - FS.truncateCommon(stream.node, stream, len); + FS.truncateChecks(stream.node); + FS.streamSetAttr(stream, { + size: len, + timestamp: Date.now() + }); }, utime(path, atime, mtime) { var lookup = FS.lookupPath(path, { follow: true });