| 171 | } |
| 172 | |
| 173 | function monitorProcess(p: Exec) { |
| 174 | let processExited: (err: any) => void; |
| 175 | const unexpectedExit = new Promise<never>((_resolve, reject) => processExited = reject); |
| 176 | const stdout: Buffer[] = []; |
| 177 | const stderr: Buffer[] = []; |
| 178 | const stdoutListener = (chunk: Buffer) => stdout.push(chunk); |
| 179 | const stderrListener = (chunk: Buffer) => stderr.push(chunk); |
| 180 | p.stdout.on('data', stdoutListener); |
| 181 | p.stderr.on('data', stderrListener); |
| 182 | p.exit.then(({ code, signal }) => { |
| 183 | processExited(`Shell server terminated (code: ${code}, signal: ${signal}) |
| 184 | ${Buffer.concat(stdout).toString()} |
| 185 | ${Buffer.concat(stderr).toString()}`); |
| 186 | }, err => { |
| 187 | processExited(`Shell server failed: ${err && (err.stack || err.message)}`); |
| 188 | }); |
| 189 | const disposeStdioListeners = () => { |
| 190 | p.stdout.off('data', stdoutListener); |
| 191 | p.stderr.off('data', stderrListener); |
| 192 | stdout.length = 0; |
| 193 | stderr.length = 0; |
| 194 | }; |
| 195 | return { |
| 196 | unexpectedExit, |
| 197 | disposeStdioListeners, |
| 198 | }; |
| 199 | } |