forked from pyodide/pyodide
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backport of emscripten-core/emscripten#21399. Resolves pyodide#4541
- Loading branch information
Showing
1 changed file
with
166 additions
and
0 deletions.
There are no files selected for viewing
166 changes: 166 additions & 0 deletions
166
emsdk/patches/0001-Fix-dup-in-nodefs-by-refcounting-nodefs-file-descrip.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
From 135baa3d4cc211c0145d2e1df116e39f60df4f91 Mon Sep 17 00:00:00 2001 | ||
From: Hood Chatham <roberthoodchatham@gmail.com> | ||
Date: Thu, 22 Feb 2024 21:47:13 -0800 | ||
Subject: [PATCH] Fix dup in nodefs by refcounting nodefs file descriptors | ||
(#21399) | ||
|
||
--- | ||
src/library_fs.js | 5 +++++ | ||
src/library_nodefs.js | 6 +++++- | ||
src/library_syscall.js | 6 +++--- | ||
test/fs/test_nodefs_dup.c | 45 +++++++++++++++++++++++++++++++++++++++ | ||
test/test_core.py | 8 +++++++ | ||
5 files changed, 66 insertions(+), 4 deletions(-) | ||
create mode 100644 test/fs/test_nodefs_dup.c | ||
|
||
diff --git a/src/library_fs.js b/src/library_fs.js | ||
index f5d16b86c..379e65268 100644 | ||
--- a/src/library_fs.js | ||
+++ b/src/library_fs.js | ||
@@ -471,6 +471,11 @@ FS.staticInit();` + | ||
closeStream(fd) { | ||
FS.streams[fd] = null; | ||
}, | ||
+ dupStream(origStream, fd = -1) { | ||
+ var stream = FS.createStream(origStream, fd); | ||
+ stream.stream_ops?.dup?.(stream); | ||
+ return stream; | ||
+ }, | ||
|
||
// | ||
// devices | ||
diff --git a/src/library_nodefs.js b/src/library_nodefs.js | ||
index 81864ffcc..ace50458c 100644 | ||
--- a/src/library_nodefs.js | ||
+++ b/src/library_nodefs.js | ||
@@ -251,6 +251,7 @@ addToLibrary({ | ||
var path = NODEFS.realPath(stream.node); | ||
try { | ||
if (FS.isFile(stream.node.mode)) { | ||
+ stream.shared.refcount = 1; | ||
stream.nfd = fs.openSync(path, NODEFS.flagsForNode(stream.flags)); | ||
} | ||
} catch (e) { | ||
@@ -260,7 +261,7 @@ addToLibrary({ | ||
}, | ||
close(stream) { | ||
try { | ||
- if (FS.isFile(stream.node.mode) && stream.nfd) { | ||
+ if (FS.isFile(stream.node.mode) && stream.nfd && --stream.shared.refcount === 0) { | ||
fs.closeSync(stream.nfd); | ||
} | ||
} catch (e) { | ||
@@ -268,6 +269,9 @@ addToLibrary({ | ||
throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); | ||
} | ||
}, | ||
+ dup(stream) { | ||
+ stream.shared.refcount++; | ||
+ }, | ||
read(stream, buffer, offset, length, position) { | ||
// Node.js < 6 compatibility: node errors on 0 length reads | ||
if (length === 0) return 0; | ||
diff --git a/src/library_syscall.js b/src/library_syscall.js | ||
index b078bd71c..69ea6f8b2 100644 | ||
--- a/src/library_syscall.js | ||
+++ b/src/library_syscall.js | ||
@@ -183,7 +183,7 @@ var SyscallsLibrary = { | ||
}, | ||
__syscall_dup: (fd) => { | ||
var old = SYSCALLS.getStreamFromFD(fd); | ||
- return FS.createStream(old).fd; | ||
+ return FS.dupStream(old).fd; | ||
}, | ||
__syscall_pipe__deps: ['$PIPEFS'], | ||
__syscall_pipe: (fdPtr) => { | ||
@@ -760,7 +760,7 @@ var SyscallsLibrary = { | ||
arg++; | ||
} | ||
var newStream; | ||
- newStream = FS.createStream(stream, arg); | ||
+ newStream = FS.dupStream(stream, arg); | ||
return newStream.fd; | ||
} | ||
case {{{ cDefs.F_GETFD }}}: | ||
@@ -1007,7 +1007,7 @@ var SyscallsLibrary = { | ||
if (old.fd === newfd) return -{{{ cDefs.EINVAL }}}; | ||
var existing = FS.getStream(newfd); | ||
if (existing) FS.close(existing); | ||
- return FS.createStream(old, newfd).fd; | ||
+ return FS.dupStream(old, newfd).fd; | ||
}, | ||
}; | ||
|
||
diff --git a/test/fs/test_nodefs_dup.c b/test/fs/test_nodefs_dup.c | ||
new file mode 100644 | ||
index 000000000..abf34935b | ||
--- /dev/null | ||
+++ b/test/fs/test_nodefs_dup.c | ||
@@ -0,0 +1,45 @@ | ||
+/* | ||
+ * Copyright 2018 The Emscripten Authors. All rights reserved. | ||
+ * Emscripten is available under two separate licenses, the MIT license and the | ||
+ * University of Illinois/NCSA Open Source License. Both these licenses can be | ||
+ * found in the LICENSE file. | ||
+ */ | ||
+ | ||
+#include <assert.h> | ||
+#include <emscripten.h> | ||
+#include <fcntl.h> | ||
+#include <stdio.h> | ||
+#include <unistd.h> | ||
+ | ||
+#ifdef NODERAWFS | ||
+#define CWD "" | ||
+#else | ||
+#define CWD "/working/" | ||
+#endif | ||
+ | ||
+int main(void) | ||
+{ | ||
+ EM_ASM( | ||
+#ifdef NODERAWFS | ||
+ FS.close(FS.open('test.txt', 'w')); | ||
+#else | ||
+ FS.mkdir('/working'); | ||
+ FS.mount(NODEFS, {root: '.'}, '/working'); | ||
+ FS.close(FS.open('/working/test.txt', 'w')); | ||
+#endif | ||
+ ); | ||
+ int fd1 = open(CWD "test.txt", O_WRONLY); | ||
+ int fd2 = dup(fd1); | ||
+ int fd3 = fcntl(fd1, F_DUPFD_CLOEXEC, 0); | ||
+ | ||
+ assert(fd1 == 3); | ||
+ assert(fd2 == 4); | ||
+ assert(fd3 == 5); | ||
+ assert(close(fd1) == 0); | ||
+ assert(write(fd2, "abcdef", 6) == 6); | ||
+ assert(close(fd2) == 0); | ||
+ assert(write(fd3, "ghijkl", 6) == 6); | ||
+ assert(close(fd3) == 0); | ||
+ printf("success\n"); | ||
+ return 0; | ||
+} | ||
diff --git a/test/test_core.py b/test/test_core.py | ||
index 3f21eb5ef..f304f1366 100644 | ||
--- a/test/test_core.py | ||
+++ b/test/test_core.py | ||
@@ -5745,6 +5745,14 @@ Module = { | ||
self.emcc_args += ['-lnodefs.js'] | ||
self.do_runf('fs/test_nodefs_cloexec.c', 'success') | ||
|
||
+ @also_with_noderawfs | ||
+ @requires_node | ||
+ def test_fs_nodefs_dup(self): | ||
+ if self.get_setting('WASMFS'): | ||
+ self.set_setting('FORCE_FILESYSTEM') | ||
+ self.emcc_args += ['-lnodefs.js'] | ||
+ self.do_runf('fs/test_nodefs_dup.c', 'success') | ||
+ | ||
@requires_node | ||
def test_fs_nodefs_home(self): | ||
self.set_setting('FORCE_FILESYSTEM') | ||
-- | ||
2.34.1 | ||
|