diff options
Diffstat (limited to 'deps/npm/node_modules/sha/node_modules/graceful-fs/polyfills.js')
-rw-r--r-- | deps/npm/node_modules/sha/node_modules/graceful-fs/polyfills.js | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/deps/npm/node_modules/sha/node_modules/graceful-fs/polyfills.js b/deps/npm/node_modules/sha/node_modules/graceful-fs/polyfills.js new file mode 100644 index 0000000000..8ac5006e2d --- /dev/null +++ b/deps/npm/node_modules/sha/node_modules/graceful-fs/polyfills.js @@ -0,0 +1,254 @@ +var fs = require('./fs.js') +var constants = require('constants') + +var origCwd = process.cwd +var cwd = null +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd +} +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} + +// (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\./)) { + fs.lchmod = function (path, mode, callback) { + callback = callback || noop + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + callback(err || err2) + }) + }) + }) + } + + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // 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 + } + try { + fs.closeSync(fd) + } catch (er) { + err2 = er + } + if (err || err2) throw (err || err2) + return ret + } +} + + +// lutimes implementation, or no-op +if (!fs.lutimes) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + cb = cb || noop + if (er) return cb(er) + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + return cb(er || er2) + }) + }) + }) + } + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + , err + , err2 + , ret + + try { + var ret = fs.futimesSync(fd, at, mt) + } catch (er) { + err = er + } + try { + fs.closeSync(fd) + } catch (er) { + err2 = er + } + 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) { + return orig.call(fs, target, uid, gid, function (er, res) { + if (chownErOk(er)) er = null + cb(er, res) + }) + } +} + +function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } +} + +// ENOSYS means that the fs doesn't support the op. Just ignore +// that, because it doesn't matter. +// +// if there's no getuid, or if getuid() is something other +// than 0, and the error is EINVAL or EPERM, then just ignore +// it. +// +// This specific case is a silent failure in cp, install, tar, +// and most other unix tools that manage permissions. +// +// When running as root, or if other types of errors are +// encountered, then it's strict. +function chownErOk (er) { + if (!er) + return true + + if (er.code === "ENOSYS") + return true + + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + 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 + } + } +} |