@@ -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+
5874async 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