@@ -55,6 +55,22 @@ function serializeActiveFile (absoluteName) {
55
55
} )
56
56
}
57
57
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
+
58
74
async function writeFileAsync ( filename , data , options = { } ) {
59
75
if ( typeof options === 'string' ) {
60
76
options = { encoding : options }
@@ -107,11 +123,19 @@ async function writeFileAsync (filename, data, options = {}) {
107
123
fd = null
108
124
109
125
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
+ } )
111
131
}
112
132
113
133
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
+ } )
115
139
}
116
140
117
141
await promisify ( fs . rename ) ( tmpfile , truename )
@@ -193,10 +217,30 @@ function writeFileSync (filename, data, options) {
193
217
if ( options . fsync !== false ) {
194
218
fs . fsyncSync ( fd )
195
219
}
220
+
196
221
fs . closeSync ( fd )
197
222
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
+
200
244
fs . renameSync ( tmpfile , filename )
201
245
threw = false
202
246
} finally {
0 commit comments