diff --git a/crates/execution/assets/runners/wasm-runner.mjs b/crates/execution/assets/runners/wasm-runner.mjs index 596567423..309bf7fcf 100644 --- a/crates/execution/assets/runners/wasm-runner.mjs +++ b/crates/execution/assets/runners/wasm-runner.mjs @@ -783,6 +783,7 @@ const stdioTtyCache = new Map(); function stdioFdIsKernelTty(fd) { const descriptor = Number(fd) >>> 0; if (descriptor > 2) return false; + if (KERNEL_STDIO_SYNC_RPC) return true; if (stdioTtyCache.has(descriptor)) return stdioTtyCache.get(descriptor); let isTty = false; try { @@ -4591,7 +4592,6 @@ wasiImport.fd_read = (fd, iovs, iovsLen, nreadPtr) => { const handle = __agentOSWasiMeasurePhase('fd_read', 'lookup_handle', () => lookupFdHandle(numericFd) ); - if (handle?.kind === 'pipe-read') { try { const requestedLength = __agentOSWasiMeasurePhase('fd_read', 'iov_scan', () => { @@ -5147,21 +5147,6 @@ wasiImport.fd_write = (fd, iovs, iovsLen, nwrittenPtr) => { } } - if (handle?.kind === 'passthrough') { - if (handle.readOnly === true) { - return WASI_ERRNO_ROFS; - } - return delegateManagedFdWrite - ? __agentOSWasiMeasurePhase('fd_write', 'delegate_call', () => - delegateManagedFdWrite(handle.targetFd, iovs, iovsLen, nwrittenPtr) - ) - : WASI_ERRNO_BADF; - } - - if (!handle && numericFd <= 2) { - return WASI_ERRNO_BADF; - } - if (numericFd === 1 || numericFd === 2) { try { const bytes = __agentOSWasiMeasurePhase('fd_write', 'guest_iov_collect', () => @@ -5189,6 +5174,21 @@ wasiImport.fd_write = (fd, iovs, iovsLen, nwrittenPtr) => { } } + if (handle?.kind === 'passthrough') { + if (handle.readOnly === true) { + return WASI_ERRNO_ROFS; + } + return delegateManagedFdWrite + ? __agentOSWasiMeasurePhase('fd_write', 'delegate_call', () => + delegateManagedFdWrite(handle.targetFd, iovs, iovsLen, nwrittenPtr) + ) + : WASI_ERRNO_BADF; + } + + if (!handle && numericFd <= 2) { + return WASI_ERRNO_BADF; + } + if (rejectClosedPassthroughFd(fd)) { return WASI_ERRNO_BADF; } @@ -5562,7 +5562,8 @@ const hostTtyImport = { }, // `host_tty.isatty(fd)` -> 1 if the guest fd is a kernel PTY, else 0. isatty(fd) { - return callSyncRpc('__kernel_isatty', [fd >>> 0]) === true ? 1 : 0; + const descriptor = Number(fd) >>> 0; + return descriptor <= 2 && stdioFdIsKernelTty(descriptor) ? 1 : 0; }, // `host_tty.get_size(fd, colsPtr, rowsPtr)` -> writes the PTY window size as two // little-endian u16s and returns 0; non-zero (ENOTTY) if fd is not a PTY. diff --git a/registry/native/c/Makefile b/registry/native/c/Makefile index 66a065250..1e7bcc254 100644 --- a/registry/native/c/Makefile +++ b/registry/native/c/Makefile @@ -673,7 +673,7 @@ $(VIM_WCC): $(WASI_SDK_DIR)/bin/clang $(BUILD_DIR)/vim: fetch-vim $(VIM_BRIDGE_BUILD)/libtermcap.a $(VIM_WCC) wasm-opt-check cd $(VIM_SRC)/src && \ CC="$(abspath $(VIM_WCC))" \ - LDFLAGS="-L$(abspath $(VIM_BRIDGE_BUILD))" \ + LDFLAGS="$(abspath $(VIM_BRIDGE_BUILD)/termios_bridge.o) -L$(abspath $(VIM_BRIDGE_BUILD))" \ vim_cv_toupper_broken=no \ vim_cv_terminfo=no \ vim_cv_tgetent=zero \ diff --git a/registry/native/c/vim/termios_bridge.c b/registry/native/c/vim/termios_bridge.c index d18e19f8f..987fa1a05 100644 --- a/registry/native/c/vim/termios_bridge.c +++ b/registry/native/c/vim/termios_bridge.c @@ -61,10 +61,18 @@ static void ensure_shadow(void) { * apps (vim) print "Output is not to a terminal" and refuse full-screen mode. * host_tty.isatty is the authoritative PTY check the kernel exposes (a strong * symbol overriding the weak libc alias). */ -int isatty(int fd) { +static int bridge_isatty(int fd) { return __host_tty_isatty((unsigned int)fd) ? 1 : 0; } +int __isatty(int fd) { + return bridge_isatty(fd); +} + +int isatty(int fd) { + return bridge_isatty(fd); +} + int tcgetattr(int fd, struct termios *t) { (void)fd; if (!t) { errno = EFAULT; return -1; }