summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/internal/child_process.ts
diff options
context:
space:
mode:
authorMarvin Hagemeister <hello@marvinh.dev>2023-05-18 14:02:14 +0200
committerGitHub <noreply@github.com>2023-05-18 14:02:14 +0200
commit695b5de6cb0cb4a10b95cbae99f2f19e5621a9eb (patch)
tree5ba8cef3ffb4cf97798879da88da6bf5e8f76f24 /ext/node/polyfills/internal/child_process.ts
parent9dc3ae8523364b8df6b8e92346907d1020e80d33 (diff)
fix(node): support passing parent stdio streams (#19171)
This is a bit bare bones but gets `npm-run-all` working. For full stdio compatibility with node more work is needed which is probably better done in follow up PRs. Fixes #19159
Diffstat (limited to 'ext/node/polyfills/internal/child_process.ts')
-rw-r--r--ext/node/polyfills/internal/child_process.ts50
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,