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