mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-15 11:14:31 +08:00
- 新增无头运行时及连接、查询、导出、批处理、审计和 MCP 命令 - 复用活动数据根、密文存储与跨进程锁,落实写入安全和取消语义 - 增加六平台 CLI 归档、独立校验和、Docker、npm 与 WinGet 分发 - 隔离 GUI/CLI 更新资产并强化 macOS 签名与公证门禁 - 补充并发、审计、事务及发布契约回归测试 Refs #902
39 lines
951 B
Go
39 lines
951 B
Go
//go:build !windows
|
|
|
|
package app
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
func atomicReplaceSQLAuditFile(source, target string) error {
|
|
if err := os.Rename(source, target); err != nil {
|
|
return err
|
|
}
|
|
directory, err := os.Open(filepath.Dir(target))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return errors.Join(directory.Sync(), directory.Close())
|
|
}
|
|
|
|
// atomicCreateSQLAuditFile publishes source at target without replacing an
|
|
// existing target. Both paths are created in the same directory, so a hard
|
|
// link gives us an atomic CREATE_NEW-style destination while the temporary
|
|
// source remains private until it is removed.
|
|
func atomicCreateSQLAuditFile(source, target string) error {
|
|
if err := os.Link(source, target); err != nil {
|
|
return err
|
|
}
|
|
if err := os.Remove(source); err != nil {
|
|
return err
|
|
}
|
|
directory, err := os.Open(filepath.Dir(target))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return errors.Join(directory.Sync(), directory.Close())
|
|
}
|