Browse code

Merge pull request #33935 from AkihiroSuda/pkg-archive-go1.9

pkg/archive.FileInfoHeader: fill file type bits

Tibor Vass authored on 2017/07/07 06:22:45
Showing 1 changed files
... ...
@@ -93,6 +93,16 @@ const (
93 93
 	OverlayWhiteoutFormat
94 94
 )
95 95
 
96
+const (
97
+	modeISDIR  = 040000  // Directory
98
+	modeISFIFO = 010000  // FIFO
99
+	modeISREG  = 0100000 // Regular file
100
+	modeISLNK  = 0120000 // Symbolic link
101
+	modeISBLK  = 060000  // Block special file
102
+	modeISCHR  = 020000  // Character special file
103
+	modeISSOCK = 0140000 // Socket
104
+)
105
+
96 106
 // IsArchivePath checks if the (possibly compressed) file at the given path
97 107
 // starts with a tar file header.
98 108
 func IsArchivePath(path string) bool {
... ...
@@ -305,12 +315,14 @@ func (compression *Compression) Extension() string {
305 305
 
306 306
 // FileInfoHeader creates a populated Header from fi.
307 307
 // Compared to archive pkg this function fills in more information.
308
+// Also, regardless of Go version, this function fills file type bits (e.g. hdr.Mode |= modeISDIR),
309
+// which have been deleted since Go 1.9 archive/tar.
308 310
 func FileInfoHeader(name string, fi os.FileInfo, link string) (*tar.Header, error) {
309 311
 	hdr, err := tar.FileInfoHeader(fi, link)
310 312
 	if err != nil {
311 313
 		return nil, err
312 314
 	}
313
-	hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
315
+	hdr.Mode = fillGo18FileTypeBits(int64(chmodTarEntry(os.FileMode(hdr.Mode))), fi)
314 316
 	name, err = canonicalTarName(name, fi.IsDir())
315 317
 	if err != nil {
316 318
 		return nil, fmt.Errorf("tar: cannot canonicalize path: %v", err)
... ...
@@ -322,6 +334,31 @@ func FileInfoHeader(name string, fi os.FileInfo, link string) (*tar.Header, erro
322 322
 	return hdr, nil
323 323
 }
324 324
 
325
+// fillGo18FileTypeBits fills type bits which have been removed on Go 1.9 archive/tar
326
+// https://github.com/golang/go/commit/66b5a2f
327
+func fillGo18FileTypeBits(mode int64, fi os.FileInfo) int64 {
328
+	fm := fi.Mode()
329
+	switch {
330
+	case fm.IsRegular():
331
+		mode |= modeISREG
332
+	case fi.IsDir():
333
+		mode |= modeISDIR
334
+	case fm&os.ModeSymlink != 0:
335
+		mode |= modeISLNK
336
+	case fm&os.ModeDevice != 0:
337
+		if fm&os.ModeCharDevice != 0 {
338
+			mode |= modeISCHR
339
+		} else {
340
+			mode |= modeISBLK
341
+		}
342
+	case fm&os.ModeNamedPipe != 0:
343
+		mode |= modeISFIFO
344
+	case fm&os.ModeSocket != 0:
345
+		mode |= modeISSOCK
346
+	}
347
+	return mode
348
+}
349
+
325 350
 // ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem
326 351
 // to a tar header
327 352
 func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {