"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/mv/node_modules/rimraf/rimraf.js" (8 Mar 2017, 5754 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 module.exports = rimraf
    2 rimraf.sync = rimrafSync
    3 
    4 var assert = require("assert")
    5 var path = require("path")
    6 var fs = require("fs")
    7 
    8 // for EMFILE handling
    9 var timeout = 0
   10 exports.EMFILE_MAX = 1000
   11 exports.BUSYTRIES_MAX = 3
   12 
   13 var isWindows = (process.platform === "win32")
   14 
   15 function defaults (options) {
   16   var methods = [
   17     'unlink',
   18     'chmod',
   19     'stat',
   20     'rmdir',
   21     'readdir'
   22   ]
   23   methods.forEach(function(m) {
   24     options[m] = options[m] || fs[m]
   25     m = m + 'Sync'
   26     options[m] = options[m] || fs[m]
   27   })
   28 }
   29 
   30 function rimraf (p, options, cb) {
   31   if (typeof options === 'function') {
   32     cb = options
   33     options = {}
   34   }
   35   assert(p)
   36   assert(options)
   37   assert(typeof cb === 'function')
   38 
   39   defaults(options)
   40 
   41   if (!cb) throw new Error("No callback passed to rimraf()")
   42 
   43   var busyTries = 0
   44   rimraf_(p, options, function CB (er) {
   45     if (er) {
   46       if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY") &&
   47           busyTries < exports.BUSYTRIES_MAX) {
   48         busyTries ++
   49         var time = busyTries * 100
   50         // try again, with the same exact callback as this one.
   51         return setTimeout(function () {
   52           rimraf_(p, options, CB)
   53         }, time)
   54       }
   55 
   56       // this one won't happen if graceful-fs is used.
   57       if (er.code === "EMFILE" && timeout < exports.EMFILE_MAX) {
   58         return setTimeout(function () {
   59           rimraf_(p, options, CB)
   60         }, timeout ++)
   61       }
   62 
   63       // already gone
   64       if (er.code === "ENOENT") er = null
   65     }
   66 
   67     timeout = 0
   68     cb(er)
   69   })
   70 }
   71 
   72 // Two possible strategies.
   73 // 1. Assume it's a file.  unlink it, then do the dir stuff on EPERM or EISDIR
   74 // 2. Assume it's a directory.  readdir, then do the file stuff on ENOTDIR
   75 //
   76 // Both result in an extra syscall when you guess wrong.  However, there
   77 // are likely far more normal files in the world than directories.  This
   78 // is based on the assumption that a the average number of files per
   79 // directory is >= 1.
   80 //
   81 // If anyone ever complains about this, then I guess the strategy could
   82 // be made configurable somehow.  But until then, YAGNI.
   83 function rimraf_ (p, options, cb) {
   84   assert(p)
   85   assert(options)
   86   assert(typeof cb === 'function')
   87 
   88   options.unlink(p, function (er) {
   89     if (er) {
   90       if (er.code === "ENOENT")
   91         return cb(null)
   92       if (er.code === "EPERM")
   93         return (isWindows)
   94           ? fixWinEPERM(p, options, er, cb)
   95           : rmdir(p, options, er, cb)
   96       if (er.code === "EISDIR")
   97         return rmdir(p, options, er, cb)
   98     }
   99     return cb(er)
  100   })
  101 }
  102 
  103 function fixWinEPERM (p, options, er, cb) {
  104   assert(p)
  105   assert(options)
  106   assert(typeof cb === 'function')
  107   if (er)
  108     assert(er instanceof Error)
  109 
  110   options.chmod(p, 666, function (er2) {
  111     if (er2)
  112       cb(er2.code === "ENOENT" ? null : er)
  113     else
  114       options.stat(p, function(er3, stats) {
  115         if (er3)
  116           cb(er3.code === "ENOENT" ? null : er)
  117         else if (stats.isDirectory())
  118           rmdir(p, options, er, cb)
  119         else
  120           options.unlink(p, cb)
  121       })
  122   })
  123 }
  124 
  125 function fixWinEPERMSync (p, options, er) {
  126   assert(p)
  127   assert(options)
  128   if (er)
  129     assert(er instanceof Error)
  130 
  131   try {
  132     options.chmodSync(p, 666)
  133   } catch (er2) {
  134     if (er2.code === "ENOENT")
  135       return
  136     else
  137       throw er
  138   }
  139 
  140   try {
  141     var stats = options.statSync(p)
  142   } catch (er3) {
  143     if (er3.code === "ENOENT")
  144       return
  145     else
  146       throw er
  147   }
  148 
  149   if (stats.isDirectory())
  150     rmdirSync(p, options, er)
  151   else
  152     options.unlinkSync(p)
  153 }
  154 
  155 function rmdir (p, options, originalEr, cb) {
  156   assert(p)
  157   assert(options)
  158   if (originalEr)
  159     assert(originalEr instanceof Error)
  160   assert(typeof cb === 'function')
  161 
  162   // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
  163   // if we guessed wrong, and it's not a directory, then
  164   // raise the original error.
  165   options.rmdir(p, function (er) {
  166     if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
  167       rmkids(p, options, cb)
  168     else if (er && er.code === "ENOTDIR")
  169       cb(originalEr)
  170     else
  171       cb(er)
  172   })
  173 }
  174 
  175 function rmkids(p, options, cb) {
  176   assert(p)
  177   assert(options)
  178   assert(typeof cb === 'function')
  179 
  180   options.readdir(p, function (er, files) {
  181     if (er)
  182       return cb(er)
  183     var n = files.length
  184     if (n === 0)
  185       return options.rmdir(p, cb)
  186     var errState
  187     files.forEach(function (f) {
  188       rimraf(path.join(p, f), options, function (er) {
  189         if (errState)
  190           return
  191         if (er)
  192           return cb(errState = er)
  193         if (--n === 0)
  194           options.rmdir(p, cb)
  195       })
  196     })
  197   })
  198 }
  199 
  200 // this looks simpler, and is strictly *faster*, but will
  201 // tie up the JavaScript thread and fail on excessively
  202 // deep directory trees.
  203 function rimrafSync (p, options) {
  204   options = options || {}
  205   defaults(options)
  206 
  207   assert(p)
  208   assert(options)
  209 
  210   try {
  211     options.unlinkSync(p)
  212   } catch (er) {
  213     if (er.code === "ENOENT")
  214       return
  215     if (er.code === "EPERM")
  216       return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
  217     if (er.code !== "EISDIR")
  218       throw er
  219     rmdirSync(p, options, er)
  220   }
  221 }
  222 
  223 function rmdirSync (p, options, originalEr) {
  224   assert(p)
  225   assert(options)
  226   if (originalEr)
  227     assert(originalEr instanceof Error)
  228 
  229   try {
  230     options.rmdirSync(p)
  231   } catch (er) {
  232     if (er.code === "ENOENT")
  233       return
  234     if (er.code === "ENOTDIR")
  235       throw originalEr
  236     if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
  237       rmkidsSync(p, options)
  238   }
  239 }
  240 
  241 function rmkidsSync (p, options) {
  242   assert(p)
  243   assert(options)
  244   options.readdirSync(p).forEach(function (f) {
  245     rimrafSync(path.join(p, f), options)
  246   })
  247   options.rmdirSync(p, options)
  248 }