9
9
"io/ioutil"
10
10
"os"
11
11
"path/filepath"
12
+ "runtime"
12
13
"strings"
13
14
"unicode"
14
15
@@ -270,9 +271,17 @@ func CopyDir(src, dst string) error {
270
271
// the copied data is synced/flushed to stable storage.
271
272
func copyFile (src , dst string ) (err error ) {
272
273
if sym , err := IsSymlink (src ); err != nil {
273
- return err
274
+ return errors . Wrap ( err , "symlink check failed" )
274
275
} else if sym {
275
- return cloneSymlink (src , dst )
276
+ if err := cloneSymlink (src , dst ); err != nil {
277
+ if runtime .GOOS == "windows" && strings .HasSuffix (err .Error (), "A required privilege is not held by the client." ) {
278
+ // If cloning the symlink fails on Windows because the user
279
+ // does not have the required privileges, ignore the error and
280
+ // fall back to copying the file contents instead of cloning.
281
+ } else {
282
+ return err
283
+ }
284
+ }
276
285
}
277
286
278
287
in , err := os .Open (src )
@@ -285,28 +294,22 @@ func copyFile(src, dst string) (err error) {
285
294
if err != nil {
286
295
return
287
296
}
288
- defer func () {
289
- if e := out .Close (); e != nil {
290
- err = e
291
- }
292
- }()
297
+ defer out .Close ()
293
298
294
- _ , err = io .Copy (out , in )
295
- if err != nil {
299
+ if _ , err = io .Copy (out , in ); err != nil {
296
300
return
297
301
}
298
302
299
- err = out .Sync ()
300
- if err != nil {
303
+ if err = out .Sync (); err != nil {
301
304
return
302
305
}
303
306
304
307
si , err := os .Stat (src )
305
308
if err != nil {
306
309
return
307
310
}
308
- err = os . Chmod ( dst , si . Mode ())
309
- if err != nil {
311
+
312
+ if err = os . Chmod ( dst , si . Mode ()); err != nil {
310
313
return
311
314
}
312
315
@@ -318,15 +321,10 @@ func copyFile(src, dst string) (err error) {
318
321
func cloneSymlink (sl , dst string ) error {
319
322
resolved , err := os .Readlink (sl )
320
323
if err != nil {
321
- return errors .Wrap (err , "failed to resolve symlink" )
322
- }
323
-
324
- err = os .Symlink (resolved , dst )
325
- if err != nil {
326
- return errors .Wrapf (err , "failed to create symlink %s to %s" , dst , resolved )
324
+ return err
327
325
}
328
326
329
- return nil
327
+ return os . Symlink ( resolved , dst )
330
328
}
331
329
332
330
// IsDir determines is the path given is a directory or not.
0 commit comments