diff options
Diffstat (limited to 'ext/node/polyfills/internal/child_process.ts')
-rw-r--r-- | ext/node/polyfills/internal/child_process.ts | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index edc4caa5e..365af4add 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -177,9 +177,9 @@ export class ChildProcess extends EventEmitter { args: cmdArgs, cwd, env: stringEnv, - stdin: toDenoStdio(stdin as NodeStdio | number), - stdout: toDenoStdio(stdout as NodeStdio | number), - stderr: toDenoStdio(stderr as NodeStdio | number), + stdin: toDenoStdio(stdin), + stdout: toDenoStdio(stdout), + stderr: toDenoStdio(stderr), windowsRawArguments: windowsVerbatimArguments, }).spawn(); this.pid = this.#process.pid; @@ -189,6 +189,16 @@ export class ChildProcess extends EventEmitter { this.stdin = Writable.fromWeb(this.#process.stdin); } + if (stdin instanceof Stream) { + this.stdin = stdin; + } + if (stdout instanceof Stream) { + this.stdout = stdout; + } + if (stderr instanceof Stream) { + this.stderr = stderr; + } + if (stdout === "pipe") { assert(this.#process.stdout); this.stdout = Readable.fromWeb(this.#process.stdout); @@ -285,15 +295,22 @@ export class ChildProcess extends EventEmitter { async #_waitForChildStreamsToClose() { const promises = [] as Array<Promise<void>>; - if (this.stdin && !this.stdin.destroyed) { + // Don't close parent process stdin if that's passed through + if (this.stdin && !this.stdin.destroyed && this.stdin !== process.stdin) { assert(this.stdin); this.stdin.destroy(); promises.push(waitForStreamToClose(this.stdin)); } - if (this.stdout && !this.stdout.destroyed) { + // Only readable streams need to be closed + if ( + this.stdout && !this.stdout.destroyed && this.stdout instanceof Readable + ) { promises.push(waitForReadableToClose(this.stdout)); } - if (this.stderr && !this.stderr.destroyed) { + // Only readable streams need to be closed + if ( + this.stderr && !this.stderr.destroyed && this.stderr instanceof Readable + ) { promises.push(waitForReadableToClose(this.stderr)); } await Promise.all(promises); @@ -317,9 +334,13 @@ const supportedNodeStdioTypes: NodeStdio[] = ["pipe", "ignore", "inherit"]; function toDenoStdio( pipe: NodeStdio | number | Stream | null | undefined, ): DenoStdio { + if (pipe instanceof Stream) { + return "inherit"; + } + if ( !supportedNodeStdioTypes.includes(pipe as NodeStdio) || - typeof pipe === "number" || pipe instanceof Stream + typeof pipe === "number" ) { notImplemented(`toDenoStdio pipe=${typeof pipe} (${pipe})`); } @@ -441,8 +462,17 @@ function normalizeStdioOption( "pipe", "pipe", ], -) { +): [ + Stream | NodeStdio | number, + Stream | NodeStdio | number, + Stream | NodeStdio | number, + ...Array<Stream | NodeStdio | number>, +] { if (Array.isArray(stdio)) { + // At least 3 stdio must be created to match node + while (stdio.length < 3) { + ArrayPrototypePush(stdio, undefined); + } return stdio; } else { switch (stdio) { @@ -796,8 +826,8 @@ export function spawnSync( args, cwd, env, - stdout: toDenoStdio(normalizedStdio[1] as NodeStdio | number), - stderr: toDenoStdio(normalizedStdio[2] as NodeStdio | number), + stdout: toDenoStdio(normalizedStdio[1]), + stderr: toDenoStdio(normalizedStdio[2]), uid, gid, windowsRawArguments: windowsVerbatimArguments, |