package mining import ( "os" "path/filepath" ) // AtomicWriteFile("profiles.json", data, 0644) func AtomicWriteFile(path string, data []byte, perm os.FileMode) error { dir := filepath.Dir(path) tmpFile, err := os.CreateTemp(dir, ".tmp-*") if err != nil { return ErrInternal("create temp file").WithCause(err) } tmpPath := tmpFile.Name() success := false defer func() { if !success { os.Remove(tmpPath) } }() if _, err := tmpFile.Write(data); err != nil { tmpFile.Close() return ErrInternal("write temp file").WithCause(err) } if err := tmpFile.Sync(); err != nil { tmpFile.Close() return ErrInternal("sync temp file").WithCause(err) } if err := tmpFile.Close(); err != nil { return ErrInternal("close temp file").WithCause(err) } if err := os.Chmod(tmpPath, perm); err != nil { return ErrInternal("set file permissions").WithCause(err) } if err := os.Rename(tmpPath, path); err != nil { return ErrInternal("rename temp file").WithCause(err) } success = true return nil }