Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81164 views
1
var fs = require('./fs.js')
2
var constants = require('constants')
3
4
var origCwd = process.cwd
5
var cwd = null
6
process.cwd = function() {
7
if (!cwd)
8
cwd = origCwd.call(process)
9
return cwd
10
}
11
var chdir = process.chdir
12
process.chdir = function(d) {
13
cwd = null
14
chdir.call(process, d)
15
}
16
17
// (re-)implement some things that are known busted or missing.
18
19
// lchmod, broken prior to 0.6.2
20
// back-port the fix here.
21
if (constants.hasOwnProperty('O_SYMLINK') &&
22
process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
23
fs.lchmod = function (path, mode, callback) {
24
callback = callback || noop
25
fs.open( path
26
, constants.O_WRONLY | constants.O_SYMLINK
27
, mode
28
, function (err, fd) {
29
if (err) {
30
callback(err)
31
return
32
}
33
// prefer to return the chmod error, if one occurs,
34
// but still try to close, and report closing errors if they occur.
35
fs.fchmod(fd, mode, function (err) {
36
fs.close(fd, function(err2) {
37
callback(err || err2)
38
})
39
})
40
})
41
}
42
43
fs.lchmodSync = function (path, mode) {
44
var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
45
46
// prefer to return the chmod error, if one occurs,
47
// but still try to close, and report closing errors if they occur.
48
var err, err2
49
try {
50
var ret = fs.fchmodSync(fd, mode)
51
} catch (er) {
52
err = er
53
}
54
try {
55
fs.closeSync(fd)
56
} catch (er) {
57
err2 = er
58
}
59
if (err || err2) throw (err || err2)
60
return ret
61
}
62
}
63
64
65
// lutimes implementation, or no-op
66
if (!fs.lutimes) {
67
if (constants.hasOwnProperty("O_SYMLINK")) {
68
fs.lutimes = function (path, at, mt, cb) {
69
fs.open(path, constants.O_SYMLINK, function (er, fd) {
70
cb = cb || noop
71
if (er) return cb(er)
72
fs.futimes(fd, at, mt, function (er) {
73
fs.close(fd, function (er2) {
74
return cb(er || er2)
75
})
76
})
77
})
78
}
79
80
fs.lutimesSync = function (path, at, mt) {
81
var fd = fs.openSync(path, constants.O_SYMLINK)
82
, err
83
, err2
84
, ret
85
86
try {
87
var ret = fs.futimesSync(fd, at, mt)
88
} catch (er) {
89
err = er
90
}
91
try {
92
fs.closeSync(fd)
93
} catch (er) {
94
err2 = er
95
}
96
if (err || err2) throw (err || err2)
97
return ret
98
}
99
100
} else if (fs.utimensat && constants.hasOwnProperty("AT_SYMLINK_NOFOLLOW")) {
101
// maybe utimensat will be bound soonish?
102
fs.lutimes = function (path, at, mt, cb) {
103
fs.utimensat(path, at, mt, constants.AT_SYMLINK_NOFOLLOW, cb)
104
}
105
106
fs.lutimesSync = function (path, at, mt) {
107
return fs.utimensatSync(path, at, mt, constants.AT_SYMLINK_NOFOLLOW)
108
}
109
110
} else {
111
fs.lutimes = function (_a, _b, _c, cb) { process.nextTick(cb) }
112
fs.lutimesSync = function () {}
113
}
114
}
115
116
117
// https://github.com/isaacs/node-graceful-fs/issues/4
118
// Chown should not fail on einval or eperm if non-root.
119
// It should not fail on enosys ever, as this just indicates
120
// that a fs doesn't support the intended operation.
121
122
fs.chown = chownFix(fs.chown)
123
fs.fchown = chownFix(fs.fchown)
124
fs.lchown = chownFix(fs.lchown)
125
126
fs.chmod = chownFix(fs.chmod)
127
fs.fchmod = chownFix(fs.fchmod)
128
fs.lchmod = chownFix(fs.lchmod)
129
130
fs.chownSync = chownFixSync(fs.chownSync)
131
fs.fchownSync = chownFixSync(fs.fchownSync)
132
fs.lchownSync = chownFixSync(fs.lchownSync)
133
134
fs.chmodSync = chownFix(fs.chmodSync)
135
fs.fchmodSync = chownFix(fs.fchmodSync)
136
fs.lchmodSync = chownFix(fs.lchmodSync)
137
138
function chownFix (orig) {
139
if (!orig) return orig
140
return function (target, uid, gid, cb) {
141
return orig.call(fs, target, uid, gid, function (er, res) {
142
if (chownErOk(er)) er = null
143
cb(er, res)
144
})
145
}
146
}
147
148
function chownFixSync (orig) {
149
if (!orig) return orig
150
return function (target, uid, gid) {
151
try {
152
return orig.call(fs, target, uid, gid)
153
} catch (er) {
154
if (!chownErOk(er)) throw er
155
}
156
}
157
}
158
159
// ENOSYS means that the fs doesn't support the op. Just ignore
160
// that, because it doesn't matter.
161
//
162
// if there's no getuid, or if getuid() is something other
163
// than 0, and the error is EINVAL or EPERM, then just ignore
164
// it.
165
//
166
// This specific case is a silent failure in cp, install, tar,
167
// and most other unix tools that manage permissions.
168
//
169
// When running as root, or if other types of errors are
170
// encountered, then it's strict.
171
function chownErOk (er) {
172
if (!er)
173
return true
174
175
if (er.code === "ENOSYS")
176
return true
177
178
var nonroot = !process.getuid || process.getuid() !== 0
179
if (nonroot) {
180
if (er.code === "EINVAL" || er.code === "EPERM")
181
return true
182
}
183
184
return false
185
}
186
187
188
// if lchmod/lchown do not exist, then make them no-ops
189
if (!fs.lchmod) {
190
fs.lchmod = function (path, mode, cb) {
191
process.nextTick(cb)
192
}
193
fs.lchmodSync = function () {}
194
}
195
if (!fs.lchown) {
196
fs.lchown = function (path, uid, gid, cb) {
197
process.nextTick(cb)
198
}
199
fs.lchownSync = function () {}
200
}
201
202
203
204
// on Windows, A/V software can lock the directory, causing this
205
// to fail with an EACCES or EPERM if the directory contains newly
206
// created files. Try again on failure, for up to 1 second.
207
if (process.platform === "win32") {
208
var rename_ = fs.rename
209
fs.rename = function rename (from, to, cb) {
210
var start = Date.now()
211
rename_(from, to, function CB (er) {
212
if (er
213
&& (er.code === "EACCES" || er.code === "EPERM")
214
&& Date.now() - start < 1000) {
215
return rename_(from, to, CB)
216
}
217
if(cb) cb(er)
218
})
219
}
220
}
221
222
223
// if read() returns EAGAIN, then just try it again.
224
var read = fs.read
225
fs.read = function (fd, buffer, offset, length, position, callback_) {
226
var callback
227
if (callback_ && typeof callback_ === 'function') {
228
var eagCounter = 0
229
callback = function (er, _, __) {
230
if (er && er.code === 'EAGAIN' && eagCounter < 10) {
231
eagCounter ++
232
return read.call(fs, fd, buffer, offset, length, position, callback)
233
}
234
callback_.apply(this, arguments)
235
}
236
}
237
return read.call(fs, fd, buffer, offset, length, position, callback)
238
}
239
240
var readSync = fs.readSync
241
fs.readSync = function (fd, buffer, offset, length, position) {
242
var eagCounter = 0
243
while (true) {
244
try {
245
return readSync.call(fs, fd, buffer, offset, length, position)
246
} catch (er) {
247
if (er.code === 'EAGAIN' && eagCounter < 10) {
248
eagCounter ++
249
continue
250
}
251
throw er
252
}
253
}
254
}
255
256
257