archive_unix.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // +build !windows
  2. package archive
  3. import (
  4. "archive/tar"
  5. "errors"
  6. "os"
  7. "syscall"
  8. "github.com/docker/docker/pkg/system"
  9. )
  10. // canonicalTarNameForPath returns platform-specific filepath
  11. // to canonical posix-style path for tar archival. p is relative
  12. // path.
  13. func CanonicalTarNameForPath(p string) (string, error) {
  14. return p, nil // already unix-style
  15. }
  16. // chmodTarEntry is used to adjust the file permissions used in tar header based
  17. // on the platform the archival is done.
  18. func chmodTarEntry(perm os.FileMode) os.FileMode {
  19. return perm // noop for unix as golang APIs provide perm bits correctly
  20. }
  21. func setHeaderForSpecialDevice(hdr *tar.Header, ta *tarAppender, name string, stat interface{}) (nlink uint32, inode uint64, err error) {
  22. s, ok := stat.(*syscall.Stat_t)
  23. if !ok {
  24. err = errors.New("cannot convert stat value to syscall.Stat_t")
  25. return
  26. }
  27. nlink = uint32(s.Nlink)
  28. inode = uint64(s.Ino)
  29. // Currently go does not fil in the major/minors
  30. if s.Mode&syscall.S_IFBLK != 0 ||
  31. s.Mode&syscall.S_IFCHR != 0 {
  32. hdr.Devmajor = int64(major(uint64(s.Rdev)))
  33. hdr.Devminor = int64(minor(uint64(s.Rdev)))
  34. }
  35. return
  36. }
  37. func major(device uint64) uint64 {
  38. return (device >> 8) & 0xfff
  39. }
  40. func minor(device uint64) uint64 {
  41. return (device & 0xff) | ((device >> 12) & 0xfff00)
  42. }
  43. // handleTarTypeBlockCharFifo is an OS-specific helper function used by
  44. // createTarFile to handle the following types of header: Block; Char; Fifo
  45. func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
  46. mode := uint32(hdr.Mode & 07777)
  47. switch hdr.Typeflag {
  48. case tar.TypeBlock:
  49. mode |= syscall.S_IFBLK
  50. case tar.TypeChar:
  51. mode |= syscall.S_IFCHR
  52. case tar.TypeFifo:
  53. mode |= syscall.S_IFIFO
  54. }
  55. if err := system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor))); err != nil {
  56. return err
  57. }
  58. return nil
  59. }
  60. func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
  61. if hdr.Typeflag == tar.TypeLink {
  62. if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
  63. if err := os.Chmod(path, hdrInfo.Mode()); err != nil {
  64. return err
  65. }
  66. }
  67. } else if hdr.Typeflag != tar.TypeSymlink {
  68. if err := os.Chmod(path, hdrInfo.Mode()); err != nil {
  69. return err
  70. }
  71. }
  72. return nil
  73. }