Skip to content

Commit d3121f0

Browse files
authored
Fix type (#1274)
* 完善所有用到的type对象,并添加中文注释 * 补充遗失的type * 修改pipe模式卡死的问题,增加trycatch捕获错误信息。 * 修改为英文报错信息。
1 parent 8f6d4f8 commit d3121f0

3 files changed

Lines changed: 74 additions & 18 deletions

File tree

src/setup.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,20 @@ export async function setup(
9494
// (SessionStart in particular) can spawn and snapshot process.env.
9595
if (feature('UDS_INBOX')) {
9696
const m = await import('./utils/udsMessaging.js')
97-
await m.startUdsMessaging(
98-
messagingSocketPath ?? m.getDefaultUdsSocketPath(),
99-
{ isExplicit: messagingSocketPath !== undefined },
100-
)
97+
try {
98+
await m.startUdsMessaging(
99+
messagingSocketPath ?? m.getDefaultUdsSocketPath(),
100+
{ isExplicit: messagingSocketPath !== undefined },
101+
)
102+
} catch (error) {
103+
logError(error)
104+
console.error(
105+
chalk.red(
106+
`Error: Failed to start messaging socket (UDS_INBOX): ${errorMessage(error)}`,
107+
),
108+
)
109+
process.exit(1)
110+
}
101111
}
102112
}
103113

src/utils/__tests__/udsMessaging.test.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
MAX_UDS_INBOX_BYTES,
2222
MAX_UDS_FRAME_BYTES,
2323
MAX_UDS_CLIENTS,
24+
MAX_UNIX_SOCKET_PATH_LENGTH,
25+
assertValidUnixSocketPath,
2426
formatUdsAddress,
2527
parseUdsTarget,
2628
sendUdsMessage,
@@ -34,11 +36,23 @@ let previousConfigDir: string | undefined
3436
let tempConfigDir = ''
3537

3638
function socketPath(label: string): string {
37-
const suffix = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}-${label}`
39+
const suffix = `${process.pid}-${Math.random().toString(16).slice(2)}-${label}`
3840
if (process.platform === 'win32') {
3941
return `\\\\.\\pipe\\claude-code-test-${suffix}`
4042
}
41-
return join(tmpdir(), 'claude-code-test', `${suffix}.sock`)
43+
const base =
44+
process.platform === 'darwin'
45+
? '/tmp/claude-uds-test'
46+
: join(tmpdir(), 'cc-uds-test')
47+
return join(base, `${suffix}.sock`)
48+
}
49+
50+
function shortTestDir(prefix: string): string {
51+
const id = `${process.pid}-${Math.random().toString(16).slice(2)}`
52+
if (process.platform === 'darwin') {
53+
return join('/tmp', `${prefix}-${id}`)
54+
}
55+
return join(tmpdir(), `${prefix}-${id}`)
4256
}
4357

4458
function sleep(ms: number): Promise<void> {
@@ -499,6 +513,27 @@ describe('UDS inbox retention', () => {
499513
expect(getDefaultUdsSocketPath()).not.toBe(firstPath)
500514
})
501515

516+
test('default socket path stays within AF_UNIX length limit', () => {
517+
const path = getDefaultUdsSocketPath()
518+
if (process.platform === 'win32') return
519+
expect(Buffer.byteLength(path, 'utf8')).toBeLessThanOrEqual(
520+
MAX_UNIX_SOCKET_PATH_LENGTH,
521+
)
522+
expect(() => assertValidUnixSocketPath(path)).not.toThrow()
523+
})
524+
525+
test('rejects socket paths longer than AF_UNIX limit', () => {
526+
if (process.platform === 'win32') return
527+
const longPath = `/tmp/${'x'.repeat(MAX_UNIX_SOCKET_PATH_LENGTH)}.sock`
528+
expect(() => assertValidUnixSocketPath(longPath)).toThrow(/max 104/)
529+
})
530+
531+
test('default socket path can bind on Node.js', async () => {
532+
const path = getDefaultUdsSocketPath()
533+
await startUdsMessaging(path, { isExplicit: true })
534+
await stopUdsMessaging()
535+
})
536+
502537
test('rejects oversized receiver responses before retaining them', async () => {
503538
const path = socketPath('oversized-response')
504539
if (process.platform !== 'win32') {
@@ -688,10 +723,7 @@ describe('UDS inbox retention', () => {
688723
})
689724

690725
test('fails closed when an explicit socket parent is not private', async () => {
691-
const parent = join(
692-
tmpdir(),
693-
`uds-socket-parent-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,
694-
)
726+
const parent = shortTestDir('uds-sp')
695727
await mkdir(parent, { recursive: true, mode: 0o755 })
696728
await chmod(parent, 0o755)
697729

