Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80629 views
1
var fs = require('fs')
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
120
fs.chown = chownFix(fs.chown)
121
fs.fchown = chownFix(fs.fchown)
122
fs.lchown = chownFix(fs.lchown)
123
124
fs.chownSync = chownFixSync(fs.chownSync)
125
fs.fchownSync = chownFixSync(fs.fchownSync)
126
fs.lchownSync = chownFixSync(fs.lchownSync)
127
128
function chownFix (orig) {
129
if (!orig) return orig
130
return function (target, uid, gid, cb) {
131
return orig.call(fs, target, uid, gid, function (er, res) {
132
if (chownErOk(er)) er = null
133
cb(er, res)
134
})
135
}
136
}
137
138
function chownFixSync (orig) {
139
if (!orig) return orig
140
return function (target, uid, gid) {
141
try {
142
return orig.call(fs, target, uid, gid)
143
} catch (er) {
144
if (!chownErOk(er)) throw er
145
}
146
}
147
}
148
149
function chownErOk (er) {
150
// if there's no getuid, or if getuid() is something other than 0,
151
// and the error is EINVAL or EPERM, then just ignore it.
152
// This specific case is a silent failure in cp, install, tar,
153
// and most other unix tools that manage permissions.
154
// When running as root, or if other types of errors are encountered,
155
// then it's strict.
156
if (!er || (!process.getuid || process.getuid() !== 0)
157
&& (er.code === "EINVAL" || er.code === "EPERM")) return true
158
}
159
160
161
// if lchmod/lchown do not exist, then make them no-ops
162
if (!fs.lchmod) {
163
fs.lchmod = function (path, mode, cb) {
164
process.nextTick(cb)
165
}
166
fs.lchmodSync = function () {}
167
}
168
if (!fs.lchown) {
169
fs.lchown = function (path, uid, gid, cb) {
170
process.nextTick(cb)
171
}
172
fs.lchownSync = function () {}
173
}
174
175
176
177
// on Windows, A/V software can lock the directory, causing this
178
// to fail with an EACCES or EPERM if the directory contains newly
179
// created files. Try again on failure, for up to 1 second.
180
if (process.platform === "win32") {
181
var rename_ = fs.rename
182
fs.rename = function rename (from, to, cb) {
183
var start = Date.now()
184
rename_(from, to, function CB (er) {
185
if (er
186
&& (er.code === "EACCES" || er.code === "EPERM")
187
&& Date.now() - start < 1000) {
188
return rename_(from, to, CB)
189
}
190
cb(er)
191
})
192
}
193
}
194
195
196
// if read() returns EAGAIN, then just try it again.
197
var read = fs.read
198
fs.read = function (fd, buffer, offset, length, position, callback_) {
199
var callback
200
if (callback_ && typeof callback_ === 'function') {
201
var eagCounter = 0
202
callback = function (er, _, __) {
203
if (er && er.code === 'EAGAIN' && eagCounter < 10) {
204
eagCounter ++
205
return read.call(fs, fd, buffer, offset, length, position, callback)
206
}
207
callback_.apply(this, arguments)
208
}
209
}
210
return read.call(fs, fd, buffer, offset, length, position, callback)
211
}
212
213
var readSync = fs.readSync
214
fs.readSync = function (fd, buffer, offset, length, position) {
215
var eagCounter = 0
216
while (true) {
217
try {
218
return readSync.call(fs, fd, buffer, offset, length, position)
219
} catch (er) {
220
if (er.code === 'EAGAIN' && eagCounter < 10) {
221
eagCounter ++
222
continue
223
}
224
throw er
225
}
226
}
227
}
228
229
230