mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-06 15:10:27 +09:00
save: fsync data safely to disk (#2681)
On modern Linux systems, it can take 30 seconds for the data to actually hit the disk (check /proc/sys/vm/dirty_expire_centisecs). If the computer crashes in those 30 seconds, the user may end up with an empty file as seen here: https://github.com/neovim/neovim/issues/9888 This is why editors like vim and nano call the fsync syscall after they wrote the file. This syscall is available as file.Sync() in Go. Running strace against micro shows that fsync is called as expected: $ strace -f -p $(pgrep micro) -e fsync strace: Process 3284344 attached with 9 threads [pid 3284351] fsync(8) = 0 Also, we now catch errors returned from w.Flush().
This commit is contained in:
@@ -59,10 +59,20 @@ func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error,
|
||||
|
||||
w := bufio.NewWriter(transform.NewWriter(writeCloser, enc.NewEncoder()))
|
||||
err = fn(w)
|
||||
w.Flush()
|
||||
|
||||
if e := writeCloser.Close(); e != nil && err == nil {
|
||||
err = e
|
||||
if err2 := w.Flush(); err2 != nil && err == nil {
|
||||
err = err2
|
||||
}
|
||||
// Call Sync() on the file to make sure the content is safely on disk.
|
||||
// Does not work with sudo as we don't have direct access to the file.
|
||||
if !withSudo {
|
||||
f := writeCloser.(*os.File)
|
||||
if err2 := f.Sync(); err2 != nil && err == nil {
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
if err2 := writeCloser.Close(); err2 != nil && err == nil {
|
||||
err = err2
|
||||
}
|
||||
|
||||
if withSudo {
|
||||
|
||||
Reference in New Issue
Block a user