Node-Pty "posix_spawnp failed" opening and closing many terminals

82 Views Asked by At

I am trying to use Node-Pty to run shell commands from within Electron. After each command finishes executing, I need to know that it has finished executing and get its return code.

Currently I'm using the following approach:

export const spawn = async ({
  cmd,
  dir,
}: {
  cmd: string;
  dir: string;
}): Promise<number> => {
  const ptyProcess = pty.spawn('bash', ['-c', cmd], {
    name: 'xterm-color',
    cols: 80,
    rows: 10,
    cwd: dir,
    env: { ...process.env },
  });

  ptyProcess.onData((ptyData) => {
    console.log({ ptyData });
  });

  return new Promise<number>((resolve) => {
    ptyProcess.onExit((x) => {
      resolve(x.exitCode);
    });
  });
};

This is working well for a while, but it seems that eventually Node-Pty fails. I can repro this consistently using the following code:

  for (let i = 1; i <= 1000; i++) {
    await spawn({ cmd: `echo hello ${i}`, dir: '~', mainWindow });
  }

It fails for me after iteration number 505 with the following error:

Error: posix_spawnp failed.
    at new UnixTerminal (/Users/dcentore/Dropbox/Projects/Derevo/release/app/node_modules/node-pty/src/unixTerminal.ts:114:22)
    at Object.spawn (/Users/dcentore/Dropbox/Projects/Derevo/release/app/node_modules/node-pty/src/index.ts:30:10)
    at spawn (/Users/dcentore/Dropbox/Projects/Derevo/src/main/gitlib/git-write.ts:74:20)
    at /Users/dcentore/Dropbox/Projects/Derevo/src/main/main.ts:53:16
    at async WebContents.<anonymous> (node:electron/js2c/browser_init:2:89579)

I believe this is because I'm running up against the Mac kern.tty.ptmx_max (set to 511 on my machine). I assume this means I'm not closing the node-pty instances correctly, but I'm struggling to figure out how to actually do that.

How can I close the node-pty instances correctly so I can indefinitely create new ones?

0

There are 0 best solutions below