Skip to content

Commit 8bad3ca

Browse files
committed
fileutils: Use ModeType as the mask for mode checks
POSIX provides S_IS*(m) macros to portably interpret the mode type, but does not define values for each type [1]. Alban pointed out that st_mode is not a bitfield on Linux [2]. For example, Linux defines [3]: S_IFBLK 060000 S_IFDIR 040000 S_IFCHR 020000 So 'm&S_IFCHR == S_IFCHR', for example, would succeed for both character and block devices. Go translates the system values to a platform-agnostic bitfield [4], so the previous approach works on Go. But it may be confusing for people used to the native non-bitfield mode, so this commit moves us to an approach that does not rely on Go's using a bitfield. I've also dropped the 07000 portion of the previous 07777 mask in favor of the cross-platform ModePerm mask. This avoids an internal magic number, and the sticky, suid, and sgid bits don't make sense for device nodes. And I'm using some contants from os instead of their syscall analogs. We can't drop the syscall dependency, because we're still using syscall to construct the Mknod arguments, but with this commit we're no longer using it to inspect the source file type. [1]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html [2]: opencontainers/runtime-tools#308 (comment) [3]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/stat.h?h=v4.16#n9 [4]: https://github.com/golang/go/blob/b0d437f866eb8987cde7e6550cacd77876f36d4b/src/os/types.go#L45
1 parent 7d4729f commit 8bad3ca

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

fileutils.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ func CopyFile(source string, dest string) error {
2222

2323
uid := int(st.Uid)
2424
gid := int(st.Gid)
25+
modeType := si.Mode()&os.ModeType
2526

2627
// Handle symlinks
27-
if si.Mode()&os.ModeSymlink != 0 {
28+
if modeType == os.ModeSymlink {
2829
target, err := os.Readlink(source)
2930
if err != nil {
3031
return err
@@ -35,15 +36,14 @@ func CopyFile(source string, dest string) error {
3536
}
3637

3738
// Handle device files
38-
if st.Mode&syscall.S_IFMT == syscall.S_IFBLK || st.Mode&syscall.S_IFMT == syscall.S_IFCHR {
39+
if modeType == os.ModeDevice {
3940
devMajor := int64(major(uint64(st.Rdev)))
4041
devMinor := int64(minor(uint64(st.Rdev)))
41-
mode := uint32(si.Mode() & 07777)
42-
if st.Mode&syscall.S_IFMT == syscall.S_IFBLK {
43-
mode |= syscall.S_IFBLK
44-
}
45-
if st.Mode&syscall.S_IFMT == syscall.S_IFCHR {
42+
mode := uint32(si.Mode() & os.ModePerm)
43+
if si.Mode()&os.ModeCharDevice != 0 {
4644
mode |= syscall.S_IFCHR
45+
} else {
46+
mode |= syscall.S_IFBLK
4747
}
4848
if err := syscall.Mknod(dest, mode, int(mkdev(devMajor, devMinor))); err != nil {
4949
return err
@@ -76,7 +76,7 @@ func CopyFile(source string, dest string) error {
7676
}
7777

7878
// Chmod the file
79-
if !(si.Mode()&os.ModeSymlink == os.ModeSymlink) {
79+
if !(modeType == os.ModeSymlink) {
8080
if err := os.Chmod(dest, si.Mode()); err != nil {
8181
return err
8282
}

0 commit comments

Comments
 (0)