1// +build !windows
2
3package fsutil
4
5import (
6	"os"
7	"syscall"
8
9	"github.com/containerd/continuity/sysx"
10	"github.com/pkg/errors"
11)
12
13func loadXattr(origpath string, stat *Stat) error {
14	xattrs, err := sysx.LListxattr(origpath)
15	if err != nil {
16		return errors.Wrapf(err, "failed to xattr %s", origpath)
17	}
18	if len(xattrs) > 0 {
19		m := make(map[string][]byte)
20		for _, key := range xattrs {
21			v, err := sysx.LGetxattr(origpath, key)
22			if err == nil {
23				m[key] = v
24			}
25		}
26		stat.Xattrs = m
27	}
28	return nil
29}
30
31func setUnixOpt(fi os.FileInfo, stat *Stat, path string, seenFiles map[uint64]string) {
32	s := fi.Sys().(*syscall.Stat_t)
33
34	stat.Uid = s.Uid
35	stat.Gid = s.Gid
36
37	if !fi.IsDir() {
38		if s.Mode&syscall.S_IFBLK != 0 ||
39			s.Mode&syscall.S_IFCHR != 0 {
40			stat.Devmajor = int64(major(uint64(s.Rdev)))
41			stat.Devminor = int64(minor(uint64(s.Rdev)))
42		}
43
44		ino := s.Ino
45		if s.Nlink > 1 {
46			if oldpath, ok := seenFiles[ino]; ok {
47				stat.Linkname = oldpath
48				stat.Size_ = 0
49			}
50		}
51		seenFiles[ino] = path
52	}
53}
54
55func major(device uint64) uint64 {
56	return (device >> 8) & 0xfff
57}
58
59func minor(device uint64) uint64 {
60	return (device & 0xff) | ((device >> 12) & 0xfff00)
61}
62