summaryrefslogtreecommitdiffstats
path: root/plugin/rpcplugin/io.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/rpcplugin/io.go')
-rw-r--r--plugin/rpcplugin/io.go54
1 files changed, 49 insertions, 5 deletions
diff --git a/plugin/rpcplugin/io.go b/plugin/rpcplugin/io.go
index f1b2f3c35..38229d868 100644
--- a/plugin/rpcplugin/io.go
+++ b/plugin/rpcplugin/io.go
@@ -1,7 +1,10 @@
package rpcplugin
import (
+ "bufio"
+ "encoding/binary"
"io"
+ "os"
)
type rwc struct {
@@ -9,15 +12,56 @@ type rwc struct {
io.WriteCloser
}
-func (rwc *rwc) Close() error {
- rerr := rwc.ReadCloser.Close()
+func (rwc *rwc) Close() (err error) {
+ if f, ok := rwc.ReadCloser.(*os.File); ok {
+ // https://groups.google.com/d/topic/golang-nuts/i4w58KJ5-J8/discussion
+ err = os.NewFile(f.Fd(), "").Close()
+ } else {
+ err = rwc.ReadCloser.Close()
+ }
werr := rwc.WriteCloser.Close()
- if rerr != nil {
- return rerr
+ if err == nil {
+ err = werr
}
- return werr
+ return
}
func NewReadWriteCloser(r io.ReadCloser, w io.WriteCloser) io.ReadWriteCloser {
return &rwc{r, w}
}
+
+type RemoteIOReader struct {
+ conn io.ReadWriteCloser
+}
+
+func (r *RemoteIOReader) Read(b []byte) (int, error) {
+ var buf [10]byte
+ n := binary.PutVarint(buf[:], int64(len(b)))
+ if _, err := r.conn.Write(buf[:n]); err != nil {
+ return 0, err
+ }
+ return r.conn.Read(b)
+}
+
+func (r *RemoteIOReader) Close() error {
+ return r.conn.Close()
+}
+
+func ConnectIOReader(conn io.ReadWriteCloser) io.ReadCloser {
+ return &RemoteIOReader{conn}
+}
+
+func ServeIOReader(r io.Reader, conn io.ReadWriteCloser) {
+ cr := bufio.NewReader(conn)
+ defer conn.Close()
+ buf := make([]byte, 32*1024)
+ for {
+ n, err := binary.ReadVarint(cr)
+ if err != nil {
+ break
+ }
+ if written, err := io.CopyBuffer(conn, io.LimitReader(r, n), buf); err != nil || written < n {
+ break
+ }
+ }
+}