Description
- Version: v10.3.0
- Platform: Linux plutobox 4.18.16-arch1-1-ARCH deps: update openssl to 1.0.1j #1 SMP PREEMPT Sat Oct 20 22:06:45 UTC 2018 x86_64 GNU/Linux
- Subsystem:
child_process
/stream
/process
Basically a duplicate of: #2276, which was either closed without having been resolved or has regressed.
Stick the following in a file:
#!/usr/bin/env node
const cp = require("child_process");
const { stdin, stdout, stderr } = process;
const child = cp.execFile("ps", [], { stdio: ["pipe", "pipe", "pipe"] });
process.stdin.pipe(child.stdin); // this is the problematic one
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
child.on("exit", (code, signal) =>
console.log({ msg: "Exited", code, signal }),
);
chmod +x
and run it in some shell, and you'll see it'll output the stuff from ps
, then just hang. Assuming your shell's stdin is being forwarded to the node process, hitting enter will unstick it. If you comment out the process.stdin...
line (since ps
doesn't actually need any stdin), you'll see it end as expected.
The workaround I'm using for this is to add the event handler child.on("exit", (code, signal) => code !== null ? process.exit(code) : signal !== null ? process.kill(process.pid, signal) : fail("Impossible situation, process exited but neither exited nor was killed"))
. I can't really use this in the general case, because I may need to do more stuff while the child process is running and exiting, and can't always assume the parent needs to die precisely when this one specific child process dies. At the same time the parent should be free to exit when all children are dead, and shouldn't hang like this.