src/archive/tar/stat_unix.go GO 102 lines View on github.com → Search inside
1// Copyright 2012 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45//go:build unix67package tar89import (10	"io/fs"11	"os/user"12	"runtime"13	"strconv"14	"sync"15	"syscall"16)1718func init() {19	sysStat = statUnix20}2122// userMap and groupMap cache UID and GID lookups for performance reasons.23// The downside is that renaming uname or gname by the OS never takes effect.24var userMap, groupMap sync.Map // map[int]string2526func statUnix(fi fs.FileInfo, h *Header, doNameLookups bool) error {27	sys, ok := fi.Sys().(*syscall.Stat_t)28	if !ok {29		return nil30	}31	h.Uid = int(sys.Uid)32	h.Gid = int(sys.Gid)33	if doNameLookups {34		// Best effort at populating Uname and Gname.35		// The os/user functions may fail for any number of reasons36		// (not implemented on that platform, cgo not enabled, etc).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.Username41			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.Name47			groupMap.Store(h.Gid, h.Gname)48		}49	}50	h.AccessTime = statAtime(sys)51	h.ChangeTime = statCtime(sys)5253	// Best effort at populating Devmajor and Devminor.54	if h.Typeflag == TypeChar || h.Typeflag == TypeBlock {55		dev := uint64(sys.Rdev) // May be int32 or uint3256		switch runtime.GOOS {57		case "aix":58			var major, minor uint3259			major = uint32((dev & 0x3fffffff00000000) >> 32)60			minor = uint32((dev & 0x00000000ffffffff) >> 0)61			h.Devmajor, h.Devminor = int64(major), int64(minor)62		case "linux":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)69		case "darwin", "ios":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)74		case "dragonfly":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)79		case "freebsd":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)84		case "netbsd":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)90		case "openbsd":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)96		default:97			// TODO: Implement solaris (see https://golang.org/issue/8106)98		}99	}100	return nil101}

Code quality findings 1

Hidden side effects; favor explicit initialization in main() or functions
info correctness func-init
func init() {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.