Example #1
0
// 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
}
Example #2
0
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
}
Example #3
0
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
	}
}