0

I've created a node.js program that gets keypress input from stdin by using setRawMode(true), per this. I've already made it so ^C and ^D (control-C/control-D) are handled; the code basically looks like this:

process.stdin.setRawMode(true)
process.stdin.on('data', data => {
  if (Buffer.from([0x03]).equals(data) || Buffer.from([0x04]).equals(data)) {
    process.exit()
  }
})

It's quite easy to fake how ^C and ^D work simply by, well, causing the program to exit. But how can I make ^Z work? Obviously I can't fake it, because it's something bash normally deals with itself. Is there some way to tell bash/sh/whatever to put the program into the background, the way ^Z normally works?

Nebula
  • 6,614
  • 4
  • 20
  • 40

1 Answers1

0

This answer on the Unix & Linux StackExchange was useful. We need to send a signal to our own process - particularly SIGTSTP:

process.kill(process.pid, 'SIGTSTP');

Within the context of my program, I also had to clean up any terminal changes (e.g. hiding cursor, using the alternate screen) before sending SIGTSTP; and I had to re-apply them upon receiving SIGCONT:

process.on('SIGCONT', () => {
  process.stdout.write(...);
});

I also found that process.stdin.setRawMode needed a refresh on SIGCONT, for some reason:

process.stdin.setRawMode(false);
process.stdin.setRawMode(true);
Nebula
  • 6,614
  • 4
  • 20
  • 40
  • For reference, here's my diff implementing this: https://notabug.org/towerofnix/mtui/commit/6da245d2d0a55f64caaf2bb185b343d4f227d0c3 – Nebula Mar 10 '19 at 13:54