* Exit methods for API * @param {Integer} code exit code for terminal
(code)
| 265 | * @param {Integer} code exit code for terminal |
| 266 | */ |
| 267 | exitCli (code) { |
| 268 | var that = this; |
| 269 | |
| 270 | // Do nothing if PM2 called programmatically (also in speedlist) |
| 271 | if (conf.PM2_PROGRAMMATIC && process.env.PM2_USAGE != 'CLI') return false; |
| 272 | |
| 273 | KMDaemon.disconnectRPC(function() { |
| 274 | that.Client.close(function() { |
| 275 | code = code || 0; |
| 276 | // Safe exits process after all streams are drained. |
| 277 | // file descriptor flag. |
| 278 | var fds = 0; |
| 279 | // exits process when stdout (1) and sdterr(2) are both drained. |
| 280 | function tryToExit() { |
| 281 | if ((fds & 1) && (fds & 2)) { |
| 282 | debug('This command took %ds to execute', (new Date() - that.start_timer) / 1000); |
| 283 | process.exit(code); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | [process.stdout, process.stderr].forEach(function(std) { |
| 288 | var fd = std.fd; |
| 289 | if (!std.bufferSize) { |
| 290 | // bufferSize equals 0 means current stream is drained. |
| 291 | fds = fds | fd; |
| 292 | } else { |
| 293 | // Appends nothing to the std queue, but will trigger `tryToExit` event on `drain`. |
| 294 | std.write && std.write('', function() { |
| 295 | fds = fds | fd; |
| 296 | tryToExit(); |
| 297 | }); |
| 298 | } |
| 299 | // Does not write anything more. |
| 300 | delete std.write; |
| 301 | }); |
| 302 | tryToExit(); |
| 303 | }); |
| 304 | }); |
| 305 | } |
| 306 | |
| 307 | //////////////////////////// |
| 308 | // Application management // |