@@ -11,6 +11,24 @@ const needEISDIRHandled = fs.lchown &&
1111 ! process . version . match ( / v 1 [ 1 - 9 ] + \. / ) &&
1212 ! process . version . match ( / v 1 0 \. [ 6 - 9 ] / )
1313
14+ const lchownSync = ( path , uid , gid ) => {
15+ try {
16+ return fs [ LCHOWNSYNC ] ( path , uid , gid )
17+ } catch ( er ) {
18+ if ( er . code !== 'ENOENT' )
19+ throw er
20+ }
21+ }
22+
23+ const chownSync = ( path , uid , gid ) => {
24+ try {
25+ return fs . chownSync ( path , uid , gid )
26+ } catch ( er ) {
27+ if ( er . code !== 'ENOENT' )
28+ throw er
29+ }
30+ }
31+
1432/* istanbul ignore next */
1533const handleEISDIR =
1634 needEISDIRHandled ? ( path , uid , gid , cb ) => er => {
@@ -28,14 +46,14 @@ const handleEISDIR =
2846const handleEISDirSync =
2947 needEISDIRHandled ? ( path , uid , gid ) => {
3048 try {
31- return fs [ LCHOWNSYNC ] ( path , uid , gid )
49+ return lchownSync ( path , uid , gid )
3250 } catch ( er ) {
3351 if ( er . code !== 'EISDIR' )
3452 throw er
35- fs . chownSync ( path , uid , gid )
53+ chownSync ( path , uid , gid )
3654 }
3755 }
38- : ( path , uid , gid ) => fs [ LCHOWNSYNC ] ( path , uid , gid )
56+ : ( path , uid , gid ) => lchownSync ( path , uid , gid )
3957
4058// fs.readdir could only accept an options object as of node v6
4159const nodeVersion = process . version
@@ -45,9 +63,19 @@ let readdirSync = (path, options) => fs.readdirSync(path, options)
4563if ( / ^ v 4 \. / . test ( nodeVersion ) )
4664 readdir = ( path , options , cb ) => fs . readdir ( path , cb )
4765
66+ const chown = ( cpath , uid , gid , cb ) => {
67+ fs [ LCHOWN ] ( cpath , uid , gid , handleEISDIR ( cpath , uid , gid , er => {
68+ // Skip ENOENT error
69+ if ( er && er . code === 'ENOENT' ) return cb ( )
70+ cb ( er )
71+ } ) )
72+ }
73+
4874const chownrKid = ( p , child , uid , gid , cb ) => {
4975 if ( typeof child === 'string' )
5076 return fs . lstat ( path . resolve ( p , child ) , ( er , stats ) => {
77+ // Skip ENOENT error
78+ if ( er && er . code === 'ENOENT' ) return cb ( )
5179 if ( er )
5280 return cb ( er )
5381 stats . name = child
@@ -59,11 +87,11 @@ const chownrKid = (p, child, uid, gid, cb) => {
5987 if ( er )
6088 return cb ( er )
6189 const cpath = path . resolve ( p , child . name )
62- fs [ LCHOWN ] ( cpath , uid , gid , handleEISDIR ( cpath , uid , gid , cb ) )
90+ chown ( cpath , uid , gid , cb )
6391 } )
6492 } else {
6593 const cpath = path . resolve ( p , child . name )
66- fs [ LCHOWN ] ( cpath , uid , gid , handleEISDIR ( cpath , uid , gid , cb ) )
94+ chown ( cpath , uid , gid , cb )
6795 }
6896}
6997
@@ -74,8 +102,10 @@ const chownr = (p, uid, gid, cb) => {
74102 // or doesn't exist. give up.
75103 if ( er && er . code !== 'ENOTDIR' && er . code !== 'ENOTSUP' )
76104 return cb ( er )
105+ if ( er && er . code === 'ENOENT' )
106+ return cb ( )
77107 if ( er || ! children . length )
78- return fs [ LCHOWN ] ( p , uid , gid , handleEISDIR ( p , uid , gid , cb ) )
108+ return chown ( p , uid , gid , cb )
79109
80110 let len = children . length
81111 let errState = null
@@ -85,7 +115,7 @@ const chownr = (p, uid, gid, cb) => {
85115 if ( er )
86116 return cb ( errState = er )
87117 if ( -- len === 0 )
88- return fs [ LCHOWN ] ( p , uid , gid , handleEISDIR ( p , uid , gid , cb ) )
118+ return chown ( p , uid , gid , cb )
89119 }
90120
91121 children . forEach ( child => chownrKid ( p , child , uid , gid , then ) )
@@ -94,9 +124,14 @@ const chownr = (p, uid, gid, cb) => {
94124
95125const chownrKidSync = ( p , child , uid , gid ) => {
96126 if ( typeof child === 'string' ) {
97- const stats = fs . lstatSync ( path . resolve ( p , child ) )
98- stats . name = child
99- child = stats
127+ try {
128+ const stats = fs . lstatSync ( path . resolve ( p , child ) )
129+ stats . name = child
130+ child = stats
131+ } catch ( er ) {
132+ if ( er . code === 'ENOENT' ) return
133+ throw er ;
134+ }
100135 }
101136
102137 if ( child . isDirectory ( ) )
@@ -112,6 +147,7 @@ const chownrSync = (p, uid, gid) => {
112147 } catch ( er ) {
113148 if ( er && er . code === 'ENOTDIR' && er . code !== 'ENOTSUP' )
114149 return handleEISDirSync ( p , uid , gid )
150+ if ( er && er . code === 'ENOENT' ) return
115151 throw er
116152 }
117153
0 commit comments