emscripten-core / emscripten-core/emscripten
Linking against `noderawfs.js` causes `ioctl_tiocgwinsz` to fail
- Dominant language
- C++
- Stars
- 27.6k
- Forks
- 3.6k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 105
Description
**Version of emscripten/emsdk:**
```
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.61-git (67fa4c16496b157a7fc3377afd69ee0445e8a6e3)
clang version 19.0.0git (/startdir/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /opt/emscripten-llvm/bin
```
**Reproducing steps**
1. Source file content:
```c
#include
#include
#include
#include
#include
#include
#include
void ensure_noderawfs_init() {
int c;
FILE *file;
file = fopen("/etc/hostname", "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
}
void print_tty_size() {
struct winsize ws;
if(ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) { // <--------------------
err(EXIT_FAILURE, "/dev/stdin not a tty");
}
printf("TTY Size: %d x %d\n", ws.ws_row, ws.ws_col);
}
int main() {
ensure_noderawfs_init();
print_tty_size();
return 0;
}
```
2. Compile the code above and run it with node:
```console
$ emcc ioctl_test.c -lnodefs.js -lnoderawfs.js
$ node ./a.out.js
my-host-name
.../ledger/build/a.out.js:128
throw ex;
^
TypeError: Cannot read properties of undefined (reading 'ioctl_tiocgwinsz')
at ___syscall_ioctl (.../ledger/build/a.out.js:4396:30)
...
```
**Failing command line in full:**
```console
$ node ./a.out.js
my-host-name
.../ledger/build/a.out.js:128
throw ex;
^
TypeError: Cannot read properties of undefined (reading 'ioctl_tiocgwinsz')
at ___syscall_ioctl (.../ledger/build/a.out.js:4396:30)
at wasm://wasm/0001a2fa:wasm-function[48]:0x13c2
at wasm://wasm/0001a2fa:wasm-function[13]:0x4af
at wasm://wasm/0001a2fa:wasm-function[14]:0x560
at wasm://wasm/0001a2fa:wasm-function[15]:0x57d
at .../ledger/build/a.out.js:641:12
at callMain (.../ledger/build/a.out.js:4985:15)
at doRun (.../ledger/build/a.out.js:5035:23)
at run (.../ledger/build/a.out.js:5050:5)
at runCaller (.../ledger/build/a.out.js:4970:19)
Node.js v20.12.2
```
Reproducing steps have been attached above.
**Full link command and output with `-v` appended:**
```console
$ emcc ioctl_test.c -lnodefs.js -lnoderawfs.js -v
emcc ioctl_test.c -lnodefs.js -lnoderawfs.js -v 2>&1 | sed 's#/home/otaku/Workspaces/clones#...#g' | sed 's#/home/otaku/#$HOME/#g'
/opt/emscripten-llvm/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=$HOME/.emscripten_cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v ioctl_test.c -c -o /tmp/emscripten_temp_e8xdm84r/ioctl_test_0.o
clang version 19.0.0git (/startdir/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /opt/emscripten-llvm/bin
(in-process)
"/opt/emscripten-llvm/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ioctl_test.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -fvisibility=hidden -debugger-tuning=gdb -fdebug-compilation-dir=.../ledger/build -v -fcoverage-compilation-dir=.../ledger/build -resource-dir /opt/emscripten-llvm/lib/clang/19 -D EMSCRIPTEN -isysroot $HOME/.emscripten_cache/sysroot -internal-isystem /opt/emscripten-llvm/lib/clang/19/include -internal-isystem $HOME/.emscripten_cache/sysroot/include/wasm32-emscripten -internal-isystem $HOME/.emscripten_cache/sysroot/include -Werror=implicit-function-declaration -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /tmp/emscripten_temp_e8xdm84r/ioctl_test_0.o -x c ioctl_test.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "$HOME/.emscripten_cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
$HOME/.emscripten_cache/sysroot/include/fakesdl
$HOME/.emscripten_cache/sysroot/include/compat
/opt/emscripten-llvm/lib/clang/19/include
$HOME/.emscripten_cache/sysroot/include
End of search list.
/opt/emscripten-llvm/bin/clang --version
/opt/emscripten-llvm/bin/wasm-ld -o a.out.wasm /tmp/emscripten_temp_e8xdm84r/ioctl_test_0.o -L$HOME/.emscripten_cache/sysroot/lib/wasm32-emscripten -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpa_r6uqttlibemscripten_js_symbols.so --strip-debug --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=_emscripten_stack_alloc --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=_emscripten_stack_restore --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --no-growable-memory --initial-heap=16777216 --no-entry --stack-first --table-base=1
/opt/emscripten-llvm/bin/llvm-objcopy a.out.wasm a.out.wasm --remove-section=.debug* --remove-section=producers
/usr/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers a.out.wasm -o a.out.wasm --detect-features
/usr/bin/node /usr/lib/emscripten/src/compiler.mjs /tmp/tmpek0bu9lr.json
```
**Extra info**
It seems to come from `library_noderawfs.js` setting `stream.tty` to `true`, while ioctl implementation in `library_syscall.js` expects a TTY object:
https://github.com/emscripten-core/emscripten/blob/a1fe3902bf73a3802eae0357d273d0e37ea79898/src/library_noderawfs.js#L47-L52
https://github.com/emscripten-core/emscripten/blob/a1fe3902bf73a3802eae0357d273d0e37ea79898/src/library_syscall.js#L279-L285
But I couldn't find any documentation on that `tty` field though.
Contributor guide
Assessment
This issue has not been assessed yet.