mirror of
https://github.com/golang/go
synced 2024-11-22 01:44:40 -07:00
misc/dist: better archive/tar Headers
This should live in archive/tar later (CL 5796073) but we can always do that after Go 1 and stick it here for now. R=golang-dev, adg CC=golang-dev https://golang.org/cl/5754096
This commit is contained in:
parent
daacba5184
commit
c405b58f3f
86
misc/dist/bindist.go
vendored
86
misc/dist/bindist.go
vendored
@ -26,7 +26,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -527,22 +526,16 @@ func makeTar(targ, workdir string) error {
|
|||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var typeFlag byte
|
hdr, err := tarFileInfoHeader(fi, path)
|
||||||
switch {
|
if err != nil {
|
||||||
case fi.Mode()&os.ModeType == 0:
|
return err
|
||||||
typeFlag = tar.TypeReg
|
|
||||||
default:
|
|
||||||
log.Fatalf("makeTar: unknown file for file %q", name)
|
|
||||||
}
|
|
||||||
hdr := &tar.Header{
|
|
||||||
Name: name,
|
|
||||||
Mode: int64(fi.Sys().(*syscall.Stat_t).Mode),
|
|
||||||
Size: fi.Size(),
|
|
||||||
ModTime: fi.ModTime(),
|
|
||||||
Typeflag: typeFlag,
|
|
||||||
Uname: "root",
|
|
||||||
Gname: "root",
|
|
||||||
}
|
}
|
||||||
|
hdr.Name = name
|
||||||
|
hdr.Uname = "root"
|
||||||
|
hdr.Gname = "root"
|
||||||
|
hdr.Uid = 0
|
||||||
|
hdr.Gid = 0
|
||||||
|
|
||||||
err = tw.WriteHeader(hdr)
|
err = tw.WriteHeader(hdr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error writing file %q: %v", name, err)
|
return fmt.Errorf("Error writing file %q: %v", name, err)
|
||||||
@ -686,3 +679,64 @@ func lookPath(prog string) (absPath string, err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sysStat, if non-nil, populates h from system-dependent fields of fi.
|
||||||
|
var sysStat func(fi os.FileInfo, h *tar.Header) error
|
||||||
|
|
||||||
|
// Mode constants from the tar spec.
|
||||||
|
const (
|
||||||
|
c_ISDIR = 040000
|
||||||
|
c_ISFIFO = 010000
|
||||||
|
c_ISREG = 0100000
|
||||||
|
c_ISLNK = 0120000
|
||||||
|
c_ISBLK = 060000
|
||||||
|
c_ISCHR = 020000
|
||||||
|
c_ISSOCK = 0140000
|
||||||
|
)
|
||||||
|
|
||||||
|
// tarFileInfoHeader creates a partially-populated Header from an os.FileInfo.
|
||||||
|
// The filename parameter is used only in the case of symlinks, to call os.Readlink.
|
||||||
|
// If fi is a symlink but filename is empty, an error is returned.
|
||||||
|
func tarFileInfoHeader(fi os.FileInfo, filename string) (*tar.Header, error) {
|
||||||
|
h := &tar.Header{
|
||||||
|
Name: fi.Name(),
|
||||||
|
ModTime: fi.ModTime(),
|
||||||
|
Mode: int64(fi.Mode().Perm()), // or'd with c_IS* constants later
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case fi.Mode()&os.ModeType == 0:
|
||||||
|
h.Mode |= c_ISREG
|
||||||
|
h.Typeflag = tar.TypeReg
|
||||||
|
h.Size = fi.Size()
|
||||||
|
case fi.IsDir():
|
||||||
|
h.Typeflag = tar.TypeDir
|
||||||
|
h.Mode |= c_ISDIR
|
||||||
|
case fi.Mode()&os.ModeSymlink != 0:
|
||||||
|
h.Typeflag = tar.TypeSymlink
|
||||||
|
h.Mode |= c_ISLNK
|
||||||
|
if filename == "" {
|
||||||
|
return h, fmt.Errorf("archive/tar: unable to populate Header.Linkname of symlinks")
|
||||||
|
}
|
||||||
|
targ, err := os.Readlink(filename)
|
||||||
|
if err != nil {
|
||||||
|
return h, err
|
||||||
|
}
|
||||||
|
h.Linkname = targ
|
||||||
|
case fi.Mode()&os.ModeDevice != 0:
|
||||||
|
if fi.Mode()&os.ModeCharDevice != 0 {
|
||||||
|
h.Mode |= c_ISCHR
|
||||||
|
h.Typeflag = tar.TypeChar
|
||||||
|
} else {
|
||||||
|
h.Mode |= c_ISBLK
|
||||||
|
h.Typeflag = tar.TypeBlock
|
||||||
|
}
|
||||||
|
case fi.Mode()&os.ModeSocket != 0:
|
||||||
|
h.Mode |= c_ISSOCK
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("archive/tar: unknown file mode %v", fi.Mode())
|
||||||
|
}
|
||||||
|
if sysStat != nil {
|
||||||
|
return h, sysStat(fi, h)
|
||||||
|
}
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
32
misc/dist/stat_darwin.go
vendored
Normal file
32
misc/dist/stat_darwin.go
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sysStat = func(fi os.FileInfo, h *tar.Header) error {
|
||||||
|
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 = time.Unix(sys.Atimespec.Unix())
|
||||||
|
h.ChangeTime = time.Unix(sys.Ctimespec.Unix())
|
||||||
|
// TODO(bradfitz): major/minor device numbers?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
32
misc/dist/stat_linux.go
vendored
Normal file
32
misc/dist/stat_linux.go
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sysStat = func(fi os.FileInfo, h *tar.Header) error {
|
||||||
|
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 = time.Unix(sys.Atim.Unix())
|
||||||
|
h.ChangeTime = time.Unix(sys.Ctim.Unix())
|
||||||
|
// TODO(bradfitz): major/minor device numbers?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user