aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/archive
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/archive')
-rw-r--r--libgo/go/archive/zip/reader.go2
-rw-r--r--libgo/go/archive/zip/reader_test.go19
-rw-r--r--libgo/go/archive/zip/struct.go68
-rw-r--r--libgo/go/archive/zip/testdata/symlink.zipbin0 -> 173 bytes
-rw-r--r--libgo/go/archive/zip/writer.go4
-rw-r--r--libgo/go/archive/zip/writer_test.go6
-rw-r--r--libgo/go/archive/zip/zip_test.go3
7 files changed, 80 insertions, 22 deletions
diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go
index 4dd0f4f..c300986 100644
--- a/libgo/go/archive/zip/reader.go
+++ b/libgo/go/archive/zip/reader.go
@@ -117,7 +117,7 @@ func (rc *ReadCloser) Close() error {
}
// Open returns a ReadCloser that provides access to the File's contents.
-// It is safe to Open and Read from files concurrently.
+// Multiple files may be read concurrently.
func (f *File) Open() (rc io.ReadCloser, err error) {
bodyOffset, err := f.findBodyOffset()
if err != nil {
diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go
index 9407e35..935860e 100644
--- a/libgo/go/archive/zip/reader_test.go
+++ b/libgo/go/archive/zip/reader_test.go
@@ -69,8 +69,23 @@ var tests = []ZipTest{
},
},
},
- {Name: "readme.zip"},
- {Name: "readme.notzip", Error: ErrFormat},
+ {
+ Name: "symlink.zip",
+ File: []ZipTestFile{
+ {
+ Name: "symlink",
+ Content: []byte("../target"),
+ Mode: 0777 | os.ModeSymlink,
+ },
+ },
+ },
+ {
+ Name: "readme.zip",
+ },
+ {
+ Name: "readme.notzip",
+ Error: ErrFormat,
+ },
{
Name: "dd.zip",
File: []ZipTestFile{
diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go
index 67e9658..35dcec6 100644
--- a/libgo/go/archive/zip/struct.go
+++ b/libgo/go/archive/zip/struct.go
@@ -57,8 +57,8 @@ type FileHeader struct {
}
// FileInfo returns an os.FileInfo for the FileHeader.
-func (fh *FileHeader) FileInfo() os.FileInfo {
- return headerFileInfo{fh}
+func (h *FileHeader) FileInfo() os.FileInfo {
+ return headerFileInfo{h}
}
// headerFileInfo implements os.FileInfo.
@@ -71,6 +71,7 @@ func (fi headerFileInfo) Size() int64 { return int64(fi.fh.UncompressedSi
func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
func (fi headerFileInfo) ModTime() time.Time { return fi.fh.ModTime() }
func (fi headerFileInfo) Mode() os.FileMode { return fi.fh.Mode() }
+func (fi headerFileInfo) Sys() interface{} { return fi.fh }
// FileInfoHeader creates a partially-populated FileHeader from an
// os.FileInfo.
@@ -151,13 +152,20 @@ func (h *FileHeader) SetModTime(t time.Time) {
h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
}
-// traditional names for Unix constants
const (
- s_IFMT = 0xf000
- s_IFDIR = 0x4000
- s_IFREG = 0x8000
- s_ISUID = 0x800
- s_ISGID = 0x400
+ // Unix constants. The specification doesn't mention them,
+ // but these seem to be the values agreed on by tools.
+ s_IFMT = 0xf000
+ s_IFSOCK = 0xc000
+ s_IFLNK = 0xa000
+ s_IFREG = 0x8000
+ s_IFBLK = 0x6000
+ s_IFDIR = 0x4000
+ s_IFCHR = 0x2000
+ s_IFIFO = 0x1000
+ s_ISUID = 0x800
+ s_ISGID = 0x400
+ s_ISVTX = 0x200
msdosDir = 0x10
msdosReadOnly = 0x01
@@ -205,10 +213,23 @@ func msdosModeToFileMode(m uint32) (mode os.FileMode) {
func fileModeToUnixMode(mode os.FileMode) uint32 {
var m uint32
- if mode&os.ModeDir != 0 {
- m = s_IFDIR
- } else {
+ switch mode & os.ModeType {
+ default:
m = s_IFREG
+ case os.ModeDir:
+ m = s_IFDIR
+ case os.ModeSymlink:
+ m = s_IFLNK
+ case os.ModeNamedPipe:
+ m = s_IFIFO
+ case os.ModeSocket:
+ m = s_IFSOCK
+ case os.ModeDevice:
+ if mode&os.ModeCharDevice != 0 {
+ m = s_IFCHR
+ } else {
+ m = s_IFBLK
+ }
}
if mode&os.ModeSetuid != 0 {
m |= s_ISUID
@@ -216,13 +237,29 @@ func fileModeToUnixMode(mode os.FileMode) uint32 {
if mode&os.ModeSetgid != 0 {
m |= s_ISGID
}
+ if mode&os.ModeSticky != 0 {
+ m |= s_ISVTX
+ }
return m | uint32(mode&0777)
}
func unixModeToFileMode(m uint32) os.FileMode {
- var mode os.FileMode
- if m&s_IFMT == s_IFDIR {
+ mode := os.FileMode(m & 0777)
+ switch m & s_IFMT {
+ case s_IFBLK:
+ mode |= os.ModeDevice
+ case s_IFCHR:
+ mode |= os.ModeDevice | os.ModeCharDevice
+ case s_IFDIR:
mode |= os.ModeDir
+ case s_IFIFO:
+ mode |= os.ModeNamedPipe
+ case s_IFLNK:
+ mode |= os.ModeSymlink
+ case s_IFREG:
+ // nothing to do
+ case s_IFSOCK:
+ mode |= os.ModeSocket
}
if m&s_ISGID != 0 {
mode |= os.ModeSetgid
@@ -230,5 +267,8 @@ func unixModeToFileMode(m uint32) os.FileMode {
if m&s_ISUID != 0 {
mode |= os.ModeSetuid
}
- return mode | os.FileMode(m&0777)
+ if m&s_ISVTX != 0 {
+ mode |= os.ModeSticky
+ }
+ return mode
}
diff --git a/libgo/go/archive/zip/testdata/symlink.zip b/libgo/go/archive/zip/testdata/symlink.zip
new file mode 100644
index 0000000..af84693
--- /dev/null
+++ b/libgo/go/archive/zip/testdata/symlink.zip
Binary files differ
diff --git a/libgo/go/archive/zip/writer.go b/libgo/go/archive/zip/writer.go
index b1b128e..a4f0654 100644
--- a/libgo/go/archive/zip/writer.go
+++ b/libgo/go/archive/zip/writer.go
@@ -19,7 +19,7 @@ import (
// Writer implements a zip file writer.
type Writer struct {
- *countWriter
+ countWriter
dir []*header
last *fileWriter
closed bool
@@ -32,7 +32,7 @@ type header struct {
// NewWriter returns a new Writer writing a zip file to w.
func NewWriter(w io.Writer) *Writer {
- return &Writer{countWriter: &countWriter{w: bufio.NewWriter(w)}}
+ return &Writer{countWriter: countWriter{w: bufio.NewWriter(w)}}
}
// Close finishes writing the zip file by writing the central directory.
diff --git a/libgo/go/archive/zip/writer_test.go b/libgo/go/archive/zip/writer_test.go
index 5a576b1..ce93fae 100644
--- a/libgo/go/archive/zip/writer_test.go
+++ b/libgo/go/archive/zip/writer_test.go
@@ -47,10 +47,10 @@ var writeTests = []WriteTest{
Mode: 0755 | os.ModeSetgid,
},
{
- Name: "setgid",
- Data: []byte("setgid file"),
+ Name: "symlink",
+ Data: []byte("../link/target"),
Method: Deflate,
- Mode: 0755 | os.ModeSetgid,
+ Mode: 0755 | os.ModeSymlink,
},
}
diff --git a/libgo/go/archive/zip/zip_test.go b/libgo/go/archive/zip/zip_test.go
index acd3d93..1a260cc 100644
--- a/libgo/go/archive/zip/zip_test.go
+++ b/libgo/go/archive/zip/zip_test.go
@@ -85,4 +85,7 @@ func TestFileHeaderRoundTrip(t *testing.T) {
if !reflect.DeepEqual(fh, fh2) {
t.Errorf("mismatch\n input=%#v\noutput=%#v\nerr=%v", fh, fh2, err)
}
+ if sysfh, ok := fi.Sys().(*FileHeader); !ok && sysfh != fh {
+ t.Errorf("Sys didn't return original *FileHeader")
+ }
}