]> git.lizzy.rs Git - micro.git/commitdiff
Fix #1383: "Save with Sudo" rewrite (#1424)
authorBonnie <41487185+estrogently@users.noreply.github.com>
Fri, 3 Jan 2020 22:39:12 +0000 (23:39 +0100)
committerZachary Yedidia <zyedidia@gmail.com>
Fri, 3 Jan 2020 22:39:12 +0000 (17:39 -0500)
* Rewrite save with sudo (Fixes #1383)

* Combine overrideFile & overrideFileAsRoot into 1 function

internal/buffer/backup.go
internal/buffer/save.go
internal/buffer/serialize.go

index 8a2e24bef1cf0307d81f0be1062d0c83bc3d478c..192ab63832384af11d4194a3a7c963ba5482f04f 100644 (file)
@@ -71,7 +71,7 @@ func (b *Buffer) Backup(checkTime bool) error {
                        }
                }
                return
-       })
+       }, false)
 
        return err
 }
index 8bf04259d983cb96ec22b29038c27854d56d0666..990e2f256a952f28a8e12efdda0d8d8a8dd7db96 100644 (file)
@@ -27,76 +27,42 @@ const LargeFileThreshold = 50000
 // overwriteFile opens the given file for writing, truncating if one exists, and then calls
 // the supplied function with the file as io.Writer object, also making sure the file is
 // closed afterwards.
-func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error) (err error) {
-       var file *os.File
-
-       if file, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
-               return
-       }
-
-       defer func() {
-               if e := file.Close(); e != nil && err == nil {
-                       err = e
-               }
-       }()
-
-       w := transform.NewWriter(file, enc.NewEncoder())
-       // w := bufio.NewWriter(file)
-
-       if err = fn(w); err != nil {
-               return
-       }
-
-       // err = w.Flush()
-       return
-}
-
-// overwriteFileAsRoot executes dd as root and then calls the supplied function
-// with dd's standard input as an io.Writer object. Dd opens the given file for writing,
-// truncating it if it exists, and writes what it receives on its standard input to the file.
-func overwriteFileAsRoot(name string, enc encoding.Encoding, fn func(io.Writer) error) (err error) {
-       var cmd *exec.Cmd
-       if runtime.GOOS == "windows" {
-               return errors.New("Save with sudo not supported on Windows")
-       } else if runtime.GOOS == "darwin" {
-               cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+name)
-       } else {
-               cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "status=none", "bs=4K", "of="+name)
-       }
-       var stdin io.WriteCloser
-
-       screenb := screen.TempFini()
-       defer screen.TempStart(screenb)
-
-       // This is a trap for Ctrl-C so that it doesn't kill micro
-       // Instead we trap Ctrl-C to kill the program we're running
-       c := make(chan os.Signal, 1)
-       signal.Notify(c, os.Interrupt)
-       go func() {
-               for range c {
-                       cmd.Process.Kill()
-               }
-       }()
-
-       if stdin, err = cmd.StdinPipe(); err != nil {
-               return
-       }
-
-       if err = cmd.Start(); err != nil {
-               return
-       }
-
-       e := fn(stdin)
-
-       if err = stdin.Close(); err != nil {
-               return
-       }
-
-       if err = cmd.Wait(); err != nil {
-               return
-       }
-
-       return e
+func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error, withSudo bool) (err error) {
+    var writeCloser io.WriteCloser
+
+    if withSudo {
+        cmd := exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+name)
+
+        if writeCloser, err = cmd.StdinPipe(); err != nil {
+            return
+        }
+
+        c := make(chan os.Signal, 1)
+        signal.Notify(c, os.Interrupt)
+        go func() {
+            <-c
+            cmd.Process.Kill()
+        }()
+
+        defer func() {
+            screenb := screen.TempFini()
+            if e := cmd.Run(); e != nil && err == nil {
+                err = e
+            }
+            screen.TempStart(screenb)
+        }()
+    } else if writeCloser, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
+        return
+    }
+
+    w := transform.NewWriter(writeCloser, enc.NewEncoder())
+    err = fn(w)
+
+    if e := writeCloser.Close(); e != nil && err == nil {
+        err = e
+    }
+
+    return
 }
 
 // Save saves the buffer to its default path
@@ -125,6 +91,9 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
        if b.Type.Scratch {
                return errors.New("Cannot save scratch buffer")
        }
+       if withSudo && runtime.GOOS == "windows" {
+           return errors.New("Save with sudo not supported on Windows")
+       }
 
        b.UpdateRules()
        if b.Settings["rmtrailingws"].(bool) {
@@ -208,14 +177,8 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
                return
        }
 
-       if withSudo {
-               err = overwriteFileAsRoot(absFilename, enc, fwriter)
-       } else {
-               err = overwriteFile(absFilename, enc, fwriter)
-       }
-
-       if err != nil {
-               return err
+       if err = overwriteFile(absFilename, enc, fwriter, withSudo); err != nil {
+           return err
        }
 
        if !b.Settings["fastdirty"].(bool) {
index 16c4b6bfaabaca45de8e53d0987b9be66742efcf..6bd0820024a8236617d4eb63c3b67534aa776a6b 100644 (file)
@@ -39,7 +39,7 @@ func (b *Buffer) Serialize() error {
                        b.ModTime,
                })
                return err
-       })
+       }, false)
 }
 
 func (b *Buffer) Unserialize() error {