|
|
@ -2,6 +2,7 @@ package common |
|
|
|
|
|
|
|
import ( |
|
|
|
"fmt" |
|
|
|
"io/ioutil" |
|
|
|
"os" |
|
|
|
"os/signal" |
|
|
|
) |
|
|
@ -26,3 +27,26 @@ func Exit(s string) { |
|
|
|
fmt.Printf(s + "\n") |
|
|
|
os.Exit(1) |
|
|
|
} |
|
|
|
|
|
|
|
// Writes to newBytes to filePath.
|
|
|
|
// Guaranteed not to lose *both* oldBytes and newBytes,
|
|
|
|
// (assuming that the OS is perfect)
|
|
|
|
func AtomicWriteFile(filePath string, newBytes []byte) error { |
|
|
|
// If a file already exists there, copy to filePath+".bak" (overwrite anything)
|
|
|
|
if _, err := os.Stat(filePath); !os.IsNotExist(err) { |
|
|
|
fileBytes, err := ioutil.ReadFile(filePath) |
|
|
|
if err != nil { |
|
|
|
return fmt.Errorf("Failed to read file %v. %v", filePath, err) |
|
|
|
} |
|
|
|
err = ioutil.WriteFile(filePath+".bak", fileBytes, 0600) |
|
|
|
if err != nil { |
|
|
|
return fmt.Errorf("Failed to write file %v. %v", filePath+".bak", err) |
|
|
|
} |
|
|
|
} |
|
|
|
// Write newBytes to filePath.
|
|
|
|
err := ioutil.WriteFile(filePath, newBytes, 0600) |
|
|
|
if err != nil { |
|
|
|
return fmt.Errorf("Failed to write file %v. %v", filePath, err) |
|
|
|
} |
|
|
|
return nil |
|
|
|
} |