mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-10 08:43:34 +08:00
- 将日志目录配置整合到数据目录设置,支持选择、打开、恢复默认与保存 - 持久化日志目录并保留环境变量优先级,目录调整后重启生效 - 通过跨进程锁和原子写入保护数据目录与日志目录配置 - 移除重复标题并互斥目录修改操作,补齐六语言文案 - 补充桌面接口、浏览器模拟及并发回归测试
50 lines
1.1 KiB
Go
50 lines
1.1 KiB
Go
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
|
|
|
|
package appdata
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
type bootstrapFileLock struct {
|
|
file *os.File
|
|
}
|
|
|
|
func acquireBootstrapFileLock(path string) (*bootstrapFileLock, error) {
|
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := unix.Flock(int(file.Fd()), unix.LOCK_EX); err != nil {
|
|
_ = file.Close()
|
|
return nil, err
|
|
}
|
|
_ = file.Chmod(0o600)
|
|
return &bootstrapFileLock{file: file}, nil
|
|
}
|
|
|
|
func (lock *bootstrapFileLock) Close() error {
|
|
if lock == nil || lock.file == nil {
|
|
return nil
|
|
}
|
|
unlockErr := unix.Flock(int(lock.file.Fd()), unix.LOCK_UN)
|
|
closeErr := lock.file.Close()
|
|
lock.file = nil
|
|
return errors.Join(unlockErr, closeErr)
|
|
}
|
|
|
|
func atomicReplaceBootstrapFile(source string, 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())
|
|
}
|