Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions acme.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"fmt"
"io"
"os"
Expand All @@ -11,24 +12,32 @@ import (
"9fans.net/go/acme"
)

var nl = []byte("\n")

// We would use io.Copy except for a bug in acme
// where it crashes when reading trying to read more
// than the negotiated 9P message size.
func copyBody(w io.Writer, win *acme.Win) error {
func copyBody(w io.Writer, win *acme.Win) (endsWithNL bool, err error) {
buf := make([]byte, 8000)
for {
n, err := win.Read("body", buf)
if err == io.EOF {
break
}
if err != nil {
return err
return false, err
}
if _, err := w.Write(buf[0:n]); err != nil {
return fmt.Errorf("write error: %v", err)
if _, err := w.Write(buf[:n]); err != nil {
return false, fmt.Errorf("write error: %v", err)
}
endsWithNL = bytes.HasSuffix(buf[:n], nl)
}
return nil
if !endsWithNL {
if _, err := w.Write(nl); err != nil {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I like the idea but I don't think this is quite right. Consider, for example, a body that consists just of the single character "a". Running apipe sha256sum should result in the body being replaced by sha256("a") but AFAICS this change means it'll be replaced by sha256("a\n").

I think that the only "right" solution here is to cope with the \ No newline at end of file line produced by diff in this case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I attempted to cope with \ No newline at end of file before but gave up. This approach was the one I was able to get done. It suits my usecase well, but you're right it's not a good general solution.

return false, fmt.Errorf("write error: %v", err)
}
}
return endsWithNL, nil
}

func acmeCurrentWin() (*acme.Win, error) {
Expand Down
25 changes: 15 additions & 10 deletions apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ func Main() error {
if err != nil {
return err
}
if err := copyBody(bodyFile, win); err != nil {
endsWithNL, err := copyBody(bodyFile, win)
if err != nil {
return err
}
bodyFile.Seek(0, 0)
Expand All @@ -70,24 +71,28 @@ func Main() error {
if err := pcmd.Start(); err != nil {
return fmt.Errorf("cannot start %q: %v", cmdArgs[0], err)
}
// TODO this doesn't appear to have the desired effect -
// changes made after "nomark" don't seem to be undoable.
// if _, err := win.Write("ctl", []byte("nomark")); err != nil {
// return err
// }
// defer win.Write("ctl", []byte("mark"))
err = apply(diffOut, func(addr string, data []byte) error {
if _, err := win.Write("ctl", []byte("mark")); err != nil {
return err
}
if _, err := win.Write("ctl", []byte("nomark")); err != nil {
return err
}
defer win.Write("ctl", []byte("mark"))
edit := func(addr string, data []byte) error {
if _, err := win.Write("addr", []byte(addr)); err != nil {
return fmt.Errorf("cannot set address %q: %v", addr, err)
}
if err := writeData(win, data); err != nil {
return fmt.Errorf("cannot write data: %v", err)
}
return nil
})
if err != nil {
}
if err := apply(diffOut, edit); err != nil {
return err
}
if !endsWithNL {
return edit(`$-/\n/`, nil)
}
return nil
}

Expand Down