|
|
@@ -6,6 +6,7 @@ package killist |
|
|
import ( |
|
|
import ( |
|
|
"bufio" |
|
|
"bufio" |
|
|
"os" |
|
|
"os" |
|
|
|
|
|
"path/filepath" |
|
|
"strings" |
|
|
"strings" |
|
|
"sync" |
|
|
"sync" |
|
|
) |
|
|
) |
|
|
@@ -79,15 +80,33 @@ func (kl *KillList) List() []string { |
|
|
return out |
|
|
return out |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// save writes the kill list atomically: it writes to a temp file in the same |
|
|
|
|
|
// directory, flushes, closes, then renames over the target. This ensures the |
|
|
|
|
|
// existing file is never truncated on a partial write or flush error. |
|
|
func (kl *KillList) save() error { |
|
|
func (kl *KillList) save() error { |
|
|
f, err := os.Create(kl.filepath) |
|
|
|
|
|
|
|
|
dir := filepath.Dir(kl.filepath) |
|
|
|
|
|
tmp, err := os.CreateTemp(dir, ".killist-*.tmp") |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return err |
|
|
return err |
|
|
} |
|
|
} |
|
|
defer f.Close() |
|
|
|
|
|
w := bufio.NewWriter(f) |
|
|
|
|
|
|
|
|
tmpName := tmp.Name() |
|
|
|
|
|
|
|
|
|
|
|
w := bufio.NewWriter(tmp) |
|
|
for t := range kl.titles { |
|
|
for t := range kl.titles { |
|
|
w.WriteString(t + "\n") |
|
|
|
|
|
|
|
|
if _, err := w.WriteString(t + "\n"); err != nil { |
|
|
|
|
|
tmp.Close() |
|
|
|
|
|
os.Remove(tmpName) |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if err := w.Flush(); err != nil { |
|
|
|
|
|
tmp.Close() |
|
|
|
|
|
os.Remove(tmpName) |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
if err := tmp.Close(); err != nil { |
|
|
|
|
|
os.Remove(tmpName) |
|
|
|
|
|
return err |
|
|
} |
|
|
} |
|
|
return w.Flush() |
|
|
|
|
|
|
|
|
return os.Rename(tmpName, kl.filepath) |
|
|
} |
|
|
} |