Source file
src/archive/tar/stat_unix.go
1
2
3
4
5
6
7 package tar
8
9 import (
10 "io/fs"
11 "os/user"
12 "runtime"
13 "strconv"
14 "sync"
15 "syscall"
16 )
17
18 func init() {
19 sysStat = statUnix
20 }
21
22
23
24 var userMap, groupMap sync.Map
25
26 func statUnix(fi fs.FileInfo, h *Header, doNameLookups bool) error {
27 sys, ok := fi.Sys().(*syscall.Stat_t)
28 if !ok {
29 return nil
30 }
31 h.Uid = int(sys.Uid)
32 h.Gid = int(sys.Gid)
33 if doNameLookups {
34
35
36
37 if u, ok := userMap.Load(h.Uid); ok {
38 h.Uname = u.(string)
39 } else if u, err := user.LookupId(strconv.Itoa(h.Uid)); err == nil {
40 h.Uname = u.Username
41 userMap.Store(h.Uid, h.Uname)
42 }
43 if g, ok := groupMap.Load(h.Gid); ok {
44 h.Gname = g.(string)
45 } else if g, err := user.LookupGroupId(strconv.Itoa(h.Gid)); err == nil {
46 h.Gname = g.Name
47 groupMap.Store(h.Gid, h.Gname)
48 }
49 }
50 h.AccessTime = statAtime(sys)
51 h.ChangeTime = statCtime(sys)
52
53
54 if h.Typeflag == TypeChar || h.Typeflag == TypeBlock {
55 dev := uint64(sys.Rdev)
56 switch runtime.GOOS {
57 case "aix":
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)
62 case "linux":
63
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)
69 case "darwin", "ios":
70
71 major := uint32((dev >> 24) & 0xff)
72 minor := uint32(dev & 0xffffff)
73 h.Devmajor, h.Devminor = int64(major), int64(minor)
74 case "dragonfly":
75
76 major := uint32((dev >> 8) & 0xff)
77 minor := uint32(dev & 0xffff00ff)
78 h.Devmajor, h.Devminor = int64(major), int64(minor)
79 case "freebsd":
80
81 major := uint32((dev >> 8) & 0xff)
82 minor := uint32(dev & 0xffff00ff)
83 h.Devmajor, h.Devminor = int64(major), int64(minor)
84 case "netbsd":
85
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)
90 case "openbsd":
91
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)
96 default:
97
98 }
99 }
100 return nil
101 }
102
View as plain text