mirror of
https://github.com/golang/go
synced 2024-10-02 14:38:33 -06:00
archive/tar: add support for atime and ctime to Writer
Both the GNU and PAX formats support atime and ctime fields. The implementation is trivial now that we have: * support for formatting PAX records for timestamps * dedicated methods that only handle one format (e.g., GNU) Fixes #17876 Change-Id: I0c604fce14a47d722098afc966399cca2037395d Reviewed-on: https://go-review.googlesource.com/55570 Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
1da0e7e28e
commit
9223adcc2c
@ -133,8 +133,9 @@ func (h *Header) allowedFormats() (format int, paxHdrs map[string]string) {
|
|||||||
const supportGNULong = false
|
const supportGNULong = false
|
||||||
|
|
||||||
var blk block
|
var blk block
|
||||||
var v7 = blk.V7()
|
v7 := blk.V7()
|
||||||
var ustar = blk.USTAR()
|
ustar := blk.USTAR()
|
||||||
|
gnu := blk.GNU()
|
||||||
verifyString(h.Name, len(v7.Name()), supportGNULong, paxPath)
|
verifyString(h.Name, len(v7.Name()), supportGNULong, paxPath)
|
||||||
verifyString(h.Linkname, len(v7.LinkName()), supportGNULong, paxLinkpath)
|
verifyString(h.Linkname, len(v7.LinkName()), supportGNULong, paxLinkpath)
|
||||||
verifyString(h.Uname, len(ustar.UserName()), false, paxUname)
|
verifyString(h.Uname, len(ustar.UserName()), false, paxUname)
|
||||||
@ -146,9 +147,8 @@ func (h *Header) allowedFormats() (format int, paxHdrs map[string]string) {
|
|||||||
verifyNumeric(h.Devmajor, len(ustar.DevMajor()), paxNone)
|
verifyNumeric(h.Devmajor, len(ustar.DevMajor()), paxNone)
|
||||||
verifyNumeric(h.Devminor, len(ustar.DevMinor()), paxNone)
|
verifyNumeric(h.Devminor, len(ustar.DevMinor()), paxNone)
|
||||||
verifyTime(h.ModTime, len(v7.ModTime()), true, paxMtime)
|
verifyTime(h.ModTime, len(v7.ModTime()), true, paxMtime)
|
||||||
// TODO(dsnet): Support atime and ctime fields.
|
verifyTime(h.AccessTime, len(gnu.AccessTime()), false, paxAtime)
|
||||||
// verifyTime(h.AccessTime, len(gnu.AccessTime()), false, paxAtime)
|
verifyTime(h.ChangeTime, len(gnu.ChangeTime()), false, paxCtime)
|
||||||
// verifyTime(h.ChangeTime, len(gnu.ChangeTime()), false, paxCtime)
|
|
||||||
|
|
||||||
if !isHeaderOnlyType(h.Typeflag) && h.Size < 0 {
|
if !isHeaderOnlyType(h.Typeflag) && h.Size < 0 {
|
||||||
return formatUnknown, nil
|
return formatUnknown, nil
|
||||||
|
@ -450,6 +450,34 @@ func TestHeaderAllowedFormats(t *testing.T) {
|
|||||||
}, {
|
}, {
|
||||||
header: &Header{ModTime: time.Unix(077777777777, 0)},
|
header: &Header{ModTime: time.Unix(077777777777, 0)},
|
||||||
formats: formatUSTAR | formatPAX | formatGNU,
|
formats: formatUSTAR | formatPAX | formatGNU,
|
||||||
|
}, {
|
||||||
|
header: &Header{ModTime: time.Unix(077777777777+1, 0)},
|
||||||
|
paxHdrs: map[string]string{paxMtime: "8589934592"},
|
||||||
|
formats: formatPAX | formatGNU,
|
||||||
|
}, {
|
||||||
|
header: &Header{ModTime: time.Unix(math.MaxInt64, 0)},
|
||||||
|
paxHdrs: map[string]string{paxMtime: "9223372036854775807"},
|
||||||
|
formats: formatPAX | formatGNU,
|
||||||
|
}, {
|
||||||
|
header: &Header{ModTime: time.Unix(-1, 0)},
|
||||||
|
paxHdrs: map[string]string{paxMtime: "-1"},
|
||||||
|
formats: formatPAX | formatGNU,
|
||||||
|
}, {
|
||||||
|
header: &Header{ModTime: time.Unix(-1, 500)},
|
||||||
|
paxHdrs: map[string]string{paxMtime: "-0.9999995"},
|
||||||
|
formats: formatPAX,
|
||||||
|
}, {
|
||||||
|
header: &Header{AccessTime: time.Unix(0, 0)},
|
||||||
|
paxHdrs: map[string]string{paxAtime: "0"},
|
||||||
|
formats: formatPAX | formatGNU,
|
||||||
|
}, {
|
||||||
|
header: &Header{AccessTime: time.Unix(-123, 0)},
|
||||||
|
paxHdrs: map[string]string{paxAtime: "-123"},
|
||||||
|
formats: formatPAX | formatGNU,
|
||||||
|
}, {
|
||||||
|
header: &Header{ChangeTime: time.Unix(123, 456)},
|
||||||
|
paxHdrs: map[string]string{paxCtime: "123.000000456"},
|
||||||
|
formats: formatPAX,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for i, v := range vectors {
|
for i, v := range vectors {
|
||||||
|
@ -141,8 +141,12 @@ func (tw *Writer) writeGNUHeader(hdr *Header) error {
|
|||||||
// Pack the main header.
|
// Pack the main header.
|
||||||
var f formatter
|
var f formatter
|
||||||
blk := tw.templateV7Plus(hdr, f.formatString, f.formatNumeric)
|
blk := tw.templateV7Plus(hdr, f.formatString, f.formatNumeric)
|
||||||
// TODO(dsnet): Support atime and ctime fields.
|
if !hdr.AccessTime.IsZero() {
|
||||||
// See https://golang.org/issue/17876
|
f.formatNumeric(blk.GNU().AccessTime(), hdr.AccessTime.Unix())
|
||||||
|
}
|
||||||
|
if !hdr.ChangeTime.IsZero() {
|
||||||
|
f.formatNumeric(blk.GNU().ChangeTime(), hdr.ChangeTime.Unix())
|
||||||
|
}
|
||||||
blk.SetFormat(formatGNU)
|
blk.SetFormat(formatGNU)
|
||||||
if f.err != nil {
|
if f.err != nil {
|
||||||
return f.err // Should never happen since header is validated
|
return f.err // Should never happen since header is validated
|
||||||
|
Loading…
Reference in New Issue
Block a user