Welcome to mirror list, hosted at ThFree Co, Russian Federation.

rimraf.js « rimraf « node_modules « npm « deps - github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 67d018ab4a3a3a1d22f643d3d53666fce41aa5f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
module.exports = rimraf
rimraf.sync = rimrafSync

var path = require("path")
  , fs

try {
  // optional dependency
  fs = require("graceful-fs")
} catch (er) {
  fs = require("fs")
}

var lstat = process.platform === "win32" ? "stat" : "lstat"
  , lstatSync = lstat + "Sync"

// for EMFILE handling
var timeout = 0
exports.EMFILE_MAX = 1000
exports.BUSYTRIES_MAX = 3

function rimraf (p, cb) {

  if (!cb) throw new Error("No callback passed to rimraf()")

  var busyTries = 0

  rimraf_(p, function CB (er) {
    if (er) {
      if (er.code === "EBUSY" && busyTries < exports.BUSYTRIES_MAX) {
        var time = (exports.BUSYTRIES_MAX - busyTries) * 100
        busyTries ++
        // try again, with the same exact callback as this one.
        return setTimeout(function () {
          rimraf_(p, CB)
        })
      }

      // this one won't happen if graceful-fs is used.
      if (er.code === "EMFILE" && timeout < exports.EMFILE_MAX) {
        return setTimeout(function () {
          rimraf_(p, CB)
        }, timeout ++)
      }

      // already gone
      if (er.code === "ENOENT") er = null
    }

    timeout = 0
    cb(er)
  })
}

function rimraf_ (p, cb) {
  fs[lstat](p, function (er, s) {
    if (er) {
      // already gone
      if (er.code === "ENOENT") return cb()
      // some other kind of error, permissions, etc.
      return cb(er)
    }

    return rm_(p, s, false, cb)
  })
}


var myGid = function myGid () {
  var g = process.getuid && process.getgid()
  myGid = function myGid () { return g }
  return g
}

var myUid = function myUid () {
  var u = process.getuid && process.getuid()
  myUid = function myUid () { return u }
  return u
}


function writable (s) {
  var mode = s.mode || 0777
    , uid = myUid()
    , gid = myGid()
  return (mode & 0002)
      || (gid === s.gid && (mode & 0020))
      || (uid === s.uid && (mode & 0200))
}

function rm_ (p, s, didWritableCheck, cb) {
  if (!didWritableCheck && !writable(s)) {
    // make file writable
    // user/group/world, doesn't matter at this point
    // since it's about to get nuked.
    return fs.chmod(p, s.mode | 0222, function (er) {
      if (er) return cb(er)
      rm_(p, s, true, cb)
    })
  }

  if (!s.isDirectory()) {
    return fs.unlink(p, cb)
  }

  // directory
  fs.readdir(p, function (er, files) {
    if (er) return cb(er)
    asyncForEach(files.map(function (f) {
      return path.join(p, f)
    }), function (file, cb) {
      rimraf(file, cb)
    }, function (er) {
      if (er) return cb(er)
      fs.rmdir(p, cb)
    })
  })
}

function asyncForEach (list, fn, cb) {
  if (!list.length) cb()
  var c = list.length
    , errState = null
  list.forEach(function (item, i, list) {
    fn(item, function (er) {
      if (errState) return
      if (er) return cb(errState = er)
      if (-- c === 0) return cb()
    })
  })
}

// this looks simpler, but it will fail with big directory trees,
// or on slow stupid awful cygwin filesystems
function rimrafSync (p) {
  try {
    var s = fs[lstatSync](p)
  } catch (er) {
    if (er.code === "ENOENT") return
    throw er
  }

  if (!writable(s)) {
    fs.chmodSync(p, s.mode | 0222)
  }

  if (!s.isDirectory()) return fs.unlinkSync(p)

  fs.readdirSync(p).forEach(function (f) {
    rimrafSync(path.join(p, f))
  })
  fs.rmdirSync(p)
}