diff --git a/archive/tar/common.go b/archive/tar/common.go index 855e5fc..c31df06 100644 --- a/archive/tar/common.go +++ b/archive/tar/common.go @@ -249,6 +249,30 @@ func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { if fm&os.ModeSticky != 0 { h.Mode |= c_ISVTX } + // If possible, populate additional fields from OS-specific + // FileInfo fields. + if sys, ok := fi.Sys().(*Header); ok { + // This FileInfo came from a Header (not the OS). Use the + // original Header to populate all remaining fields. + h.Uid = sys.Uid + h.Gid = sys.Gid + h.Uname = sys.Uname + h.Gname = sys.Gname + h.AccessTime = sys.AccessTime + h.ChangeTime = sys.ChangeTime + if sys.Xattrs != nil { + h.Xattrs = make(map[string]string) + for k, v := range sys.Xattrs { + h.Xattrs[k] = v + } + } + if sys.Typeflag == TypeLink { + // hard link + h.Typeflag = TypeLink + h.Size = 0 + h.Linkname = sys.Linkname + } + } if sysStat != nil { return h, sysStat(fi, h) } diff --git a/archive/tar/stat_unix.go b/archive/tar/stat_unix.go index 24b9311..27d112f 100644 --- a/archive/tar/stat_unix.go +++ b/archive/tar/stat_unix.go @@ -16,41 +16,22 @@ func init() { } func statUnix(fi os.FileInfo, h *Header) error { - switch sys := fi.Sys().(type) { - case *syscall.Stat_t: - h.Uid = int(sys.Uid) - h.Gid = int(sys.Gid) - // TODO(bradfitz): populate username & group. os/user - // doesn't cache LookupId lookups, and lacks group - // lookup functions. - h.AccessTime = statAtime(sys) - h.ChangeTime = statCtime(sys) - // TODO(bradfitz): major/minor device numbers? - if fi.Mode().IsRegular() && sys.Nlink > 1 { - h.Typeflag = TypeLink - h.Size = 0 - // TODO(vbatts): Linkname? - } - case *Header: - // for the roundtrip logic - h.Uid = sys.Uid - h.Gid = sys.Gid - h.Uname = sys.Uname - h.Gname = sys.Gname - h.AccessTime = sys.AccessTime - h.ChangeTime = sys.ChangeTime - if sys.Xattrs != nil { - h.Xattrs = make(map[string]string) - for k, v := range sys.Xattrs { - h.Xattrs[k] = v - } - } - if sys.Typeflag == TypeLink { - // hard link - h.Typeflag = TypeLink - h.Size = 0 - h.Linkname = sys.Linkname - } + sys, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return nil + } + h.Uid = int(sys.Uid) + h.Gid = int(sys.Gid) + // TODO(bradfitz): populate username & group. os/user + // doesn't cache LookupId lookups, and lacks group + // lookup functions. + h.AccessTime = statAtime(sys) + h.ChangeTime = statCtime(sys) + // TODO(bradfitz): major/minor device numbers? + if fi.Mode().IsRegular() && sys.Nlink > 1 { + h.Typeflag = TypeLink + h.Size = 0 + // TODO(vbatts): Linkname? } return nil } diff --git a/archive/tar/tar_test.go b/archive/tar/tar_test.go index 3fdd83d..d63c072 100644 --- a/archive/tar/tar_test.go +++ b/archive/tar/tar_test.go @@ -10,7 +10,6 @@ import ( "os" "path" "reflect" - "runtime" "strings" "testing" "time" @@ -136,9 +135,6 @@ type headerRoundTripTest struct { } func TestHeaderRoundTrip(t *testing.T) { - if runtime.GOOS == "windows" || runtime.GOOS == "plan9" || runtime.GOOS == "nacl" { - t.Skipf("skipping on %s; issue 11426", runtime.GOOS) - } golden := []headerRoundTripTest{ // regular file. {