Repository navigation
[api] Fix named pipe / UDS creation - #64818
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Repeated transport closure can delete a replacement Unix socket and prevent new connections.
1 open finding
What changed in this PR
Improves API transport creation for the native TypeScript compiler and language server.
Changes:
- Creates private Unix socket directories with explicit permissions and cleanup.
- Updates explicit Unix path semantics and documentation.
- Randomizes Windows sync API pipe names.
| File | Description |
|---|---|
| tsc/internal/lsp/server.go | Creates private transports and returns their actual paths. |
| tsc/internal/lsp/lsproto/lsp_generated.go | Documents Unix directory semantics. |
| tsc/internal/ipc/transport.go | Adds private transport creation and cleanup. |
| tsc/internal/ipc/transport_windows.go | Adapts Windows listener creation. |
| tsc/internal/ipc/transport_unix.go | Creates permission-restricted sockets and directories. |
| tsc/internal/ipc/transport_unix_test.go | Tests permissions, directory reuse rejection, and cleanup. |
| tsc/internal/api/server.go | Updates pipe option documentation. |
| tsc/cmd/tsc/api.go | Updates command-line pipe help. |
| tools/scripts/lsp/generate.mts | Updates protocol documentation generation. |
| packages/typescript/src/api/syncChannel.ts | Uses randomized Windows pipe names. |
Files not reviewed (1)
- tsc/internal/lsp/lsproto/lsp_generated.go: Generated file
🧠 Review effort: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
The Windows connectivity test lacks an Accept call, causing dialing to time out despite correct permissions.
1 open finding
1 resolved since last review
Files not reviewed (1)
- tsc/internal/lsp/lsproto/lsp_generated.go: Generated file
🧠 Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Cross-platform access controls and cleanup behavior need Unix and Windows validation that was not performed during this review.
0 open findings
1 resolved since last review
Files not reviewed (1)
- tsc/internal/lsp/lsproto/lsp_generated.go: Generated file
🧠 Review effort: Balanced
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
After this is merged, see if we can do a cherry pick of this to release-7.0 (the bot won't let you do it until this is merged, but I bet it conflicts anyway)
|
TypeScript Bot (@typescript-bot) cherry-pick this to release-7.0 |
|
Hey, Andrew Branch (@andrewbranch)! I was unable to cherry-pick this PR. Check the logs at: https://github.com/microsoft/TypeScript/actions/runs/38650096582 |
Port microsoft/TypeScript#64818 (257e87406), Go N' 3e9236361fa9. On Unix, NewPipeTransport(path) (ipc/transport.go:26) needs a path that does not exist: newPipeListener (transport_unix.go:14) makes it a 0700 directory, and listenInPrivatePipeDirectory (:29) listens on <path>/socket and sets it to 0600. NewPrivatePipeTransport (:38) uses os.MkdirTemp("", "tsgo-api-") instead (newPrivatePipeListener, :21). The transport keeps a cleanup that removes the socket and the directory; Close (:55) runs it unless the listener was already closed (net.ErrClosed), so a second Close leaves a replacement at the path. Each failure step joins the cleanup error, as in Go. Accept and Close of a closed Unix listener now wrap net.ErrClosed (ERR_NET_CLOSED), and the Windows listener returns it for winio's ErrPipeListenerClosed. custom/initializeAPISession (lsp/server.go:2334) makes the transport from the requested path, or a private one named by generateAPIPipeName (:2409, was generateAPIPipePath), and answers transport.Path(): the socket on Unix. The --pipe help text (cmd/tsc/api.go:33) and the StdioServerOptions.PipePath doc (api/server.go:24) follow Go. PORT divergence: Go's Windows pipe gets the security descriptor D:P(A;;GA;;;<user SID>). miow has no security attributes and the Win32 calls need unsafe (D-W1), so the port keeps the default descriptor. Tests: TestPipeTransportClosePreservesReplacement and TestPipeTransportPermissions (ipc/transport_unix_test.go:19, :47; a helper process with umask 002, as Go). The protected port test lsp_server_apisession_test.rs asks for a pipe path that does not exist and connects to the pipe that the server answers. Go N' evidence (the N' oracle over LSP): the answer for pipe P is "P/socket", P is 0700, the socket 0600, both are gone after the API client connects, and a P that exists fails with "failed to create API transport: create private socket directory: mkdir P: file exists". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

One semi-related fix per commit.
${tmpdir}/socket, so the same strategy as above can be used