package main import ( "errors" "fmt" "io" "os" "path/filepath" ) // checkNew fails if path already exists. func checkNew(path string) error { if _, err := os.Lstat(path); err == nil { return fmt.Errorf("%s already exists; outputs are never overwritten", path) } else if !errors.Is(err, os.ErrNotExist) { return err } return nil } // writeAtomic stages the output in a private temporary file next to path and // publishes it only after fn succeeded (spec ยง56). Publication creates path // without replacing an existing file: a hard link where the file system // supports it, otherwise an exclusive create and copy. On any failure no // partial output remains. func writeAtomic(path string, fn func(io.Writer) error) (err error) { if err := checkNew(path); err != nil { return err } tmp, err := os.CreateTemp(filepath.Dir(path), ".datekeys-*") if err != nil { return err } name := tmp.Name() defer func() { tmp.Close() os.Remove(name) }() if err := fn(tmp); err != nil { return err } if err := tmp.Sync(); err != nil { return err } if err := tmp.Close(); err != nil { return err } if err := os.Link(name, path); err == nil { return nil } else if errors.Is(err, os.ErrExist) { return fmt.Errorf("%s already exists; outputs are never overwritten", path) } return copyExclusive(name, path) } func copyExclusive(from, to string) error { src, err := os.Open(from) if err != nil { return err } defer src.Close() dst, err := os.OpenFile(to, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600) if err != nil { return err } _, copyErr := io.Copy(dst, src) syncErr := dst.Sync() closeErr := dst.Close() if err := errors.Join(copyErr, syncErr, closeErr); err != nil { os.Remove(to) return err } return nil }