Security update for permissions_by_term
[yaffs-website] / node_modules / graceful-fs / graceful-fs.js
1 // Monkey-patching the fs module.
2 // It's ugly, but there is simply no other way to do this.
3 var fs = module.exports = require('./fs.js')
4
5 var assert = require('assert')
6
7 // fix up some busted stuff, mostly on windows and old nodes
8 require('./polyfills.js')
9
10 var util = require('util')
11
12 function noop () {}
13
14 var debug = noop
15 if (util.debuglog)
16   debug = util.debuglog('gfs')
17 else if (/\bgfs\b/i.test(process.env.NODE_DEBUG || ''))
18   debug = function() {
19     var m = util.format.apply(util, arguments)
20     m = 'GFS: ' + m.split(/\n/).join('\nGFS: ')
21     console.error(m)
22   }
23
24 if (/\bgfs\b/i.test(process.env.NODE_DEBUG || '')) {
25   process.on('exit', function() {
26     debug('fds', fds)
27     debug(queue)
28     assert.equal(queue.length, 0)
29   })
30 }
31
32
33 var originalOpen = fs.open
34 fs.open = open
35
36 function open(path, flags, mode, cb) {
37   if (typeof mode === "function") cb = mode, mode = null
38   if (typeof cb !== "function") cb = noop
39   new OpenReq(path, flags, mode, cb)
40 }
41
42 function OpenReq(path, flags, mode, cb) {
43   this.path = path
44   this.flags = flags
45   this.mode = mode
46   this.cb = cb
47   Req.call(this)
48 }
49
50 util.inherits(OpenReq, Req)
51
52 OpenReq.prototype.process = function() {
53   originalOpen.call(fs, this.path, this.flags, this.mode, this.done)
54 }
55
56 var fds = {}
57 OpenReq.prototype.done = function(er, fd) {
58   debug('open done', er, fd)
59   if (fd)
60     fds['fd' + fd] = this.path
61   Req.prototype.done.call(this, er, fd)
62 }
63
64
65 var originalReaddir = fs.readdir
66 fs.readdir = readdir
67
68 function readdir(path, cb) {
69   if (typeof cb !== "function") cb = noop
70   new ReaddirReq(path, cb)
71 }
72
73 function ReaddirReq(path, cb) {
74   this.path = path
75   this.cb = cb
76   Req.call(this)
77 }
78
79 util.inherits(ReaddirReq, Req)
80
81 ReaddirReq.prototype.process = function() {
82   originalReaddir.call(fs, this.path, this.done)
83 }
84
85 ReaddirReq.prototype.done = function(er, files) {
86   if (files && files.sort)
87     files = files.sort()
88   Req.prototype.done.call(this, er, files)
89   onclose()
90 }
91
92
93 var originalClose = fs.close
94 fs.close = close
95
96 function close (fd, cb) {
97   debug('close', fd)
98   if (typeof cb !== "function") cb = noop
99   delete fds['fd' + fd]
100   originalClose.call(fs, fd, function(er) {
101     onclose()
102     cb(er)
103   })
104 }
105
106
107 var originalCloseSync = fs.closeSync
108 fs.closeSync = closeSync
109
110 function closeSync (fd) {
111   try {
112     return originalCloseSync(fd)
113   } finally {
114     onclose()
115   }
116 }
117
118
119 // Req class
120 function Req () {
121   // start processing
122   this.done = this.done.bind(this)
123   this.failures = 0
124   this.process()
125 }
126
127 Req.prototype.done = function (er, result) {
128   var tryAgain = false
129   if (er) {
130     var code = er.code
131     var tryAgain = code === "EMFILE" || code === "ENFILE"
132     if (process.platform === "win32")
133       tryAgain = tryAgain || code === "OK"
134   }
135
136   if (tryAgain) {
137     this.failures ++
138     enqueue(this)
139   } else {
140     var cb = this.cb
141     cb(er, result)
142   }
143 }
144
145 var queue = []
146
147 function enqueue(req) {
148   queue.push(req)
149   debug('enqueue %d %s', queue.length, req.constructor.name, req)
150 }
151
152 function onclose() {
153   var req = queue.shift()
154   if (req) {
155     debug('process', req.constructor.name, req)
156     req.process()
157   }
158 }