|
|
@ -145,7 +145,69 @@ function setupKillAndExit() { |
|
|
|
process._exiting = true; |
|
|
|
process.emit('exit', process.exitCode || 0); |
|
|
|
} |
|
|
|
|
|
|
|
// Flush stdio streams prior to exit.
|
|
|
|
// `flushSync` not present if stream redirected to file in shell.
|
|
|
|
flushSync(process.stdout); |
|
|
|
flushSync(process.stderr); |
|
|
|
|
|
|
|
process.reallyExit(process.exitCode || 0); |
|
|
|
|
|
|
|
function flushSync(stream) { |
|
|
|
|
|
|
|
// Behavior of this function outside of process.exit() is undefined
|
|
|
|
// due to the following factors:
|
|
|
|
// * Stream fd may be blocking after this call.
|
|
|
|
// * In the event of an incomplete flush pending buffered write
|
|
|
|
// requests may be truncated.
|
|
|
|
// * No return code.
|
|
|
|
|
|
|
|
if (stream._writev) |
|
|
|
return; |
|
|
|
|
|
|
|
var handle = stream._handle; |
|
|
|
if (!handle || !handle.flushSync) |
|
|
|
return; |
|
|
|
|
|
|
|
var fd = handle.fd; |
|
|
|
if (typeof fd !== 'number' || fd < 0) |
|
|
|
return; |
|
|
|
|
|
|
|
// FIXME: late module resolution avoids cross require problem
|
|
|
|
const fs = require('fs'); |
|
|
|
|
|
|
|
const Buffer = require('buffer'); |
|
|
|
|
|
|
|
// Queued libuv writes must be flushed first.
|
|
|
|
// Note: fd will set to blocking after handle.flushSync()
|
|
|
|
if (handle.flushSync() !== 0) { |
|
|
|
// bad fd or write queue for libuv stream not entirely flushed
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// then the queued stream chunks can be flushed
|
|
|
|
var state = stream._writableState; |
|
|
|
var entry = state.bufferedRequest; |
|
|
|
while (entry) { |
|
|
|
var chunk = entry.chunk; |
|
|
|
if (!(chunk instanceof Buffer)) { |
|
|
|
chunk = Buffer.from(chunk, entry.encoding); |
|
|
|
} |
|
|
|
// Note: fd is blocking at this point
|
|
|
|
var written = fs.writeSync(fd, chunk, 0, chunk.length); |
|
|
|
if (written !== chunk.length) { |
|
|
|
// stream chunk not flushed entirely - stop writing.
|
|
|
|
// FIXME: buffered request queue should be repaired here
|
|
|
|
// rather than being truncated after loop break
|
|
|
|
break; |
|
|
|
} |
|
|
|
entry = entry.next; |
|
|
|
} |
|
|
|
|
|
|
|
state.bufferedRequestCount = 0; |
|
|
|
state.bufferedRequest = null; |
|
|
|
state.lastBufferedRequest = null; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
process.kill = function(pid, sig) { |
|
|
|