...
1
2
3
4
19
20 package fs
21
22 import (
23 "fmt"
24 "os"
25 "runtime"
26 "syscall"
27
28 "github.com/containerd/continuity/sysx"
29 )
30
31 func copyFileInfo(fi os.FileInfo, src, name string) error {
32 st := fi.Sys().(*syscall.Stat_t)
33 if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
34 if os.IsPermission(err) {
35
36
37
38 if dstStat, err2 := os.Lstat(name); err2 == nil {
39 st2 := dstStat.Sys().(*syscall.Stat_t)
40 if st.Uid == st2.Uid && st.Gid == st2.Gid {
41 err = nil
42 }
43 }
44 }
45 if err != nil {
46 return fmt.Errorf("failed to chown %s: %w", name, err)
47 }
48 }
49
50 if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
51 if err := os.Chmod(name, fi.Mode()); err != nil {
52 return fmt.Errorf("failed to chmod %s: %w", name, err)
53 }
54 }
55
56 if err := utimesNano(name, StatAtime(st), StatMtime(st)); err != nil {
57 return fmt.Errorf("failed to utime %s: %w", name, err)
58 }
59
60 return nil
61 }
62
63 func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
64 xattrKeys, err := sysx.LListxattr(src)
65 if err != nil {
66 if os.IsPermission(err) && runtime.GOOS == "darwin" {
67
68 return nil
69 }
70 e := fmt.Errorf("failed to list xattrs on %s: %w", src, err)
71 if errorHandler != nil {
72 e = errorHandler(dst, src, "", e)
73 }
74 return e
75 }
76 for _, xattr := range xattrKeys {
77 if _, exclude := excludes[xattr]; exclude {
78 continue
79 }
80 data, err := sysx.LGetxattr(src, xattr)
81 if err != nil {
82 e := fmt.Errorf("failed to get xattr %q on %s: %w", xattr, src, err)
83 if errorHandler != nil {
84 if e = errorHandler(dst, src, xattr, e); e == nil {
85 continue
86 }
87 }
88 return e
89 }
90 if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
91 e := fmt.Errorf("failed to set xattr %q on %s: %w", xattr, dst, err)
92 if errorHandler != nil {
93 if e = errorHandler(dst, src, xattr, e); e == nil {
94 continue
95 }
96 }
97 return e
98 }
99 }
100
101 return nil
102 }
103
View as plain text