// https://github.com/docker/docker/blob/master/pkg/archive/archive_unix.go // Add a file's device major and minor numbers // to the file's header within a tar archive. // Return the file's inode and the number of hardlinks to that inode. func tarSetHeader(hdr *tar.Header, stat interface{}) (hasHardLinks bool, inode uint64, err error) { s, ok := stat.(*syscall.Stat_t) if !ok { err = fmt.Errorf("cannot convert stat value to syscall.Stat_t") return } hasHardLinks = (uint32(s.Nlink) > 1) inode = uint64(s.Ino) // Currently go does not fil in the major/minors if s.Mode&syscall.S_IFBLK != 0 || s.Mode&syscall.S_IFCHR != 0 { hdr.Devmajor = int64(devmajor(uint64(s.Rdev))) hdr.Devminor = int64(devminor(uint64(s.Rdev))) } return }
func setHeaderForSpecialDevice(hdr *tar.Header, ta *tarAppender, name string, stat interface{}) (inode uint64, err error) { s, ok := stat.(*syscall.Stat_t) if !ok { err = errors.New("cannot convert stat value to syscall.Stat_t") return } inode = uint64(s.Ino) // Currently go does not fill in the major/minors if s.Mode&syscall.S_IFBLK != 0 || s.Mode&syscall.S_IFCHR != 0 { hdr.Devmajor = int64(major(uint64(s.Rdev))) hdr.Devminor = int64(minor(uint64(s.Rdev))) } return }
func populateHeaderUnix(h *tar.Header, fi os.FileInfo, seen map[uint64]string) { st, ok := fi.Sys().(*syscall.Stat_t) if !ok { return } h.Uid = int(st.Uid) h.Gid = int(st.Gid) if st.Mode&syscall.S_IFMT == syscall.S_IFBLK || st.Mode&syscall.S_IFMT == syscall.S_IFCHR { h.Devminor = int64(C.my_minor(C.dev_t(st.Rdev))) h.Devmajor = int64(C.my_major(C.dev_t(st.Rdev))) } // If we have already seen this inode, generate a hardlink p, ok := seen[uint64(st.Ino)] if ok { h.Linkname = p h.Typeflag = tar.TypeLink } else { seen[uint64(st.Ino)] = h.Name } }