"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/graceful-fs/polyfills.js" (8 Mar 2017, 8836 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 var fs = require('./fs.js')
    2 var constants = require('constants')
    3 
    4 var origCwd = process.cwd
    5 var cwd = null
    6 
    7 var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform
    8 
    9 process.cwd = function() {
   10   if (!cwd)
   11     cwd = origCwd.call(process)
   12   return cwd
   13 }
   14 try {
   15   process.cwd()
   16 } catch (er) {}
   17 
   18 var chdir = process.chdir
   19 process.chdir = function(d) {
   20   cwd = null
   21   chdir.call(process, d)
   22 }
   23 
   24 module.exports = patch
   25 
   26 function patch (fs) {
   27   // (re-)implement some things that are known busted or missing.
   28 
   29   // lchmod, broken prior to 0.6.2
   30   // back-port the fix here.
   31   if (constants.hasOwnProperty('O_SYMLINK') &&
   32       process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
   33     patchLchmod(fs)
   34   }
   35 
   36   // lutimes implementation, or no-op
   37   if (!fs.lutimes) {
   38     patchLutimes(fs)
   39   }
   40 
   41   // https://github.com/isaacs/node-graceful-fs/issues/4
   42   // Chown should not fail on einval or eperm if non-root.
   43   // It should not fail on enosys ever, as this just indicates
   44   // that a fs doesn't support the intended operation.
   45 
   46   fs.chown = chownFix(fs.chown)
   47   fs.fchown = chownFix(fs.fchown)
   48   fs.lchown = chownFix(fs.lchown)
   49 
   50   fs.chmod = chmodFix(fs.chmod)
   51   fs.fchmod = chmodFix(fs.fchmod)
   52   fs.lchmod = chmodFix(fs.lchmod)
   53 
   54   fs.chownSync = chownFixSync(fs.chownSync)
   55   fs.fchownSync = chownFixSync(fs.fchownSync)
   56   fs.lchownSync = chownFixSync(fs.lchownSync)
   57 
   58   fs.chmodSync = chmodFixSync(fs.chmodSync)
   59   fs.fchmodSync = chmodFixSync(fs.fchmodSync)
   60   fs.lchmodSync = chmodFixSync(fs.lchmodSync)
   61 
   62   fs.stat = statFix(fs.stat)
   63   fs.fstat = statFix(fs.fstat)
   64   fs.lstat = statFix(fs.lstat)
   65 
   66   fs.statSync = statFixSync(fs.statSync)
   67   fs.fstatSync = statFixSync(fs.fstatSync)
   68   fs.lstatSync = statFixSync(fs.lstatSync)
   69 
   70   // if lchmod/lchown do not exist, then make them no-ops
   71   if (!fs.lchmod) {
   72     fs.lchmod = function (path, mode, cb) {
   73       if (cb) process.nextTick(cb)
   74     }
   75     fs.lchmodSync = function () {}
   76   }
   77   if (!fs.lchown) {
   78     fs.lchown = function (path, uid, gid, cb) {
   79       if (cb) process.nextTick(cb)
   80     }
   81     fs.lchownSync = function () {}
   82   }
   83 
   84   // on Windows, A/V software can lock the directory, causing this
   85   // to fail with an EACCES or EPERM if the directory contains newly
   86   // created files.  Try again on failure, for up to 60 seconds.
   87 
   88   // Set the timeout this long because some Windows Anti-Virus, such as Parity
   89   // bit9, may lock files for up to a minute, causing npm package install
   90   // failures. Also, take care to yield the scheduler. Windows scheduling gives
   91   // CPU to a busy looping process, which can cause the program causing the lock
   92   // contention to be starved of CPU by node, so the contention doesn't resolve.
   93   if (platform === "win32") {
   94     fs.rename = (function (fs$rename) { return function (from, to, cb) {
   95       var start = Date.now()
   96       var backoff = 0;
   97       fs$rename(from, to, function CB (er) {
   98         if (er
   99             && (er.code === "EACCES" || er.code === "EPERM")
  100             && Date.now() - start < 60000) {
  101           setTimeout(function() {
  102             fs.stat(to, function (stater, st) {
  103               if (stater && stater.code === "ENOENT")
  104                 fs$rename(from, to, CB);
  105               else
  106                 cb(er)
  107             })
  108           }, backoff)
  109           if (backoff < 100)
  110             backoff += 10;
  111           return;
  112         }
  113         if (cb) cb(er)
  114       })
  115     }})(fs.rename)
  116   }
  117 
  118   // if read() returns EAGAIN, then just try it again.
  119   fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) {
  120     var callback
  121     if (callback_ && typeof callback_ === 'function') {
  122       var eagCounter = 0
  123       callback = function (er, _, __) {
  124         if (er && er.code === 'EAGAIN' && eagCounter < 10) {
  125           eagCounter ++
  126           return fs$read.call(fs, fd, buffer, offset, length, position, callback)
  127         }
  128         callback_.apply(this, arguments)
  129       }
  130     }
  131     return fs$read.call(fs, fd, buffer, offset, length, position, callback)
  132   }})(fs.read)
  133 
  134   fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) {
  135     var eagCounter = 0
  136     while (true) {
  137       try {
  138         return fs$readSync.call(fs, fd, buffer, offset, length, position)
  139       } catch (er) {
  140         if (er.code === 'EAGAIN' && eagCounter < 10) {
  141           eagCounter ++
  142           continue
  143         }
  144         throw er
  145       }
  146     }
  147   }})(fs.readSync)
  148 }
  149 
  150 function patchLchmod (fs) {
  151   fs.lchmod = function (path, mode, callback) {
  152     fs.open( path
  153            , constants.O_WRONLY | constants.O_SYMLINK
  154            , mode
  155            , function (err, fd) {
  156       if (err) {
  157         if (callback) callback(err)
  158         return
  159       }
  160       // prefer to return the chmod error, if one occurs,
  161       // but still try to close, and report closing errors if they occur.
  162       fs.fchmod(fd, mode, function (err) {
  163         fs.close(fd, function(err2) {
  164           if (callback) callback(err || err2)
  165         })
  166       })
  167     })
  168   }
  169 
  170   fs.lchmodSync = function (path, mode) {
  171     var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
  172 
  173     // prefer to return the chmod error, if one occurs,
  174     // but still try to close, and report closing errors if they occur.
  175     var threw = true
  176     var ret
  177     try {
  178       ret = fs.fchmodSync(fd, mode)
  179       threw = false
  180     } finally {
  181       if (threw) {
  182         try {
  183           fs.closeSync(fd)
  184         } catch (er) {}
  185       } else {
  186         fs.closeSync(fd)
  187       }
  188     }
  189     return ret
  190   }
  191 }
  192 
  193 function patchLutimes (fs) {
  194   if (constants.hasOwnProperty("O_SYMLINK")) {
  195     fs.lutimes = function (path, at, mt, cb) {
  196       fs.open(path, constants.O_SYMLINK, function (er, fd) {
  197         if (er) {
  198           if (cb) cb(er)
  199           return
  200         }
  201         fs.futimes(fd, at, mt, function (er) {
  202           fs.close(fd, function (er2) {
  203             if (cb) cb(er || er2)
  204           })
  205         })
  206       })
  207     }
  208 
  209     fs.lutimesSync = function (path, at, mt) {
  210       var fd = fs.openSync(path, constants.O_SYMLINK)
  211       var ret
  212       var threw = true
  213       try {
  214         ret = fs.futimesSync(fd, at, mt)
  215         threw = false
  216       } finally {
  217         if (threw) {
  218           try {
  219             fs.closeSync(fd)
  220           } catch (er) {}
  221         } else {
  222           fs.closeSync(fd)
  223         }
  224       }
  225       return ret
  226     }
  227 
  228   } else {
  229     fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) }
  230     fs.lutimesSync = function () {}
  231   }
  232 }
  233 
  234 function chmodFix (orig) {
  235   if (!orig) return orig
  236   return function (target, mode, cb) {
  237     return orig.call(fs, target, mode, function (er) {
  238       if (chownErOk(er)) er = null
  239       if (cb) cb.apply(this, arguments)
  240     })
  241   }
  242 }
  243 
  244 function chmodFixSync (orig) {
  245   if (!orig) return orig
  246   return function (target, mode) {
  247     try {
  248       return orig.call(fs, target, mode)
  249     } catch (er) {
  250       if (!chownErOk(er)) throw er
  251     }
  252   }
  253 }
  254 
  255 
  256 function chownFix (orig) {
  257   if (!orig) return orig
  258   return function (target, uid, gid, cb) {
  259     return orig.call(fs, target, uid, gid, function (er) {
  260       if (chownErOk(er)) er = null
  261       if (cb) cb.apply(this, arguments)
  262     })
  263   }
  264 }
  265 
  266 function chownFixSync (orig) {
  267   if (!orig) return orig
  268   return function (target, uid, gid) {
  269     try {
  270       return orig.call(fs, target, uid, gid)
  271     } catch (er) {
  272       if (!chownErOk(er)) throw er
  273     }
  274   }
  275 }
  276 
  277 
  278 function statFix (orig) {
  279   if (!orig) return orig
  280   // Older versions of Node erroneously returned signed integers for
  281   // uid + gid.
  282   return function (target, cb) {
  283     return orig.call(fs, target, function (er, stats) {
  284       if (!stats) return cb.apply(this, arguments)
  285       if (stats.uid < 0) stats.uid += 0x100000000
  286       if (stats.gid < 0) stats.gid += 0x100000000
  287       if (cb) cb.apply(this, arguments)
  288     })
  289   }
  290 }
  291 
  292 function statFixSync (orig) {
  293   if (!orig) return orig
  294   // Older versions of Node erroneously returned signed integers for
  295   // uid + gid.
  296   return function (target) {
  297     var stats = orig.call(fs, target)
  298     if (stats.uid < 0) stats.uid += 0x100000000
  299     if (stats.gid < 0) stats.gid += 0x100000000
  300     return stats;
  301   }
  302 }
  303 
  304 // ENOSYS means that the fs doesn't support the op. Just ignore
  305 // that, because it doesn't matter.
  306 //
  307 // if there's no getuid, or if getuid() is something other
  308 // than 0, and the error is EINVAL or EPERM, then just ignore
  309 // it.
  310 //
  311 // This specific case is a silent failure in cp, install, tar,
  312 // and most other unix tools that manage permissions.
  313 //
  314 // When running as root, or if other types of errors are
  315 // encountered, then it's strict.
  316 function chownErOk (er) {
  317   if (!er)
  318     return true
  319 
  320   if (er.code === "ENOSYS")
  321     return true
  322 
  323   var nonroot = !process.getuid || process.getuid() !== 0
  324   if (nonroot) {
  325     if (er.code === "EINVAL" || er.code === "EPERM")
  326       return true
  327   }
  328 
  329   return false
  330 }