From 4ddd87e7738601ac2125283b0e7e260eed18e12e Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 22 Sep 2014 15:48:46 +0200 Subject: [PATCH] Locking around osutil.Rename and some descriptive text --- model/model.go | 12 +----------- osutil/osutil.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/model/model.go b/model/model.go index dc6dc7911..ebb3afcbd 100644 --- a/model/model.go +++ b/model/model.go @@ -630,13 +630,6 @@ func (m *Model) SetIgnores(repo string, content []string) error { fmt.Fprintln(writer, line) } - err = writer.Flush() - if err != nil { - l.Warnln("Saving .stignore:", err) - fd.Close() - return err - } - err = fd.Close() if err != nil { l.Warnln("Saving .stignore:", err) @@ -644,10 +637,7 @@ func (m *Model) SetIgnores(repo string, content []string) error { } file := filepath.Join(cfg.Directory, ".stignore") - m.rmut.Lock() - os.Remove(file) - err = osutil.Rename(fd.Name(), file) - m.rmut.Unlock() + err = osutil.Rename(tmpFileName, file) if err != nil { l.Warnln("Saving .stignore:", err) return err diff --git a/osutil/osutil.go b/osutil/osutil.go index 08a991e20..32f5595ed 100644 --- a/osutil/osutil.go +++ b/osutil/osutil.go @@ -9,9 +9,22 @@ import ( "os" "path/filepath" "runtime" + "sync" ) +// Try to keep this entire operation atomic-like. We shouldn't be doing this +// often enough that there is any contention on this lock. +var renameLock sync.Mutex + +// Rename renames a file, while trying hard to succeed on various systems by +// temporarily tweaking directory permissions and removing the destination +// file when necessary. Will make sure to delete the from file if the +// operation fails, so use only for situations like committing a temp file to +// it's final location. func Rename(from, to string) error { + renameLock.Lock() + defer renameLock.Unlock() + // Make sure the destination directory is writeable toDir := filepath.Dir(to) if info, err := os.Stat(toDir); err == nil {