/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * Copyright 2017 Joyent, Inc. */ 'use strict'; var NODE_MINOR_VER_WITHOUT_PROCESS_EXIT_CODE = 10; function setBlocking() { [process.stdout, process.stderr].forEach(function setStreamBlocking(s) { if (s && s._handle && s._handle.setBlocking) { s._handle.setBlocking(true); } }); } /* * A "soft" version of `process.exit([code])` that will avoid actually using * `process.exit` if possible -- only if exiting non-zero and with an older * version of node (<= 0.10) that doesn't yet support `process.exitCode`. * * See the discussion in "Solution 1" of the README.md. * * Usage: * var exeunt = require('exeunt'); * // ... * exeunt.softExit(code); * return; * * @param {Number} code - Optional exit code. Defaults to 0. */ function softExit(code) { var exitCode = code || 0; var nodeVer = process.versions.node.split('.').map(Number); var supportsProcessExitCode = true; if (nodeVer[0] === 0 && nodeVer[1] <= NODE_MINOR_VER_WITHOUT_PROCESS_EXIT_CODE) { supportsProcessExitCode = false; } if (supportsProcessExitCode) { process.exitCode = exitCode; } else if (exitCode !== 0) { process.exit(exitCode); } } /* * Set stdout and stderr blocking and then `process.exit()` asynchronously to * allow stdout and stderr to flush before process termination. * * Call this function as follows: * exeunt([code]); * return; * instead of: * process.exit([code]); * to attempt to ensure stdout/stderr are flushed before exiting. * * Note that this isn't perfect. See the README.md for considerations. This * function corresponds to "Solution 4" described there. * * @param {Number} code - Optional exit code. Defaults to 0. */ function exeunt(code) { var exitCode = code || 0; // Set stdout and stderr to be blocking *before* we exit... setBlocking(); // ...then exit. However, we must do so in a way that node (libuv) will // do another pass through the event loop to handle async IO (in // `uv__io_poll`). setImmediate(function processExit() { process.exit(exitCode); }); } module.exports = exeunt; module.exports.softExit = softExit;