fix(ext/node): support abstract Unix sockets in node:net pipe bind (#33872)
Fixes #33759.
`CString::new()` in `uv_pipe_bind` rejected paths containing NUL bytes,
but abstract Unix sockets (Linux) require a `\0` prefix in
`sockaddr_un.sun_path`. This broke Nuxt 4 / Nitro, which uses
`\0socketname` on Linux with Node >= 20.
### Root cause
Nitro's `getSocketAddress()` on Linux:
```js
if (process.platform === "linux") {
const nodeMajor = Number.parseInt(process.versions.node.split(".")[0], 10);
if (nodeMajor >= 20) {
return `\0${socketName}`; // Abstract Unix socket
}
}
```
In `uv_pipe_bind`, `CString::new(path)` returns `Err(NulError)` for this
path → mapped to `UV_EINVAL` → bind silently fails → `uv_pipe_listen`
finds `internal_fd = None` → returns `UV_EINVAL` → surfaces as `"listen
EINVAL: invalid argument"`.
### Changes
- **`libs/core/uv_compat/pipe.rs`**: Extract `make_sockaddr_un()` helper
that builds `sockaddr_un` correctly for both abstract sockets (raw
bytes, no NUL terminator) and filesystem sockets (NUL-terminated,
interior NULs rejected). Applied to both `uv_pipe_bind` and
`uv_pipe_connect`.
- **`libs/core/uv_compat/pipe.rs`** (`close_pipe`): Skip `remove_file`
for abstract sockets (no filesystem entry).
- **`ext/node/ops/pipe_wrap.rs`** (`fchmod`): No-op for abstract sockets
(chmod doesn't apply).
- **`ext/node/polyfills/net.ts`**: Add `readableAll`/`writableAll`
validation for abstract socket paths (matching Node.js behavior).
- **`tests/node_compat/config.jsonc`**: Enable
`test-pipe-abstract-socket.js` and `test-pipe-abstract-socket-http.js`. B
Bartek Iwańczuk committed
df92ffe7cdf3f9def2e4859577dbde5f4fe9a2ae
Parent: 82588c3
Committed by GitHub <noreply@github.com>
on 5/6/2026, 6:52:18 PM