diff --git a/bend2/effs/tcp_connect.js b/bend2/effs/tcp_connect.js index bbcaeb8aab..6a48d46eaa 100644 --- a/bend2/effs/tcp_connect.js +++ b/bend2/effs/tcp_connect.js @@ -4,11 +4,11 @@ // The socket is non-blocking for life: EINPROGRESS parks the computation // until the socket is writable, and then SO_ERROR says how the connect ended. function tcp_connect(host, port, k) { - const sys = io_sys(); const at = io_addr(host, Number(port)); if (at === null) { return io_fail(22); } + const sys = io_sys(); const fd = sys.socket(2, 1, 0); if (fd < 0) { return io_fail(sys.errno()); diff --git a/tests/io/tcp_connect_no_ffi.bend b/tests/io/tcp_connect_no_ffi.bend new file mode 100644 index 0000000000..f0b03d955a --- /dev/null +++ b/tests/io/tcp_connect_no_ffi.bend @@ -0,0 +1,21 @@ +# Invalid connect arguments answer EINVAL even when FFI initialization fails. +# The JS twin models a host without bun:ffi; valid Node TCP stays unsupported. +import Base + +def ffi_absent() -> IO(Unit): + import "./tcp_connect_no_ffi.js" + +def report(r: Result<&1, &1, U32 & String, Socket>) -> IO(Unit): + match r: + case Done{socket}: + Socket.close(socket) + case Fail{(code, message)}: + IO.print(U32.show(code)) + +def main() -> IO(Unit): + do IO: + ffi_absent() + r : Result<&1, &1, U32 & String, Socket> <- TCP.connect("127.0.0.256", 0) + report(r) + +#|22 diff --git a/tests/io/tcp_connect_no_ffi.js b/tests/io/tcp_connect_no_ffi.js new file mode 100644 index 0000000000..0ee3af9893 --- /dev/null +++ b/tests/io/tcp_connect_no_ffi.js @@ -0,0 +1,18 @@ +// Make io_sys initialization fail once, as on a host without bun:ffi. +function ffi_absent_run() { + const prior = Object.getOwnPropertyDescriptor(globalThis, "BEND_SYS"); + Object.defineProperty(globalThis, "BEND_SYS", { + configurable: true, + get() { + if (prior) { + Object.defineProperty(globalThis, "BEND_SYS", prior); + } else { + delete globalThis.BEND_SYS; + } + throw new Error("no ffi on this host"); + }, + }); + return { $: CID(Unit) }; +} + +io_eff(CID(ffi_absent), ffi_absent_run);