stat_unix.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. // +build linux darwin dragonfly freebsd openbsd netbsd solaris
  5. package tar
  6. import (
  7. "os"
  8. "runtime"
  9. "syscall"
  10. )
  11. func init() {
  12. sysStat = statUnix
  13. }
  14. func statUnix(fi os.FileInfo, h *Header) error {
  15. sys, ok := fi.Sys().(*syscall.Stat_t)
  16. if !ok {
  17. return nil
  18. }
  19. h.Uid = int(sys.Uid)
  20. h.Gid = int(sys.Gid)
  21. // TODO(bradfitz): populate username & group. os/user
  22. // doesn't cache LookupId lookups, and lacks group
  23. // lookup functions.
  24. h.AccessTime = statAtime(sys)
  25. h.ChangeTime = statCtime(sys)
  26. // Best effort at populating Devmajor and Devminor.
  27. if h.Typeflag == TypeChar || h.Typeflag == TypeBlock {
  28. dev := uint64(sys.Rdev) // May be int32 or uint32
  29. switch runtime.GOOS {
  30. case "linux":
  31. // Copied from golang.org/x/sys/unix/dev_linux.go.
  32. major := uint32((dev & 0x00000000000fff00) >> 8)
  33. major |= uint32((dev & 0xfffff00000000000) >> 32)
  34. minor := uint32((dev & 0x00000000000000ff) >> 0)
  35. minor |= uint32((dev & 0x00000ffffff00000) >> 12)
  36. h.Devmajor, h.Devminor = int64(major), int64(minor)
  37. case "darwin":
  38. // Copied from golang.org/x/sys/unix/dev_darwin.go.
  39. major := uint32((dev >> 24) & 0xff)
  40. minor := uint32(dev & 0xffffff)
  41. h.Devmajor, h.Devminor = int64(major), int64(minor)
  42. case "dragonfly":
  43. // Copied from golang.org/x/sys/unix/dev_dragonfly.go.
  44. major := uint32((dev >> 8) & 0xff)
  45. minor := uint32(dev & 0xffff00ff)
  46. h.Devmajor, h.Devminor = int64(major), int64(minor)
  47. case "freebsd":
  48. // Copied from golang.org/x/sys/unix/dev_freebsd.go.
  49. major := uint32((dev >> 8) & 0xff)
  50. minor := uint32(dev & 0xffff00ff)
  51. h.Devmajor, h.Devminor = int64(major), int64(minor)
  52. case "netbsd":
  53. // Copied from golang.org/x/sys/unix/dev_netbsd.go.
  54. major := uint32((dev & 0x000fff00) >> 8)
  55. minor := uint32((dev & 0x000000ff) >> 0)
  56. minor |= uint32((dev & 0xfff00000) >> 12)
  57. h.Devmajor, h.Devminor = int64(major), int64(minor)
  58. case "openbsd":
  59. // Copied from golang.org/x/sys/unix/dev_openbsd.go.
  60. major := uint32((dev & 0x0000ff00) >> 8)
  61. minor := uint32((dev & 0x000000ff) >> 0)
  62. minor |= uint32((dev & 0xffff0000) >> 8)
  63. h.Devmajor, h.Devminor = int64(major), int64(minor)
  64. default:
  65. // TODO: Implement solaris (see https://golang.org/issue/8106)
  66. }
  67. }
  68. return nil
  69. }