Skip to content

Instantly share code, notes, and snippets.

@chowey
Last active September 6, 2018 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chowey/69e48cd70c884a78bfeb93ea9e764535 to your computer and use it in GitHub Desktop.
Save chowey/69e48cd70c884a78bfeb93ea9e764535 to your computer and use it in GitHub Desktop.
Bidirectional stream copy

This implementation of bidirectional stream copy has the right behavior for closing streams. The first stream to return io.EOF as a reader triggers a close on the second stream, and then the bidirectional copy may be considered done. The close on the second stream should trigger an error (e.g. io.EOF) on the read of the first stream, closing that stream too.

package main
func CopyBidirectional(a, b io.ReadWriteCloser) {
select {
case <-copyStream(a, b):
case <-copyStream(b, a):
}
}
func copyStream(dst io.WriteCloser, src io.Reader) <-chan struct{} {
done := make(chan struct{})
go func() {
defer close(done)
defer dst.Close()
io.Copy(dst, src)
}()
return done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment