Skip to content

Commit 0573e22

Browse files
authored
Merge pull request #5702 from dmcgowan/archive-cleanup-lchmod
archive: cleanup lchmod logic
2 parents 7eceeb9 + 5383522 commit 0573e22

5 files changed

Lines changed: 36 additions & 21 deletions

File tree

archive/tar.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,8 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header
393393
}
394394
}
395395

396-
// There is no LChmod, so ignore mode for symlink. Also, this
397-
// must happen after chown, as that can modify the file mode
398-
if err := handleLChmod(hdr, path, hdrInfo); err != nil {
396+
// call lchmod after lchown since lchown can modify the file mode
397+
if err := lchmod(path, hdrInfo.Mode()); err != nil {
399398
return err
400399
}
401400

archive/tar_freebsd.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
package archive
2020

21-
import "golang.org/x/sys/unix"
21+
import (
22+
"os"
23+
24+
"golang.org/x/sys/unix"
25+
)
2226

2327
// mknod wraps unix.Mknod. FreeBSD's unix.Mknod signature is different from
2428
// other Unix and Unix-like operating systems.
@@ -34,3 +38,11 @@ func lsetxattrCreate(link string, attr string, data []byte) error {
3438
}
3539
return err
3640
}
41+
42+
func lchmod(path string, mode os.FileMode) error {
43+
err := unix.Fchmodat(unix.AT_FDCWD, path, uint32(mode), unix.AT_SYMLINK_NOFOLLOW)
44+
if err != nil {
45+
err = &os.PathError{Op: "lchmod", Path: path, Err: err}
46+
}
47+
return err
48+
}

archive/tar_mostunix.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
package archive
2020

21-
import "golang.org/x/sys/unix"
21+
import (
22+
"os"
23+
24+
"golang.org/x/sys/unix"
25+
)
2226

2327
// mknod wraps Unix.Mknod and casts dev to int
2428
func mknod(path string, mode uint32, dev uint64) error {
@@ -34,3 +38,18 @@ func lsetxattrCreate(link string, attr string, data []byte) error {
3438
}
3539
return err
3640
}
41+
42+
// lchmod checks for symlink and changes the mode if not a symlink
43+
func lchmod(path string, mode os.FileMode) error {
44+
fi, err := os.Lstat(path)
45+
if err != nil {
46+
return err
47+
}
48+
49+
if fi.Mode()&os.ModeSymlink == 0 {
50+
if err := os.Chmod(path, mode); err != nil {
51+
return err
52+
}
53+
}
54+
return nil
55+
}

archive/tar_unix.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,6 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
111111
return mknod(path, mode, unix.Mkdev(uint32(hdr.Devmajor), uint32(hdr.Devminor)))
112112
}
113113

114-
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
115-
if hdr.Typeflag == tar.TypeLink {
116-
if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
117-
if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) {
118-
return err
119-
}
120-
}
121-
} else if hdr.Typeflag != tar.TypeSymlink {
122-
if err := os.Chmod(path, hdrInfo.Mode()); err != nil {
123-
return err
124-
}
125-
}
126-
return nil
127-
}
128-
129114
func getxattr(path, attr string) ([]byte, error) {
130115
b, err := sysx.LGetxattr(path, attr)
131116
if err == unix.ENOTSUP || err == sysx.ENODATA {

archive/tar_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
9898
return nil
9999
}
100100

101-
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
101+
func lchmod(path string, mode os.FileMode) error {
102102
return nil
103103
}
104104

0 commit comments

Comments
 (0)