]> Cypherpunks repositories - gostls13.git/commitdiff
godoc: atomically update filter file
authorRobert Griesemer <gri@golang.org>
Tue, 14 Sep 2010 23:54:38 +0000 (16:54 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 14 Sep 2010 23:54:38 +0000 (16:54 -0700)
R=rsc
CC=golang-dev
https://golang.org/cl/2206041

src/cmd/godoc/godoc.go
src/cmd/godoc/utils.go

index e174c4e5aee03c1a042db2e99b282aa0fae72a05..484098323590f33c2d69e076a0bcb0aad6452ca7 100644 (file)
@@ -170,10 +170,8 @@ func updateFilterFile() {
        })
 
        // update filter file
-       // TODO(gri) should write a tmp file and atomically rename
-       err := ioutil.WriteFile(*filter, buf.Bytes(), 0666)
-       if err != nil {
-               log.Stderrf("ioutil.Writefile(%s): %s", *filter, err)
+       if err := writeFileAtomically(*filter, buf.Bytes()); err != nil {
+               log.Stderrf("writeFileAtomically(%s): %s", *filter, err)
                filterDelay.backoff(24 * 60) // back off exponentially, but try at least once a day
        } else {
                filterDelay.set(*filterMin) // revert to regular filter update schedule
index f95ff83f2308b1eface946e8ea761dd41c2ffaa6..55cf878414362343aa51d3784098affa2fb0f272 100644 (file)
@@ -7,6 +7,8 @@
 package main
 
 import (
+       "io"
+       "io/ioutil"
        "os"
        pathutil "path"
        "sort"
@@ -85,3 +87,23 @@ func canonicalizePaths(list []string, filter func(path string) bool) []string {
 
        return list[0:i]
 }
+
+
+// writeFileAtomically writes data to a temporary file and then
+// atomically renames that file to the file named by filename.
+//
+func writeFileAtomically(filename string, data []byte) os.Error {
+       f, err := ioutil.TempFile(cwd, filename)
+       if err != nil {
+               return err
+       }
+       n, err := f.Write(data)
+       f.Close()
+       if err != nil {
+               return err
+       }
+       if n < len(data) {
+               return io.ErrShortWrite
+       }
+       return os.Rename(f.Name(), filename)
+}