@@ -11,6 +11,24 @@ const needEISDIRHandled = fs.lchown &&
11
11
! process . version . match ( / v 1 [ 1 - 9 ] + \. / ) &&
12
12
! process . version . match ( / v 1 0 \. [ 6 - 9 ] / )
13
13
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
+
14
32
/* istanbul ignore next */
15
33
const handleEISDIR =
16
34
needEISDIRHandled ? ( path , uid , gid , cb ) => er => {
@@ -28,14 +46,14 @@ const handleEISDIR =
28
46
const handleEISDirSync =
29
47
needEISDIRHandled ? ( path , uid , gid ) => {
30
48
try {
31
- return fs [ LCHOWNSYNC ] ( path , uid , gid )
49
+ return lchownSync ( path , uid , gid )
32
50
} catch ( er ) {
33
51
if ( er . code !== 'EISDIR' )
34
52
throw er
35
- fs . chownSync ( path , uid , gid )
53
+ chownSync ( path , uid , gid )
36
54
}
37
55
}
38
- : ( path , uid , gid ) => fs [ LCHOWNSYNC ] ( path , uid , gid )
56
+ : ( path , uid , gid ) => lchownSync ( path , uid , gid )
39
57
40
58
// fs.readdir could only accept an options object as of node v6
41
59
const nodeVersion = process . version
@@ -45,9 +63,19 @@ let readdirSync = (path, options) => fs.readdirSync(path, options)
45
63
if ( / ^ v 4 \. / . test ( nodeVersion ) )
46
64
readdir = ( path , options , cb ) => fs . readdir ( path , cb )
47
65
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
+
48
74
const chownrKid = ( p , child , uid , gid , cb ) => {
49
75
if ( typeof child === 'string' )
50
76
return fs . lstat ( path . resolve ( p , child ) , ( er , stats ) => {
77
+ // Skip ENOENT error
78
+ if ( er && er . code === 'ENOENT' ) return cb ( )
51
79
if ( er )
52
80
return cb ( er )
53
81
stats . name = child
@@ -59,11 +87,11 @@ const chownrKid = (p, child, uid, gid, cb) => {
59
87
if ( er )
60
88
return cb ( er )
61
89
const cpath = path . resolve ( p , child . name )
62
- fs [ LCHOWN ] ( cpath , uid , gid , handleEISDIR ( cpath , uid , gid , cb ) )
90
+ chown ( cpath , uid , gid , cb )
63
91
} )
64
92
} else {
65
93
const cpath = path . resolve ( p , child . name )
66
- fs [ LCHOWN ] ( cpath , uid , gid , handleEISDIR ( cpath , uid , gid , cb ) )
94
+ chown ( cpath , uid , gid , cb )
67
95
}
68
96
}
69
97
@@ -74,8 +102,10 @@ const chownr = (p, uid, gid, cb) => {
74
102
// or doesn't exist. give up.
75
103
if ( er && er . code !== 'ENOTDIR' && er . code !== 'ENOTSUP' )
76
104
return cb ( er )
105
+ if ( er && er . code === 'ENOENT' )
106
+ return cb ( )
77
107
if ( er || ! children . length )
78
- return fs [ LCHOWN ] ( p , uid , gid , handleEISDIR ( p , uid , gid , cb ) )
108
+ return chown ( p , uid , gid , cb )
79
109
80
110
let len = children . length
81
111
let errState = null
@@ -85,7 +115,7 @@ const chownr = (p, uid, gid, cb) => {
85
115
if ( er )
86
116
return cb ( errState = er )
87
117
if ( -- len === 0 )
88
- return fs [ LCHOWN ] ( p , uid , gid , handleEISDIR ( p , uid , gid , cb ) )
118
+ return chown ( p , uid , gid , cb )
89
119
}
90
120
91
121
children . forEach ( child => chownrKid ( p , child , uid , gid , then ) )
@@ -94,9 +124,14 @@ const chownr = (p, uid, gid, cb) => {
94
124
95
125
const chownrKidSync = ( p , child , uid , gid ) => {
96
126
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
+ }
100
135
}
101
136
102
137
if ( child . isDirectory ( ) )
@@ -112,6 +147,7 @@ const chownrSync = (p, uid, gid) => {
112
147
} catch ( er ) {
113
148
if ( er && er . code === 'ENOTDIR' && er . code !== 'ENOTSUP' )
114
149
return handleEISDirSync ( p , uid , gid )
150
+ if ( er && er . code === 'ENOENT' ) return
115
151
throw er
116
152
}
117
153
0 commit comments