From f7a572df8c14b5baad262db7331ac4eab34a5bcb Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Thu, 19 Mar 2026 16:56:45 +0000 Subject: [PATCH 1/2] syscall: Accept O_NONBLOCK flag in pipe2 pipe2 only accepted O_CLOEXEC, rejecting O_NONBLOCK with ENOTSUP. Accept O_NONBLOCK and set it on the created pipe streams. This is needed by GLib's GWakeup which uses pipe2(fds, O_CLOEXEC | O_NONBLOCK). --- src/lib/libsyscall.js | 8 +++++++- test/codesize/test_codesize_cxx_lto.json | 4 ++-- test/codesize/test_codesize_hello_dylink_all.json | 6 +++--- test/unistd/misc.c | 8 ++++++++ test/unistd/misc.out | 4 ++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/lib/libsyscall.js b/src/lib/libsyscall.js index cbc5d3d0a5774..9769e87d4d9cd 100644 --- a/src/lib/libsyscall.js +++ b/src/lib/libsyscall.js @@ -199,12 +199,18 @@ var SyscallsLibrary = { if (fdPtr == 0) { throw new FS.ErrnoError({{{ cDefs.EFAULT }}}); } - if (flags && flags != {{{ cDefs.O_CLOEXEC }}}) { + var validFlags = {{{ cDefs.O_CLOEXEC }}} | {{{ cDefs.O_NONBLOCK }}}; + if (flags & ~validFlags) { throw new FS.ErrnoError({{{ cDefs.ENOTSUP }}}); } var res = PIPEFS.createPipe(); + if (flags & {{{ cDefs.O_NONBLOCK }}}) { + FS.getStream(res.readable_fd).flags |= {{{ cDefs.O_NONBLOCK }}}; + FS.getStream(res.writable_fd).flags |= {{{ cDefs.O_NONBLOCK }}}; + } + {{{ makeSetValue('fdPtr', 0, 'res.readable_fd', 'i32') }}}; {{{ makeSetValue('fdPtr', 4, 'res.writable_fd', 'i32') }}}; diff --git a/test/codesize/test_codesize_cxx_lto.json b/test/codesize/test_codesize_cxx_lto.json index 7bea9337c40d2..f92589e8aecc0 100644 --- a/test/codesize/test_codesize_cxx_lto.json +++ b/test/codesize/test_codesize_cxx_lto.json @@ -2,9 +2,9 @@ "a.out.js": 18563, "a.out.js.gz": 7666, "a.out.nodebug.wasm": 101956, - "a.out.nodebug.wasm.gz": 39460, + "a.out.nodebug.wasm.gz": 39461, "total": 120519, - "total_gz": 47126, + "total_gz": 47127, "sent": [ "a (emscripten_resize_heap)", "b (_setitimer_js)", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index acfb97308b036..c46d7869829e7 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 244300, - "a.out.nodebug.wasm": 577444, - "total": 821744, + "a.out.js": 244343, + "a.out.nodebug.wasm": 577451, + "total": 821794, "sent": [ "IMG_Init", "IMG_Load", diff --git a/test/unistd/misc.c b/test/unistd/misc.c index 3efcbad477a63..190582957f200 100644 --- a/test/unistd/misc.c +++ b/test/unistd/misc.c @@ -86,6 +86,14 @@ int main() { printf("pipe2(bad): %d", pipe2(0, 0)); printf(", errno: %d\n", errno); errno = 0; + printf("pipe2(O_NONBLOCK): %d", pipe2(pipe_arg, O_NONBLOCK)); + printf(", errno: %d\n", errno); + printf("pipe2(O_NONBLOCK) read flags: %d\n", (fcntl(pipe_arg[0], F_GETFL) & O_NONBLOCK) != 0); + printf("pipe2(O_NONBLOCK) write flags: %d\n", (fcntl(pipe_arg[1], F_GETFL) & O_NONBLOCK) != 0); + errno = 0; + printf("pipe2(O_CLOEXEC|O_NONBLOCK): %d", pipe2(pipe_arg, O_CLOEXEC | O_NONBLOCK)); + printf(", errno: %d\n", errno); + errno = 0; char* exec_argv[] = {"arg", 0}; char* exec_env[] = {"a=b", 0}; diff --git a/test/unistd/misc.out b/test/unistd/misc.out index 17e5b17ffa0e5..4ed4b37a3b5fd 100644 --- a/test/unistd/misc.out +++ b/test/unistd/misc.out @@ -15,6 +15,10 @@ pipe(good): 0, errno: 0 pipe(bad): -1, errno: 21 pipe2(good): 0, errno: 0 pipe2(bad): -1, errno: 21 +pipe2(O_NONBLOCK): 0, errno: 0 +pipe2(O_NONBLOCK) read flags: 1 +pipe2(O_NONBLOCK) write flags: 1 +pipe2(O_CLOEXEC|O_NONBLOCK): 0, errno: 0 execl: -1, errno: 45 execle: -1, errno: 45 execlp: -1, errno: 45 From 6a7d9830e6d896bebd572450654482c20a0cd05e Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 31 Mar 2026 09:08:00 -0700 Subject: [PATCH 2/2] codesize --- test/codesize/test_codesize_cxx_lto.json | 4 ++-- test/codesize/test_codesize_hello_dylink_all.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/codesize/test_codesize_cxx_lto.json b/test/codesize/test_codesize_cxx_lto.json index f92589e8aecc0..7bea9337c40d2 100644 --- a/test/codesize/test_codesize_cxx_lto.json +++ b/test/codesize/test_codesize_cxx_lto.json @@ -2,9 +2,9 @@ "a.out.js": 18563, "a.out.js.gz": 7666, "a.out.nodebug.wasm": 101956, - "a.out.nodebug.wasm.gz": 39461, + "a.out.nodebug.wasm.gz": 39460, "total": 120519, - "total_gz": 47127, + "total_gz": 47126, "sent": [ "a (emscripten_resize_heap)", "b (_setitimer_js)", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index c46d7869829e7..259c8f515c742 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { "a.out.js": 244343, - "a.out.nodebug.wasm": 577451, - "total": 821794, + "a.out.nodebug.wasm": 577444, + "total": 821787, "sent": [ "IMG_Init", "IMG_Load",