Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	| /*! | |
| * destroy | |
| * Copyright(c) 2014 Jonathan Ong | |
| * Copyright(c) 2015-2022 Douglas Christopher Wilson | |
| * MIT Licensed | |
| */ | |
| /** | |
| * Module dependencies. | |
| * @private | |
| */ | |
| var EventEmitter = require('events').EventEmitter | |
| var ReadStream = require('fs').ReadStream | |
| var Stream = require('stream') | |
| var Zlib = require('zlib') | |
| /** | |
| * Module exports. | |
| * @public | |
| */ | |
| module.exports = destroy | |
| /** | |
| * Destroy the given stream, and optionally suppress any future `error` events. | |
| * | |
| * @param {object} stream | |
| * @param {boolean} suppress | |
| * @public | |
| */ | |
| function destroy (stream, suppress) { | |
| if (isFsReadStream(stream)) { | |
| destroyReadStream(stream) | |
| } else if (isZlibStream(stream)) { | |
| destroyZlibStream(stream) | |
| } else if (hasDestroy(stream)) { | |
| stream.destroy() | |
| } | |
| if (isEventEmitter(stream) && suppress) { | |
| stream.removeAllListeners('error') | |
| stream.addListener('error', noop) | |
| } | |
| return stream | |
| } | |
| /** | |
| * Destroy a ReadStream. | |
| * | |
| * @param {object} stream | |
| * @private | |
| */ | |
| function destroyReadStream (stream) { | |
| stream.destroy() | |
| if (typeof stream.close === 'function') { | |
| // node.js core bug work-around | |
| stream.on('open', onOpenClose) | |
| } | |
| } | |
| /** | |
| * Close a Zlib stream. | |
| * | |
| * Zlib streams below Node.js 4.5.5 have a buggy implementation | |
| * of .close() when zlib encountered an error. | |
| * | |
| * @param {object} stream | |
| * @private | |
| */ | |
| function closeZlibStream (stream) { | |
| if (stream._hadError === true) { | |
| var prop = stream._binding === null | |
| ? '_binding' | |
| : '_handle' | |
| stream[prop] = { | |
| close: function () { this[prop] = null } | |
| } | |
| } | |
| stream.close() | |
| } | |
| /** | |
| * Destroy a Zlib stream. | |
| * | |
| * Zlib streams don't have a destroy function in Node.js 6. On top of that | |
| * simply calling destroy on a zlib stream in Node.js 8+ will result in a | |
| * memory leak. So until that is fixed, we need to call both close AND destroy. | |
| * | |
| * PR to fix memory leak: https://github.com/nodejs/node/pull/23734 | |
| * | |
| * In Node.js 6+8, it's important that destroy is called before close as the | |
| * stream would otherwise emit the error 'zlib binding closed'. | |
| * | |
| * @param {object} stream | |
| * @private | |
| */ | |
| function destroyZlibStream (stream) { | |
| if (typeof stream.destroy === 'function') { | |
| // node.js core bug work-around | |
| // istanbul ignore if: node.js 0.8 | |
| if (stream._binding) { | |
| // node.js < 0.10.0 | |
| stream.destroy() | |
| if (stream._processing) { | |
| stream._needDrain = true | |
| stream.once('drain', onDrainClearBinding) | |
| } else { | |
| stream._binding.clear() | |
| } | |
| } else if (stream._destroy && stream._destroy !== Stream.Transform.prototype._destroy) { | |
| // node.js >= 12, ^11.1.0, ^10.15.1 | |
| stream.destroy() | |
| } else if (stream._destroy && typeof stream.close === 'function') { | |
| // node.js 7, 8 | |
| stream.destroyed = true | |
| stream.close() | |
| } else { | |
| // fallback | |
| // istanbul ignore next | |
| stream.destroy() | |
| } | |
| } else if (typeof stream.close === 'function') { | |
| // node.js < 8 fallback | |
| closeZlibStream(stream) | |
| } | |
| } | |
| /** | |
| * Determine if stream has destroy. | |
| * @private | |
| */ | |
| function hasDestroy (stream) { | |
| return stream instanceof Stream && | |
| typeof stream.destroy === 'function' | |
| } | |
| /** | |
| * Determine if val is EventEmitter. | |
| * @private | |
| */ | |
| function isEventEmitter (val) { | |
| return val instanceof EventEmitter | |
| } | |
| /** | |
| * Determine if stream is fs.ReadStream stream. | |
| * @private | |
| */ | |
| function isFsReadStream (stream) { | |
| return stream instanceof ReadStream | |
| } | |
| /** | |
| * Determine if stream is Zlib stream. | |
| * @private | |
| */ | |
| function isZlibStream (stream) { | |
| return stream instanceof Zlib.Gzip || | |
| stream instanceof Zlib.Gunzip || | |
| stream instanceof Zlib.Deflate || | |
| stream instanceof Zlib.DeflateRaw || | |
| stream instanceof Zlib.Inflate || | |
| stream instanceof Zlib.InflateRaw || | |
| stream instanceof Zlib.Unzip | |
| } | |
| /** | |
| * No-op function. | |
| * @private | |
| */ | |
| function noop () {} | |
| /** | |
| * On drain handler to clear binding. | |
| * @private | |
| */ | |
| // istanbul ignore next: node.js 0.8 | |
| function onDrainClearBinding () { | |
| this._binding.clear() | |
| } | |
| /** | |
| * On open handler to close stream. | |
| * @private | |
| */ | |
| function onOpenClose () { | |
| if (typeof this.fd === 'number') { | |
| // actually close down the fd | |
| this.close() | |
| } | |
| } | |
