//go:build !windows && !plan9 && !js && !linux package local import ( "os" "syscall" "golang.org/x/sys/unix" ) const haveLChmod = true // syscallMode returns the syscall-specific mode bits from Go's portable mode bits. // // Borrowed from the syscall source since it isn't public. func syscallMode(i os.FileMode) (o uint32) { o |= uint32(i.Perm()) if i&os.ModeSetuid != 0 { o |= syscall.S_ISUID } if i&os.ModeSetgid != 0 { o |= syscall.S_ISGID } if i&os.ModeSticky != 0 { o |= syscall.S_ISVTX } return o } // lChmod changes the mode of the named file to mode. If the file is a symbolic // link, it changes the link, not the target. If there is an error, // it will be of type *PathError. func lChmod(name string, mode os.FileMode) error { // NB linux does not support AT_SYMLINK_NOFOLLOW as a parameter to fchmodat // and returns ENOTSUP if you try, so we don't support this on linux if e := unix.Fchmodat(unix.AT_FDCWD, name, syscallMode(mode), unix.AT_SYMLINK_NOFOLLOW); e != nil { return &os.PathError{Op: "lChmod", Path: name, Err: e} } return nil }