Set the execute bit on Windows executables (fixes #1762)

This commit is contained in:
Jakob Borg 2015-05-05 21:19:59 +02:00
parent e6866ee980
commit 5fc0808f28
2 changed files with 25 additions and 3 deletions

View File

@ -192,3 +192,21 @@ func copyFileContents(src, dst string) (err error) {
err = out.Sync() err = out.Sync()
return return
} }
var execExts map[string]bool
func init() {
// PATHEXT contains a list of executable file extensions, on Windows
pathext := filepath.SplitList(os.Getenv("PATHEXT"))
// We want the extensions in execExts to be lower case
execExts = make(map[string]bool, len(pathext))
for _, ext := range pathext {
execExts[strings.ToLower(ext)] = true
}
}
// IsWindowsExecutable returns true if the given path has an extension that is
// in the list of executable extensions.
func IsWindowsExecutable(path string) bool {
return execExts[strings.ToLower(filepath.Ext(path))]
}

View File

@ -308,6 +308,11 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
} }
if info.Mode().IsRegular() { if info.Mode().IsRegular() {
curMode := uint32(info.Mode())
if runtime.GOOS == "windows" && osutil.IsWindowsExecutable(rn) {
curMode |= 0111
}
if w.CurrentFiler != nil { if w.CurrentFiler != nil {
// A file is "unchanged", if it // A file is "unchanged", if it
// - exists // - exists
@ -319,7 +324,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
// - was not invalid (since it looks valid now) // - was not invalid (since it looks valid now)
// - has the same size as previously // - has the same size as previously
cf, ok = w.CurrentFiler.CurrentFile(rn) cf, ok = w.CurrentFiler.CurrentFile(rn)
permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Flags, uint32(info.Mode())) permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Flags, curMode)
if ok && permUnchanged && !cf.IsDeleted() && cf.Modified == info.ModTime().Unix() && !cf.IsDirectory() && if ok && permUnchanged && !cf.IsDeleted() && cf.Modified == info.ModTime().Unix() && !cf.IsDirectory() &&
!cf.IsSymlink() && !cf.IsInvalid() && cf.Size() == info.Size() { !cf.IsSymlink() && !cf.IsInvalid() && cf.Size() == info.Size() {
return nil return nil
@ -330,7 +335,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
} }
} }
var flags = uint32(info.Mode() & maskModePerm) var flags = curMode & uint32(maskModePerm)
if w.IgnorePerms { if w.IgnorePerms {
flags = protocol.FlagNoPermBits | 0666 flags = protocol.FlagNoPermBits | 0666
} }
@ -387,5 +392,4 @@ func SymlinkTypeEqual(disk, index uint32) bool {
return true return true
} }
return disk&protocol.SymlinkTypeMask == index&protocol.SymlinkTypeMask return disk&protocol.SymlinkTypeMask == index&protocol.SymlinkTypeMask
} }