1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
22 // userMap and groupMap caches UID and GID lookups for performance reasons.
23 // The downside is that renaming uname or gname by the OS never takes effect.
24 var userMap, groupMap sync.Map // map[int]string
26 func statUnix(fi fs.FileInfo, h *Header) error {
27 sys, ok := fi.Sys().(*syscall.Stat_t)
34 // Best effort at populating Uname and Gname.
35 // The os/user functions may fail for any number of reasons
36 // (not implemented on that platform, cgo not enabled, etc).
37 if u, ok := userMap.Load(h.Uid); ok {
39 } else if u, err := user.LookupId(strconv.Itoa(h.Uid)); err == nil {
41 userMap.Store(h.Uid, h.Uname)
43 if g, ok := groupMap.Load(h.Gid); ok {
45 } else if g, err := user.LookupGroupId(strconv.Itoa(h.Gid)); err == nil {
47 groupMap.Store(h.Gid, h.Gname)
50 h.AccessTime = statAtime(sys)
51 h.ChangeTime = statCtime(sys)
53 // Best effort at populating Devmajor and Devminor.
54 if h.Typeflag == TypeChar || h.Typeflag == TypeBlock {
55 dev := uint64(sys.Rdev) // May be int32 or uint32
58 var major, minor uint32
59 major = uint32((dev & 0x3fffffff00000000) >> 32)
60 minor = uint32((dev & 0x00000000ffffffff) >> 0)
61 h.Devmajor, h.Devminor = int64(major), int64(minor)
63 // Copied from golang.org/x/sys/unix/dev_linux.go.
64 major := uint32((dev & 0x00000000000fff00) >> 8)
65 major |= uint32((dev & 0xfffff00000000000) >> 32)
66 minor := uint32((dev & 0x00000000000000ff) >> 0)
67 minor |= uint32((dev & 0x00000ffffff00000) >> 12)
68 h.Devmajor, h.Devminor = int64(major), int64(minor)
70 // Copied from golang.org/x/sys/unix/dev_darwin.go.
71 major := uint32((dev >> 24) & 0xff)
72 minor := uint32(dev & 0xffffff)
73 h.Devmajor, h.Devminor = int64(major), int64(minor)
75 // Copied from golang.org/x/sys/unix/dev_dragonfly.go.
76 major := uint32((dev >> 8) & 0xff)
77 minor := uint32(dev & 0xffff00ff)
78 h.Devmajor, h.Devminor = int64(major), int64(minor)
80 // Copied from golang.org/x/sys/unix/dev_freebsd.go.
81 major := uint32((dev >> 8) & 0xff)
82 minor := uint32(dev & 0xffff00ff)
83 h.Devmajor, h.Devminor = int64(major), int64(minor)
85 // Copied from golang.org/x/sys/unix/dev_netbsd.go.
86 major := uint32((dev & 0x000fff00) >> 8)
87 minor := uint32((dev & 0x000000ff) >> 0)
88 minor |= uint32((dev & 0xfff00000) >> 12)
89 h.Devmajor, h.Devminor = int64(major), int64(minor)
91 // Copied from golang.org/x/sys/unix/dev_openbsd.go.
92 major := uint32((dev & 0x0000ff00) >> 8)
93 minor := uint32((dev & 0x000000ff) >> 0)
94 minor |= uint32((dev & 0xffff0000) >> 8)
95 h.Devmajor, h.Devminor = int64(major), int64(minor)
97 // TODO: Implement solaris (see https://golang.org/issue/8106)