5

I have a architecture with one parent that spawns a child as follow :

this.process = child.spawn(this.cmd, this.args);

this.process.on('exit', (code: number, signal: string) => {
    this.exitCode = code;
    console.log(`exit code: ${code}`);
});

there is no particular option because i want to keep a link with the child. So, when i press Ctr-C to kill the parent, it catches SIGINT to (1) end the child, (2) exit properly. But SIGINT is also propagated to the child, so the parent cannot end it gracefully. So, is there a way to do so ? maybe by preventing SIGINT to be propagated to the child ? or telling the child to ignore the signal ?

i know that something is possible by adding option detached: true and stdio: 'ignore' when spawning, but i don't want to do that because if the parent dies, i end up with zombies process. Whereas keeping the links ensure that the child is killed if the parent dies unexpectedly. Finally, i want to avoid catching SIGINT in the child as i want to keep it dumb.

EDIT: the parent already have a process.on('SIGINT', () => { ... } and the child is in python.

Hattori
  • 351
  • 4
  • 15

1 Answers1

5

You can catch exit codes like this:

process.on('SIGINT', () => {
  // handle it yourself
})

You can propagate it to children like so:

process.on('SIGINT', () => {
  this.child.kill('SIGINT')
})

The child can of course also choose to handle the signal, it is wise to not assume the child process will exit simply because you sent a single signal. You may need to set a timeout and send repeat or different signals to fully kill a process. You will also want to listen to the 'exit' message of the child process to know when its actually killed before continuing.

Documentation

justin.m.chase
  • 13,061
  • 8
  • 52
  • 100
  • 2
    the thing is that `SIGINT` is sent to the whole group. Which means to the child as well. I actually already have `process.on('SIGINT', () => { //end child }` but it does not prevent the child to receive `SIGINT` independently. Moreover, `spawn` function returns the child process. So, in the code a gave, if i add `this.process.on('SIGINT', () => { //do something }`, i would expect the `SIGINT` to be catch also for the child. but it is not the case. And it seems (through what a read), that the child need to be detached from the parents to work. Wich i don't want. – Hattori May 27 '20 at 14:23
  • Like you suggested yourself, it seems you'll need to catch the signal from the child and handle it / ignore it there. I will be doing that in my case, where both parent and child are Node processes. – jorisw Jan 02 '21 at 14:51