| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 | var fs = require('fs')var constants = require('constants')var origCwd = process.cwdvar cwd = nullprocess.cwd = function() {  if (!cwd)    cwd = origCwd.call(process)  return cwd}var chdir = process.chdirprocess.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-opif (!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.fs.chown = chownFix(fs.chown)fs.fchown = chownFix(fs.fchown)fs.lchown = chownFix(fs.lchown)fs.chownSync = chownFixSync(fs.chownSync)fs.fchownSync = chownFixSync(fs.fchownSync)fs.lchownSync = chownFixSync(fs.lchownSync)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    }  }}function chownErOk (er) {  // 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.  if (!er || (!process.getuid || process.getuid() !== 0)      && (er.code === "EINVAL" || er.code === "EPERM")) return true}// if lchmod/lchown do not exist, then make them no-opsif (!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)      }      cb(er)    })  }}// if read() returns EAGAIN, then just try it again.var read = fs.readfs.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.readSyncfs.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    }  }}
 |