...

Source file src/archive/tar/stat_unix.go

Documentation: archive/tar

		 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.
		 4  
		 5  //go:build aix || linux || darwin || dragonfly || freebsd || openbsd || netbsd || solaris
		 6  // +build aix linux darwin dragonfly freebsd openbsd netbsd solaris
		 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  // userMap and groupMap caches UID and GID lookups for performance reasons.
		24  // The downside is that renaming uname or gname by the OS never takes effect.
		25  var userMap, groupMap sync.Map // map[int]string
		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  	// Best effort at populating Uname and Gname.
		36  	// The os/user functions may fail for any number of reasons
		37  	// (not implemented on that platform, cgo not enabled, etc).
		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  	// Best effort at populating Devmajor and Devminor.
		55  	if h.Typeflag == TypeChar || h.Typeflag == TypeBlock {
		56  		dev := uint64(sys.Rdev) // May be int32 or uint32
		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  			// Copied from golang.org/x/sys/unix/dev_linux.go.
		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  			// Copied from golang.org/x/sys/unix/dev_darwin.go.
		72  			major := uint32((dev >> 24) & 0xff)
		73  			minor := uint32(dev & 0xffffff)
		74  			h.Devmajor, h.Devminor = int64(major), int64(minor)
		75  		case "dragonfly":
		76  			// Copied from golang.org/x/sys/unix/dev_dragonfly.go.
		77  			major := uint32((dev >> 8) & 0xff)
		78  			minor := uint32(dev & 0xffff00ff)
		79  			h.Devmajor, h.Devminor = int64(major), int64(minor)
		80  		case "freebsd":
		81  			// Copied from golang.org/x/sys/unix/dev_freebsd.go.
		82  			major := uint32((dev >> 8) & 0xff)
		83  			minor := uint32(dev & 0xffff00ff)
		84  			h.Devmajor, h.Devminor = int64(major), int64(minor)
		85  		case "netbsd":
		86  			// Copied from golang.org/x/sys/unix/dev_netbsd.go.
		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  			// Copied from golang.org/x/sys/unix/dev_openbsd.go.
		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  			// TODO: Implement solaris (see https://golang.org/issue/8106)
		99  		}
	 100  	}
	 101  	return nil
	 102  }
	 103  

View as plain text