@@ -707,10 +739,7 @@ describe('UDS inbox retention', () => {
707739
})
708740

709741
test('fails closed when an explicit socket parent is a file', async () => {
710-
const parentFile = join(
711-
tmpdir(),
712-
`uds-socket-parent-file-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,
713-
)
742+
const parentFile = shortTestDir('uds-spf')
714743
await writeFile(parentFile, 'not a directory', 'utf-8')
715744

716745
try {

src/utils/udsMessaging.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,31 +85,46 @@ export const MAX_UDS_CLIENTS = 128
8585
export const UDS_AUTH_TIMEOUT_MS = 2_000
8686
export const UDS_IDLE_TIMEOUT_MS = 30_000
8787

88+
/** macOS/BSD AF_UNIX `sun_path` limit (bytes, excluding NUL). */
89+
export const MAX_UNIX_SOCKET_PATH_LENGTH = 104
90+
8891
// ---------------------------------------------------------------------------
8992
// Public API — socket path helpers
9093
// ---------------------------------------------------------------------------
9194

95+
export function assertValidUnixSocketPath(path: string): void {
96+
if (process.platform === 'win32') return
97+
const byteLength = Buffer.byteLength(path, 'utf8')
98+
if (byteLength > MAX_UNIX_SOCKET_PATH_LENGTH) {
99+
throw new Error(
100+
`[udsMessaging] socket path is ${byteLength} bytes (max ${MAX_UNIX_SOCKET_PATH_LENGTH}): ${path}`,
101+
)
102+
}
103+
}
104+
92105
/**
93-
* Default socket path based on PID, placed in a tmpdir subdirectory so it
94-
* survives across config-home changes and avoids polluting ~/.claude.
106+
* Default socket path based on PID. Uses a flat file under a short temp
107+
* directory so the path stays within the AF_UNIX limit on macOS.
95108
*
96109
* On Windows, Node.js requires named pipe paths in the `\\.\pipe\` namespace;
97110
* file-system paths like `C:\...\Temp\x.sock` cause EACCES. Bun handles both
98111
* transparently, but we use the pipe format on Windows for Node.js compat.
99112
*/
100113
export function getDefaultUdsSocketPath(): string {
101114
if (defaultSocketPath) return defaultSocketPath
102-
const nonce = randomBytes(16).toString('hex')
115+
const nonce = randomBytes(8).toString('hex')
103116
if (process.platform === 'win32') {
104117
defaultSocketPath = `\\\\.\\pipe\\claude-code-${process.pid}-${nonce}`
105118
return defaultSocketPath
106119
}
120+
107121
defaultSocketPath = join(
108122
tmpdir(),
109-
'claude-code-socks',
123+
'cc-socks',
110124
`${process.pid}-${nonce}`,
111125
'messaging.sock',
112126
)
127+
assertValidUnixSocketPath(defaultSocketPath)
113128
return defaultSocketPath
114129
}
115130

@@ -416,6 +431,8 @@ export async function startUdsMessaging(
416431
return
417432
}
418433

434+
assertValidUnixSocketPath(path)
435+
419436
// Ensure parent directory exists (skip on Windows — pipe paths aren't files)
420437
if (process.platform !== 'win32') {
421438
await ensureSocketParent(path)

0 commit comments

Comments
 (0)