Skip to content

Commit 9945428

Browse files
committed
Fix issues surrounding opening files within code-server's terminal.
1 parent 059893f commit 9945428

File tree

4 files changed

+28
-79
lines changed

4 files changed

+28
-79
lines changed

src/node/cli.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -737,10 +737,11 @@ export const shouldOpenInExistingInstance = async (args: Args): Promise<string |
737737
}
738738

739739
// It's possible the user is trying to spawn another instance of code-server.
740-
// Check if any unrelated flags are set (check against one because `_` always
741-
// exists), that a file or directory was passed, and that the socket is
742-
// active.
743-
if (Object.keys(args).length === 1 && args._.length > 0) {
740+
// 1. Check if any unrelated flags are set
741+
// 2. That a file or directory was passed
742+
// 3. That the socket is active
743+
// TODO: We check against 3 because some defaults always exist. This is fragile.
744+
if (Object.keys(args).length === 3 && args._.length > 0) {
744745
const socketPath = await readSocketPath(DEFAULT_SOCKET_PATH)
745746
if (socketPath && (await canConnect(socketPath))) {
746747
return socketPath

src/node/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export function getPackageJson(relativePath: string): JSONSchemaForNPMPackageJso
1818

1919
const pkg = getPackageJson("../../package.json")
2020

21+
export const pkgName = pkg.name || "code-server"
2122
export const version = pkg.version || "development"
2223
export const commit = pkg.commit || "development"
2324
export const rootPath = path.resolve(__dirname, "../..")

src/node/entry.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
11
import { logger } from "@coder/logger"
22
import { optionDescriptions, parse, readConfigFile, setDefaults, shouldOpenInExistingInstance } from "./cli"
3-
import { commit, version } from "./constants"
3+
import { commit, pkgName, version } from "./constants"
44
import { openInExistingInstance, runCodeServer, runVsCodeCli, shouldSpawnCliProcess } from "./main"
55
import { monkeyPatchProxyProtocols } from "./proxy_agent"
6-
import { isChild, wrapper } from "./wrapper"
6+
import { loadAMDModule } from "./util"
7+
import { wrapper } from "./wrapper"
8+
9+
const cliPipe = process.env["VSCODE_IPC_HOOK_CLI"] as string
10+
const cliCommand = process.env["VSCODE_CLIENT_COMMAND"] as string
711

812
async function entry(): Promise<void> {
913
monkeyPatchProxyProtocols()
14+
const cliArgs = await parse(process.argv.slice(2))
1015

1116
// There's no need to check flags like --help or to spawn in an existing
1217
// instance for the child process because these would have already happened in
1318
// the parent and the child wouldn't have been spawned. We also get the
1419
// arguments from the parent so we don't have to parse twice and to account
1520
// for environment manipulation (like how PASSWORD gets removed to avoid
1621
// leaking to child processes).
17-
if (isChild(wrapper)) {
18-
const args = await wrapper.handshake()
19-
wrapper.preventExit()
20-
const server = await runCodeServer(args)
21-
wrapper.onDispose(() => server.dispose())
22+
23+
if (cliPipe || cliCommand) {
24+
const remoteAgentMain = await loadAMDModule<CodeServerLib.RemoteCLIMain>("vs/server/remoteCli", "main")
25+
26+
remoteAgentMain(
27+
{
28+
productName: pkgName,
29+
version,
30+
commit,
31+
executableName: pkgName,
32+
},
33+
process.argv.slice(2),
34+
)
2235
return
2336
}
2437

25-
const cliArgs = await parse(process.argv.slice(2))
2638
const configArgs = await readConfigFile(cliArgs.config)
2739
const args = await setDefaults(cliArgs, configArgs)
2840

@@ -64,7 +76,7 @@ async function entry(): Promise<void> {
6476
return openInExistingInstance(args, socketPath)
6577
}
6678

67-
return wrapper.start(args)
79+
runCodeServer(args)
6880
}
6981

7082
entry().catch((error) => {

src/node/wrapper.ts

+1-66
Original file line numberDiff line numberDiff line change
@@ -143,64 +143,6 @@ abstract class Process {
143143
}
144144
}
145145

146-
/**
147-
* Child process that will clean up after itself if the parent goes away and can
148-
* perform a handshake with the parent and ask it to relaunch.
149-
*/
150-
class ChildProcess extends Process {
151-
public logger = logger.named(`child:${process.pid}`)
152-
153-
public constructor(private readonly parentPid: number) {
154-
super()
155-
156-
// Kill the inner process if the parent dies. This is for the case where the
157-
// parent process is forcefully terminated and cannot clean up.
158-
setInterval(() => {
159-
try {
160-
// process.kill throws an exception if the process doesn't exist.
161-
process.kill(this.parentPid, 0)
162-
} catch (_) {
163-
// Consider this an error since it should have been able to clean up
164-
// the child process unless it was forcefully killed.
165-
this.logger.error(`parent process ${parentPid} died`)
166-
this._onDispose.emit(undefined)
167-
}
168-
}, 5000)
169-
}
170-
171-
/**
172-
* Initiate the handshake and wait for a response from the parent.
173-
*/
174-
public async handshake(): Promise<DefaultedArgs> {
175-
this.send({ type: "handshake" })
176-
const message = await onMessage<ParentMessage, ParentHandshakeMessage>(
177-
process,
178-
(message): message is ParentHandshakeMessage => {
179-
return message.type === "handshake"
180-
},
181-
this.logger,
182-
)
183-
return message.args
184-
}
185-
186-
/**
187-
* Notify the parent process that it should relaunch the child.
188-
*/
189-
public relaunch(version: string): void {
190-
this.send({ type: "relaunch", version })
191-
}
192-
193-
/**
194-
* Send a message to the parent.
195-
*/
196-
private send(message: ChildMessage): void {
197-
if (!process.send) {
198-
throw new Error("not spawned with IPC")
199-
}
200-
process.send(message)
201-
}
202-
}
203-
204146
/**
205147
* Parent process wrapper that spawns the child process and performs a handshake
206148
* with it. Will relaunch the child if it receives a SIGUSR1 or is asked to by
@@ -346,14 +288,7 @@ export class ParentProcess extends Process {
346288
/**
347289
* Process wrapper.
348290
*/
349-
export const wrapper =
350-
typeof process.env.CODE_SERVER_PARENT_PID !== "undefined"
351-
? new ChildProcess(parseInt(process.env.CODE_SERVER_PARENT_PID))
352-
: new ParentProcess(require("../../package.json").version)
353-
354-
export function isChild(proc: ChildProcess | ParentProcess): proc is ChildProcess {
355-
return proc instanceof ChildProcess
356-
}
291+
export const wrapper = new ParentProcess(require("../../package.json").version)
357292

358293
// It's possible that the pipe has closed (for example if you run code-server
359294
// --version | head -1). Assume that means we're done.

0 commit comments

Comments
 (0)