Skip to content

Commit 5383522

Browse files
committed
Cleanup lchmod logic in archive
Move to single lchmod interface mirroring other implementations. Separate logic for freebsd which supports symlink no follow flag. Signed-off-by: Derek McGowan <[email protected]>
1 parent 7eceeb9 commit 5383522

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)