Go 38 lines
//go:build !windows
package selfupdate
import (
"os"
"path/filepath"
)
// swap atomically replaces target with newPath. The temp file is written
// in the same directory as target so the rename is a same-filesystem
// move (POSIX guarantees atomicity for those).
func swap(newPath, target string) error {
info, err := os.Stat(target)
if err != nil {
return err
}
dir := filepath.Dir(target)
tmp, err := os.CreateTemp(dir, ".eeco-new-*")
if err != nil {
return err
}
tmpName := tmp.Name()
if err := tmp.Close(); err != nil {
os.Remove(tmpName)
return err
}
if err := copyFile(newPath, tmpName); err != nil {
os.Remove(tmpName)
return err
}
if err := os.Chmod(tmpName, info.Mode()); err != nil {
os.Remove(tmpName)
return err
}
return os.Rename(tmpName, target)
}