@@ -23,24 +23,27 @@ int __syscall_getuid32(void) {
2323 return __syscall_getuid32_js ();
2424}
2525
26- EM_JS (int , __syscall_umask_js , (int mask ), {
27- // If we're in node and we can, call native process.umask()
26+ // Emscripten's syscall layer tracks the umask in SYSCALLS.currentUmask and
27+ // applies it itself when creating files and directories. We mount the real
28+ // filesystem via NODEFS, which applies proces.umask() to everything as well. To
29+ // avoid masking the mode twice, read and zero out process umask at startup,
30+ // and store it as emscripten's umask.
31+ EM_JS (void , __syscall_init_umask_js , (void ) , {
2832 if (ENVIRONMENT_IS_NODE ) {
2933 try {
30- return process .umask (mask );
31- } catch (e ) {
32- // oops...
33- // NodeJS docs: "In Worker threads, process.umask(mask) will throw an exception."
34- // umask docs: "This system call always succeeds"
35- return 0 ;
34+ // process.umask(0) returns the previous umask and sets it to 0.
35+ SYSCALLS .currentUmask = process .umask (0 );
36+ } catch (e ) {
37+ // NodeJS docs: "In Worker threads, process.umask(mask) will throw an
38+ // exception." In that case just keep emscripten's default umask.
3639 }
3740 }
38- // Fall back to the stub case of returning 0.
39- return 0 ;
4041})
4142
42- int __syscall_umask (int mask ) {
43- return __syscall_umask_js (mask );
43+ EM_JS_DEPS (__syscall_init_umask , "$SYSCALLS" );
44+
45+ __attribute__((constructor )) void __syscall_init_umask (void ) {
46+ __syscall_init_umask_js ();
4447}
4548
4649#include <wasi/api.h>
@@ -290,6 +293,26 @@ int __syscall_poll(intptr_t fds, int nfds, int timeout) {
290293 return __block_for_int (p );
291294}
292295
296+
297+ // Workaround for an Emscripten bug: getentropy(buffer, 1) returns the single
298+ // byte of entropy as the return code. Fixed upstream by
299+ // emscripten-core/emscripten#27122
300+ int __real_getentropy (void * , size_t );
301+
302+ int __wrap_getentropy (void * buffer , size_t len ) {
303+ if (len != 1 ) {
304+ return __real_getentropy (buffer , len );
305+ }
306+ // Length is 1. Workaround is to get two bytes of entropy and write the
307+ // first one into the original target buffer.
308+ uint8_t tmp [2 ];
309+ int ret = __real_getentropy (tmp , 2 );
310+ if (ret == 0 ) {
311+ * (uint8_t * )buffer = tmp [0 ];
312+ }
313+ return ret ;
314+ }
315+
293316#include <sys/ioctl.h>
294317
295318int syscall_ioctl_orig (int fd , int request , void * varargs )
0 commit comments