Skip to content

Commit

Permalink
save: Create temporary file first before overwriting the target file
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeKar committed Apr 29, 2024
1 parent e562115 commit 35016cc
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions internal/buffer/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error,
var writeCloser io.WriteCloser
var screenb bool
var cmd *exec.Cmd
tmpName := name + ".tmp"

if withSudo {
cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+name)
cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+tmpName)

if writeCloser, err = cmd.StdinPipe(); err != nil {
return
Expand All @@ -54,7 +55,7 @@ func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error,
screen.TempStart(screenb)
return err
}
} else if writeCloser, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666); err != nil {
} else if writeCloser, err = os.OpenFile(tmpName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666); err != nil {
return
}

Expand All @@ -79,10 +80,34 @@ func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error,
if withSudo {
// wait for dd to finish and restart the screen if we used sudo
err := cmd.Wait()
if err != nil {
screen.TempStart(screenb)
return err
}

cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "mv", tmpName, name)

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
<-c
cmd.Process.Kill()
}()

if e := cmd.Start(); e != nil && err == nil {
screen.TempStart(screenb)
return err
}

err = cmd.Wait()
screen.TempStart(screenb)
if err != nil {
return err
}
} else {
if err == nil {
err = os.Rename(tmpName, name)
}
}

return
Expand Down

0 comments on commit 35016cc

Please sign in to comment.