@@ -46,13 +46,20 @@ func removeAll(path string) error {
46
46
}
47
47
defer parent .Close ()
48
48
49
- return removeAllFrom (parent , base )
49
+ if err := removeAllFrom (parent , base ); err != nil {
50
+ if pathErr , ok := err .(* PathError ); ok {
51
+ pathErr .Path = parentDir + string (PathSeparator ) + pathErr .Path
52
+ err = pathErr
53
+ }
54
+ return err
55
+ }
56
+ return nil
50
57
}
51
58
52
- func removeAllFrom (parent * File , path string ) error {
59
+ func removeAllFrom (parent * File , base string ) error {
53
60
parentFd := int (parent .Fd ())
54
61
// Simple case: if Unlink (aka remove) works, we're done.
55
- err := unix .Unlinkat (parentFd , path , 0 )
62
+ err := unix .Unlinkat (parentFd , base , 0 )
56
63
if err == nil || IsNotExist (err ) {
57
64
return nil
58
65
}
@@ -64,21 +71,21 @@ func removeAllFrom(parent *File, path string) error {
64
71
// whose contents need to be removed.
65
72
// Otherwise just return the error.
66
73
if err != syscall .EISDIR && err != syscall .EPERM && err != syscall .EACCES {
67
- return err
74
+ return & PathError { "unlinkat" , base , err }
68
75
}
69
76
70
77
// Is this a directory we need to recurse into?
71
78
var statInfo syscall.Stat_t
72
- statErr := unix .Fstatat (parentFd , path , & statInfo , unix .AT_SYMLINK_NOFOLLOW )
79
+ statErr := unix .Fstatat (parentFd , base , & statInfo , unix .AT_SYMLINK_NOFOLLOW )
73
80
if statErr != nil {
74
81
if IsNotExist (statErr ) {
75
82
return nil
76
83
}
77
- return statErr
84
+ return & PathError { "fstatat" , base , statErr }
78
85
}
79
86
if statInfo .Mode & syscall .S_IFMT != syscall .S_IFDIR {
80
- // Not a directory; return the error from the Remove .
81
- return err
87
+ // Not a directory; return the error from the unix.Unlinkat .
88
+ return & PathError { "unlinkat" , base , err }
82
89
}
83
90
84
91
// Remove the directory's entries.
@@ -87,12 +94,12 @@ func removeAllFrom(parent *File, path string) error {
87
94
const request = 1024
88
95
89
96
// Open the directory to recurse into
90
- file , err := openFdAt (parentFd , path )
97
+ file , err := openFdAt (parentFd , base )
91
98
if err != nil {
92
99
if IsNotExist (err ) {
93
100
return nil
94
101
}
95
- recurseErr = err
102
+ recurseErr = & PathError { "openfdat" , base , err }
96
103
break
97
104
}
98
105
@@ -103,12 +110,15 @@ func removeAllFrom(parent *File, path string) error {
103
110
if IsNotExist (readErr ) {
104
111
return nil
105
112
}
106
- return readErr
113
+ return & PathError { "readdirnames" , base , readErr }
107
114
}
108
115
109
116
for _ , name := range names {
110
117
err := removeAllFrom (file , name )
111
118
if err != nil {
119
+ if pathErr , ok := err .(* PathError ); ok {
120
+ pathErr .Path = base + string (PathSeparator ) + pathErr .Path
121
+ }
112
122
recurseErr = err
113
123
}
114
124
}
@@ -127,15 +137,15 @@ func removeAllFrom(parent *File, path string) error {
127
137
}
128
138
129
139
// Remove the directory itself.
130
- unlinkError := unix .Unlinkat (parentFd , path , unix .AT_REMOVEDIR )
140
+ unlinkError := unix .Unlinkat (parentFd , base , unix .AT_REMOVEDIR )
131
141
if unlinkError == nil || IsNotExist (unlinkError ) {
132
142
return nil
133
143
}
134
144
135
145
if recurseErr != nil {
136
146
return recurseErr
137
147
}
138
- return unlinkError
148
+ return & PathError { "unlinkat" , base , unlinkError }
139
149
}
140
150
141
151
// openFdAt opens path relative to the directory in fd.
@@ -157,7 +167,7 @@ func openFdAt(dirfd int, name string) (*File, error) {
157
167
continue
158
168
}
159
169
160
- return nil , & PathError { "openat" , name , e }
170
+ return nil , e
161
171
}
162
172
163
173
if ! supportsCloseOnExec {
0 commit comments