mirror of
https://github.com/coder/code-server.git
synced 2026-05-05 20:15:19 +02:00
Fix coping and moving files around using the file tree (#568)
* Implement write/read buffers in electron fill This makes cutting and copy files from the file tree work. * Implement fs.createReadStream This is used by the file tree to copy files. * Allow passing proxies back from client to server This makes things like piping streams possible. * Synchronously bind to proxy events This eliminates any chance whatsoever of missing events due to binding too late. * Make it possible to bind some events on demand * Add some protocol documentation
This commit is contained in:
@@ -7,29 +7,35 @@ import { WritableProxy, ReadableProxy } from "./stream";
|
||||
|
||||
export type ForkProvider = (modulePath: string, args?: string[], options?: cp.ForkOptions) => cp.ChildProcess;
|
||||
|
||||
export class ChildProcessProxy implements ServerProxy {
|
||||
public constructor(private readonly process: cp.ChildProcess) {}
|
||||
export class ChildProcessProxy extends ServerProxy<cp.ChildProcess> {
|
||||
public constructor(instance: cp.ChildProcess) {
|
||||
super({
|
||||
bindEvents: ["close", "disconnect", "error", "exit", "message"],
|
||||
doneEvents: ["close"],
|
||||
instance,
|
||||
});
|
||||
}
|
||||
|
||||
public async kill(signal?: string): Promise<void> {
|
||||
this.process.kill(signal);
|
||||
this.instance.kill(signal);
|
||||
}
|
||||
|
||||
public async disconnect(): Promise<void> {
|
||||
this.process.disconnect();
|
||||
this.instance.disconnect();
|
||||
}
|
||||
|
||||
public async ref(): Promise<void> {
|
||||
this.process.ref();
|
||||
this.instance.ref();
|
||||
}
|
||||
|
||||
public async unref(): Promise<void> {
|
||||
this.process.unref();
|
||||
this.instance.unref();
|
||||
}
|
||||
|
||||
// tslint:disable-next-line no-any
|
||||
public async send(message: any): Promise<void> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
this.process.send(message, (error) => {
|
||||
this.instance.send(message, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
@@ -40,25 +46,13 @@ export class ChildProcessProxy implements ServerProxy {
|
||||
}
|
||||
|
||||
public async getPid(): Promise<number> {
|
||||
return this.process.pid;
|
||||
}
|
||||
|
||||
public async onDone(cb: () => void): Promise<void> {
|
||||
this.process.on("close", cb);
|
||||
return this.instance.pid;
|
||||
}
|
||||
|
||||
public async dispose(): Promise<void> {
|
||||
this.process.kill();
|
||||
setTimeout(() => this.process.kill("SIGKILL"), 5000); // Double tap.
|
||||
}
|
||||
|
||||
// tslint:disable-next-line no-any
|
||||
public async onEvent(cb: (event: string, ...args: any[]) => void): Promise<void> {
|
||||
this.process.on("close", (code, signal) => cb("close", code, signal));
|
||||
this.process.on("disconnect", () => cb("disconnect"));
|
||||
this.process.on("error", (error) => cb("error", error));
|
||||
this.process.on("exit", (exitCode, signal) => cb("exit", exitCode, signal));
|
||||
this.process.on("message", (message) => cb("message", message));
|
||||
this.instance.kill();
|
||||
setTimeout(() => this.instance.kill("SIGKILL"), 5000); // Double tap.
|
||||
await super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +92,10 @@ export class ChildProcessModuleProxy {
|
||||
return {
|
||||
childProcess: new ChildProcessProxy(process),
|
||||
stdin: process.stdin && new WritableProxy(process.stdin),
|
||||
stdout: process.stdout && new ReadableProxy(process.stdout),
|
||||
stderr: process.stderr && new ReadableProxy(process.stderr),
|
||||
// Child processes streams appear to immediately flow so we need to bind
|
||||
// to the data event right away.
|
||||
stdout: process.stdout && new ReadableProxy(process.stdout, ["data"]),
|
||||
stderr: process.stderr && new ReadableProxy(process.stderr, ["data"]),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user