diff options
author | isaacs <i@izs.me> | 2015-06-28 00:10:02 +0300 |
---|---|---|
committer | Rebecca Turner <me@re-becca.org> | 2015-07-01 12:41:35 +0300 |
commit | 593dd33be501ff6e438b596caf8050f35eb8c49d (patch) | |
tree | a57e51af7da76ab3a331de72e7080062b990fdb4 /node_modules/graceful-fs | |
parent | 6094754474e3b31435d3fcb7c52956e81f750aa4 (diff) |
graceful-fs@4.1.2
PR-URL: https://github.com/npm/npm/pull/8735
Diffstat (limited to 'node_modules/graceful-fs')
-rw-r--r-- | node_modules/graceful-fs/.npmignore | 1 | ||||
-rw-r--r-- | node_modules/graceful-fs/LICENSE | 2 | ||||
-rw-r--r-- | node_modules/graceful-fs/fs.js | 32 | ||||
-rw-r--r-- | node_modules/graceful-fs/graceful-fs.js | 323 | ||||
-rw-r--r-- | node_modules/graceful-fs/legacy-streams.js | 118 | ||||
-rw-r--r-- | node_modules/graceful-fs/package.json | 63 | ||||
-rw-r--r-- | node_modules/graceful-fs/polyfills.js | 263 | ||||
-rw-r--r-- | node_modules/graceful-fs/test/max-open.js | 69 | ||||
-rw-r--r-- | node_modules/graceful-fs/test/open.js | 39 | ||||
-rw-r--r-- | node_modules/graceful-fs/test/readdir-sort.js | 20 | ||||
-rw-r--r-- | node_modules/graceful-fs/test/write-then-read.js | 47 |
11 files changed, 504 insertions, 473 deletions
diff --git a/node_modules/graceful-fs/.npmignore b/node_modules/graceful-fs/.npmignore deleted file mode 100644 index c2658d7d1..000000000 --- a/node_modules/graceful-fs/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ diff --git a/node_modules/graceful-fs/LICENSE b/node_modules/graceful-fs/LICENSE index 19129e315..9d2c80369 100644 --- a/node_modules/graceful-fs/LICENSE +++ b/node_modules/graceful-fs/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) Isaac Z. Schlueter and Contributors +Copyright (c) Isaac Z. Schlueter, Ben Noordhuis, and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/node_modules/graceful-fs/fs.js b/node_modules/graceful-fs/fs.js index 64ad98023..8ad4a3839 100644 --- a/node_modules/graceful-fs/fs.js +++ b/node_modules/graceful-fs/fs.js @@ -1,11 +1,21 @@ -// eeeeeevvvvviiiiiiillllll -// more evil than monkey-patching the native builtin? -// Not sure. - -var mod = require("module") -var pre = '(function (exports, require, module, __filename, __dirname) { ' -var post = '});' -var src = pre + process.binding('natives').fs + post -var vm = require('vm') -var fn = vm.runInThisContext(src) -fn(exports, require, module, __filename, __dirname) +'use strict' + +var fs = require('fs') + +module.exports = clone(fs) + +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj + + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) + + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) + + return copy +} diff --git a/node_modules/graceful-fs/graceful-fs.js b/node_modules/graceful-fs/graceful-fs.js index fb206b838..fe3b17cb6 100644 --- a/node_modules/graceful-fs/graceful-fs.js +++ b/node_modules/graceful-fs/graceful-fs.js @@ -1,11 +1,7 @@ -// Monkey-patching the fs module. -// It's ugly, but there is simply no other way to do this. -var fs = module.exports = require('./fs.js') - -var assert = require('assert') - -// fix up some busted stuff, mostly on windows and old nodes -require('./polyfills.js') +var fs = require('fs') +var polyfills = require('./polyfills.js') +var legacy = require('./legacy-streams.js') +var queue = [] var util = require('util') @@ -13,146 +9,243 @@ function noop () {} var debug = noop if (util.debuglog) - debug = util.debuglog('gfs') -else if (/\bgfs\b/i.test(process.env.NODE_DEBUG || '')) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) debug = function() { var m = util.format.apply(util, arguments) - m = 'GFS: ' + m.split(/\n/).join('\nGFS: ') + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') console.error(m) } -if (/\bgfs\b/i.test(process.env.NODE_DEBUG || '')) { +if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { - debug('fds', fds) debug(queue) - assert.equal(queue.length, 0) + require('assert').equal(queue.length, 0) }) } - -var originalOpen = fs.open -fs.open = open - -function open(path, flags, mode, cb) { - if (typeof mode === "function") cb = mode, mode = null - if (typeof cb !== "function") cb = noop - new OpenReq(path, flags, mode, cb) +module.exports = patch(require('./fs.js')) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { + module.exports = patch(fs) } -function OpenReq(path, flags, mode, cb) { - this.path = path - this.flags = flags - this.mode = mode - this.cb = cb - Req.call(this) -} - -util.inherits(OpenReq, Req) - -OpenReq.prototype.process = function() { - originalOpen.call(fs, this.path, this.flags, this.mode, this.done) -} - -var fds = {} -OpenReq.prototype.done = function(er, fd) { - debug('open done', er, fd) - if (fd) - fds['fd' + fd] = this.path - Req.prototype.done.call(this, er, fd) -} - - -var originalReaddir = fs.readdir -fs.readdir = readdir +// Always patch fs.close/closeSync, because we want to +// retry() whenever a close happens *anywhere* in the program. +// This is essential when multiple graceful-fs instances are +// in play at the same time. +fs.close = (function (fs$close) { return function (fd, cb) { + return fs$close.call(fs, fd, function (err) { + if (!err) + retry() + + if (typeof cb === 'function') + cb.apply(this, arguments) + }) +}})(fs.close) + +fs.closeSync = (function (fs$closeSync) { return function (fd) { + // Note that graceful-fs also retries when fs.closeSync() fails. + // Looks like a bug to me, although it's probably a harmless one. + var rval = fs$closeSync.apply(fs, arguments) + retry() + return rval +}})(fs.closeSync) + +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + fs.FileReadStream = ReadStream; // Legacy name. + fs.FileWriteStream = WriteStream; // Legacy name. + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$readFile(path, options, cb) + + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } -function readdir(path, cb) { - if (typeof cb !== "function") cb = noop - new ReaddirReq(path, cb) -} + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$writeFile(path, data, options, cb) + + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } -function ReaddirReq(path, cb) { - this.path = path - this.cb = cb - Req.call(this) -} + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$appendFile(path, data, options, cb) + + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } -util.inherits(ReaddirReq, Req) + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, cb) { + return go$readdir(path, cb) + + function go$readdir () { + return fs$readdir(path, function (err, files) { + if (files && files.sort) + files.sort(); // Backwards compatibility with graceful-fs. + + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [path, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } -ReaddirReq.prototype.process = function() { - originalReaddir.call(fs, this.path, this.done) -} -ReaddirReq.prototype.done = function(er, files) { - if (files && files.sort) - files = files.sort() - Req.prototype.done.call(this, er, files) - onclose() -} + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } + var fs$ReadStream = fs.ReadStream + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open -var originalClose = fs.close -fs.close = close + var fs$WriteStream = fs.WriteStream + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open -function close (fd, cb) { - debug('close', fd) - if (typeof cb !== "function") cb = noop - delete fds['fd' + fd] - originalClose.call(fs, fd, function(er) { - onclose() - cb(er) - }) -} + fs.ReadStream = ReadStream + fs.WriteStream = WriteStream + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } -var originalCloseSync = fs.closeSync -fs.closeSync = closeSync + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() + + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } -function closeSync (fd) { - try { - return originalCloseSync(fd) - } finally { - onclose() + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) } -} + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } -// Req class -function Req () { - // start processing - this.done = this.done.bind(this) - this.failures = 0 - this.process() -} + function createReadStream (path, options) { + return new ReadStream(path, options) + } -Req.prototype.done = function (er, result) { - var tryAgain = false - if (er) { - var code = er.code - var tryAgain = code === "EMFILE" || code === "ENFILE" - if (process.platform === "win32") - tryAgain = tryAgain || code === "OK" + function createWriteStream (path, options) { + return new WriteStream(path, options) } - if (tryAgain) { - this.failures ++ - enqueue(this) - } else { - var cb = this.cb - cb(er, result) + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null + + return go$open(path, flags, mode, cb) + + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } } -} -var queue = [] + return fs +} -function enqueue(req) { - queue.push(req) - debug('enqueue %d %s', queue.length, req.constructor.name, req) +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + queue.push(elem) } -function onclose() { - var req = queue.shift() - if (req) { - debug('process', req.constructor.name, req) - req.process() +function retry () { + var elem = queue.shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) } } diff --git a/node_modules/graceful-fs/legacy-streams.js b/node_modules/graceful-fs/legacy-streams.js new file mode 100644 index 000000000..d617b50fc --- /dev/null +++ b/node_modules/graceful-fs/legacy-streams.js @@ -0,0 +1,118 @@ +var Stream = require('stream').Stream + +module.exports = legacy + +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } + + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); + + Stream.call(this); + + var self = this; + + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; + + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.encoding) this.setEncoding(this.encoding); + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } + + if (this.start > this.end) { + throw new Error('start must be <= end'); + } + + this.pos = this.start; + } + + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } + + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } + + self.fd = fd; + self.emit('open', fd); + self._read(); + }) + } + + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); + + Stream.call(this); + + this.path = path; + this.fd = null; + this.writable = true; + + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } + + this.pos = this.start; + } + + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } + } +} diff --git a/node_modules/graceful-fs/package.json b/node_modules/graceful-fs/package.json index 7a68ed4a1..b01932d06 100644 --- a/node_modules/graceful-fs/package.json +++ b/node_modules/graceful-fs/package.json @@ -1,53 +1,36 @@ { "_args": [ [ - "graceful-fs@~3.0.8", - "/Users/rebecca/code/npm" + "graceful-fs@latest", + "/Users/isaacs/dev/npm/npm" ] ], - "_from": "graceful-fs@>=3.0.8 <3.1.0", - "_id": "graceful-fs@3.0.8", + "_from": "graceful-fs@latest", + "_id": "graceful-fs@4.1.2", "_inCache": true, "_location": "/graceful-fs", - "_nodeVersion": "2.0.1", + "_nodeVersion": "2.2.1", "_npmUser": { "email": "isaacs@npmjs.com", "name": "isaacs" }, - "_npmVersion": "2.10.1", + "_npmVersion": "3.0.0", "_phantomChildren": {}, "_requested": { "name": "graceful-fs", - "raw": "graceful-fs@~3.0.8", - "rawSpec": "~3.0.8", + "raw": "graceful-fs@latest", + "rawSpec": "latest", "scope": null, - "spec": ">=3.0.8 <3.1.0", - "type": "range" + "spec": "latest", + "type": "tag" }, "_requiredBy": [ - "/", - "/cmd-shim", - "/fs-vacuum", - "/fs-write-stream-atomic", - "/fstream", - "/node-gyp", - "/npm-registry-client", - "/read-installed", - "/read-package-json", - "/readdir-scoped-modules", - "/sha", - "/write-file-atomic" + "/" ], - "_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz", - "_shasum": "ce813e725fa82f7e6147d51c9a5ca68270551c22", + "_shasum": "fe2239b7574972e67e41f808823f9bfa4a991e37", "_shrinkwrap": null, - "_spec": "graceful-fs@~3.0.8", - "_where": "/Users/rebecca/code/npm", - "author": { - "email": "i@izs.me", - "name": "Isaac Z. Schlueter", - "url": "http://blog.izs.me" - }, + "_spec": "graceful-fs@latest", + "_where": "/Users/isaacs/dev/npm/npm", "bugs": { "url": "https://github.com/isaacs/node-graceful-fs/issues" }, @@ -62,13 +45,19 @@ "test": "test" }, "dist": { - "shasum": "ce813e725fa82f7e6147d51c9a5ca68270551c22", - "tarball": "http://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz" + "shasum": "fe2239b7574972e67e41f808823f9bfa4a991e37", + "tarball": "http://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "engines": { "node": ">=0.4.0" }, - "gitHead": "45c57aa5e323c35a985a525de6f0c9a6ef59e1f8", + "files": [ + "fs.js", + "graceful-fs.js", + "legacy-streams.js", + "polyfills.js" + ], + "gitHead": "c286080071b6be9aa9ba108b0bb9b44ff122926d", "homepage": "https://github.com/isaacs/node-graceful-fs#readme", "keywords": [ "EACCESS", @@ -98,10 +87,10 @@ "optionalDependencies": {}, "repository": { "type": "git", - "url": "git://github.com/isaacs/node-graceful-fs.git" + "url": "git+https://github.com/isaacs/node-graceful-fs.git" }, "scripts": { - "test": "tap test/*.js" + "test": "node test.js | tap -" }, - "version": "3.0.8" + "version": "4.1.2" } diff --git a/node_modules/graceful-fs/polyfills.js b/node_modules/graceful-fs/polyfills.js index 42705391a..5e4f48046 100644 --- a/node_modules/graceful-fs/polyfills.js +++ b/node_modules/graceful-fs/polyfills.js @@ -8,18 +8,118 @@ process.cwd = function() { cwd = origCwd.call(process) return cwd } +try { + process.cwd() +} catch (er) {} + var chdir = process.chdir process.chdir = function(d) { cwd = null chdir.call(process, d) } -// (re-)implement some things that are known busted or missing. +module.exports = patch + +function patch (fs) { + // (re-)implement some things that are known busted or missing. + + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } + + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } + + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. + + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) + + fs.chmod = chownFix(fs.chmod) + fs.fchmod = chownFix(fs.fchmod) + fs.lchmod = chownFix(fs.lchmod) + + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) + + fs.chmodSync = chownFix(fs.chmodSync) + fs.fchmodSync = chownFix(fs.fchmodSync) + fs.lchmodSync = chownFix(fs.lchmodSync) -// lchmod, broken prior to 0.6.2 -// back-port the fix here. -if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + process.nextTick(cb) + } + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + process.nextTick(cb) + } + fs.lchownSync = function () {} + } + + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 1 second. + if (process.platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 1000) { + return fs$rename(from, to, CB) + } + if (cb) cb(er) + }) + }})(fs.rename) + } + + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + }})(fs.read) + + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) +} + +function patchLchmod (fs) { fs.lchmod = function (path, mode, callback) { callback = callback || noop fs.open( path @@ -45,25 +145,25 @@ if (constants.hasOwnProperty('O_SYMLINK') && // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. - var err, err2 - try { - var ret = fs.fchmodSync(fd, mode) - } catch (er) { - err = er - } + var threw = true + var ret try { - fs.closeSync(fd) - } catch (er) { - err2 = er + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } } - if (err || err2) throw (err || err2) return ret } } - -// lutimes implementation, or no-op -if (!fs.lutimes) { +function patchLutimes (fs) { if (constants.hasOwnProperty("O_SYMLINK")) { fs.lutimes = function (path, at, mt, cb) { fs.open(path, constants.O_SYMLINK, function (er, fd) { @@ -79,62 +179,29 @@ if (!fs.lutimes) { fs.lutimesSync = function (path, at, mt) { var fd = fs.openSync(path, constants.O_SYMLINK) - , err - , err2 - , ret - + var ret + var threw = true try { - var ret = fs.futimesSync(fd, at, mt) - } catch (er) { - err = er - } - try { - fs.closeSync(fd) - } catch (er) { - err2 = er + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } } - if (err || err2) throw (err || err2) return ret } - } else if (fs.utimensat && constants.hasOwnProperty("AT_SYMLINK_NOFOLLOW")) { - // maybe utimensat will be bound soonish? - fs.lutimes = function (path, at, mt, cb) { - fs.utimensat(path, at, mt, constants.AT_SYMLINK_NOFOLLOW, cb) - } - - fs.lutimesSync = function (path, at, mt) { - return fs.utimensatSync(path, at, mt, constants.AT_SYMLINK_NOFOLLOW) - } - } else { fs.lutimes = function (_a, _b, _c, cb) { process.nextTick(cb) } fs.lutimesSync = function () {} } } - -// https://github.com/isaacs/node-graceful-fs/issues/4 -// Chown should not fail on einval or eperm if non-root. -// It should not fail on enosys ever, as this just indicates -// that a fs doesn't support the intended operation. - -fs.chown = chownFix(fs.chown) -fs.fchown = chownFix(fs.fchown) -fs.lchown = chownFix(fs.lchown) - -fs.chmod = chownFix(fs.chmod) -fs.fchmod = chownFix(fs.fchmod) -fs.lchmod = chownFix(fs.lchmod) - -fs.chownSync = chownFixSync(fs.chownSync) -fs.fchownSync = chownFixSync(fs.fchownSync) -fs.lchownSync = chownFixSync(fs.lchownSync) - -fs.chmodSync = chownFix(fs.chmodSync) -fs.fchmodSync = chownFix(fs.fchmodSync) -fs.lchmodSync = chownFix(fs.lchmodSync) - function chownFix (orig) { if (!orig) return orig return function (target, uid, gid, cb) { @@ -183,73 +250,3 @@ function chownErOk (er) { return false } - - -// if lchmod/lchown do not exist, then make them no-ops -if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - process.nextTick(cb) - } - fs.lchmodSync = function () {} -} -if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - process.nextTick(cb) - } - fs.lchownSync = function () {} -} - - - -// on Windows, A/V software can lock the directory, causing this -// to fail with an EACCES or EPERM if the directory contains newly -// created files. Try again on failure, for up to 1 second. -if (process.platform === "win32") { - var rename_ = fs.rename - fs.rename = function rename (from, to, cb) { - var start = Date.now() - rename_(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 1000) { - return rename_(from, to, CB) - } - if(cb) cb(er) - }) - } -} - - -// if read() returns EAGAIN, then just try it again. -var read = fs.read -fs.read = function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return read.call(fs, fd, buffer, offset, length, position, callback) -} - -var readSync = fs.readSync -fs.readSync = function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } - } -} - diff --git a/node_modules/graceful-fs/test/max-open.js b/node_modules/graceful-fs/test/max-open.js deleted file mode 100644 index a6b9ba43d..000000000 --- a/node_modules/graceful-fs/test/max-open.js +++ /dev/null @@ -1,69 +0,0 @@ -var test = require('tap').test -var fs = require('../') - -test('open lots of stuff', function (t) { - // Get around EBADF from libuv by making sure that stderr is opened - // Otherwise Darwin will refuse to give us a FD for stderr! - process.stderr.write('') - - // How many parallel open()'s to do - var n = 1024 - var opens = 0 - var fds = [] - var going = true - var closing = false - var doneCalled = 0 - - for (var i = 0; i < n; i++) { - go() - } - - function go() { - opens++ - fs.open(__filename, 'r', function (er, fd) { - if (er) throw er - fds.push(fd) - if (going) go() - }) - } - - // should hit ulimit pretty fast - setTimeout(function () { - going = false - t.equal(opens - fds.length, n) - done() - }, 100) - - - function done () { - if (closing) return - doneCalled++ - - if (fds.length === 0) { - console.error('done called %d times', doneCalled) - // First because of the timeout - // Then to close the fd's opened afterwards - // Then this time, to complete. - // Might take multiple passes, depending on CPU speed - // and ulimit, but at least 3 in every case. - t.ok(doneCalled >= 2) - return t.end() - } - - closing = true - setTimeout(function () { - // console.error('do closing again') - closing = false - done() - }, 100) - - // console.error('closing time') - var closes = fds.slice(0) - fds.length = 0 - closes.forEach(function (fd) { - fs.close(fd, function (er) { - if (er) throw er - }) - }) - } -}) diff --git a/node_modules/graceful-fs/test/open.js b/node_modules/graceful-fs/test/open.js deleted file mode 100644 index 85732f236..000000000 --- a/node_modules/graceful-fs/test/open.js +++ /dev/null @@ -1,39 +0,0 @@ -var test = require('tap').test -var fs = require('../graceful-fs.js') - -test('graceful fs is monkeypatched fs', function (t) { - t.equal(fs, require('../fs.js')) - t.end() -}) - -test('open an existing file works', function (t) { - var fd = fs.openSync(__filename, 'r') - fs.closeSync(fd) - fs.open(__filename, 'r', function (er, fd) { - if (er) throw er - fs.close(fd, function (er) { - if (er) throw er - t.pass('works') - t.end() - }) - }) -}) - -test('open a non-existing file throws', function (t) { - var er - try { - var fd = fs.openSync('this file does not exist', 'r') - } catch (x) { - er = x - } - t.ok(er, 'should throw') - t.notOk(fd, 'should not get an fd') - t.equal(er.code, 'ENOENT') - - fs.open('neither does this file', 'r', function (er, fd) { - t.ok(er, 'should throw') - t.notOk(fd, 'should not get an fd') - t.equal(er.code, 'ENOENT') - t.end() - }) -}) diff --git a/node_modules/graceful-fs/test/readdir-sort.js b/node_modules/graceful-fs/test/readdir-sort.js deleted file mode 100644 index cb63a6846..000000000 --- a/node_modules/graceful-fs/test/readdir-sort.js +++ /dev/null @@ -1,20 +0,0 @@ -var test = require("tap").test -var fs = require("../fs.js") - -var readdir = fs.readdir -fs.readdir = function(path, cb) { - process.nextTick(function() { - cb(null, ["b", "z", "a"]) - }) -} - -var g = require("../") - -test("readdir reorder", function (t) { - g.readdir("whatevers", function (er, files) { - if (er) - throw er - t.same(files, [ "a", "b", "z" ]) - t.end() - }) -}) diff --git a/node_modules/graceful-fs/test/write-then-read.js b/node_modules/graceful-fs/test/write-then-read.js deleted file mode 100644 index 21e4c26bf..000000000 --- a/node_modules/graceful-fs/test/write-then-read.js +++ /dev/null @@ -1,47 +0,0 @@ -var fs = require('../'); -var rimraf = require('rimraf'); -var mkdirp = require('mkdirp'); -var test = require('tap').test; -var p = require('path').resolve(__dirname, 'files'); - -process.chdir(__dirname) - -// Make sure to reserve the stderr fd -process.stderr.write(''); - -var num = 4097; -var paths = new Array(num); - -test('make files', function (t) { - rimraf.sync(p); - mkdirp.sync(p); - - for (var i = 0; i < num; ++i) { - paths[i] = 'files/file-' + i; - fs.writeFileSync(paths[i], 'content'); - } - - t.end(); -}) - -test('read files', function (t) { - // now read them - var done = 0; - for (var i = 0; i < num; ++i) { - fs.readFile(paths[i], function(err, data) { - if (err) - throw err; - - ++done; - if (done === num) { - t.pass('success'); - t.end() - } - }); - } -}); - -test('cleanup', function (t) { - rimraf.sync(p); - t.end(); -}); |