Skip to content

Commit 2159ad2

Browse files
kevvaisaacs
authored andcommitted
Don't error on ENOSYS, EINVAL or EPERM when changing ownership or mode
Fixes #49. EDIT(isaacs): Rebased latest, added tests to get back to 100% coverage. PR-URL: #55 Credit: @kevva Close: #55 Reviewed-by: @isaacs
1 parent e322288 commit 2159ad2

File tree

2 files changed

+243
-114
lines changed

2 files changed

+243
-114
lines changed

index.js

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ function serializeActiveFile (absoluteName) {
5555
})
5656
}
5757

58+
// https://github.com/isaacs/node-graceful-fs/blob/master/polyfills.js#L315-L342
59+
function isChownErrOk (err) {
60+
if (err.code === 'ENOSYS') {
61+
return true
62+
}
63+
64+
const nonroot = !process.getuid || process.getuid() !== 0
65+
if (nonroot) {
66+
if (err.code === 'EINVAL' || err.code === 'EPERM') {
67+
return true
68+
}
69+
}
70+
71+
return false
72+
}
73+
5874
async function writeFileAsync (filename, data, options = {}) {
5975
if (typeof options === 'string') {
6076
options = { encoding: options }
@@ -107,11 +123,19 @@ async function writeFileAsync (filename, data, options = {}) {
107123
fd = null
108124

109125
if (options.chown) {
110-
await promisify(fs.chown)(tmpfile, options.chown.uid, options.chown.gid)
126+
await promisify(fs.chown)(tmpfile, options.chown.uid, options.chown.gid).catch(err => {
127+
if (!isChownErrOk(err)) {
128+
throw err
129+
}
130+
})
111131
}
112132

113133
if (options.mode) {
114-
await promisify(fs.chmod)(tmpfile, options.mode)
134+
await promisify(fs.chmod)(tmpfile, options.mode).catch(err => {
135+
if (!isChownErrOk(err)) {
136+
throw err
137+
}
138+
})
115139
}
116140

117141
await promisify(fs.rename)(tmpfile, truename)
@@ -193,10 +217,30 @@ function writeFileSync (filename, data, options) {
193217
if (options.fsync !== false) {
194218
fs.fsyncSync(fd)
195219
}
220+
196221
fs.closeSync(fd)
197222
fd = null
198-
if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid)
199-
if (options.mode) fs.chmodSync(tmpfile, options.mode)
223+
224+
if (options.chown) {
225+
try {
226+
fs.chownSync(tmpfile, options.chown.uid, options.chown.gid)
227+
} catch (err) {
228+
if (!isChownErrOk(err)) {
229+
throw err
230+
}
231+
}
232+
}
233+
234+
if (options.mode) {
235+
try {
236+
fs.chmodSync(tmpfile, options.mode)
237+
} catch (err) {
238+
if (!isChownErrOk(err)) {
239+
throw err
240+
}
241+
}
242+
}
243+
200244
fs.renameSync(tmpfile, filename)
201245
threw = false
202246
} finally {

0 commit comments

Comments
 (0)