Took a step back on cmd exec, just getting EOF/hangup on client/server ends working

This commit is contained in:
Russ Magee 2018-01-17 20:36:53 -08:00
parent ad5366bdfb
commit cca2895526
2 changed files with 67 additions and 24 deletions

View file

@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"sync"
hkex "blitter.com/herradurakex"
)
@ -22,6 +23,8 @@ import (
// connection (app-specific, passed through to the server to use or
// ignore at its discretion).
func main() {
var wg sync.WaitGroup
var cAlg string
var hAlg string
var server string
@ -36,8 +39,48 @@ func main() {
fmt.Println("Err!")
panic(err)
}
_, err = io.Copy(conn, os.Stdin)
if err != nil && err.Error() != "EOF" {
fmt.Println(err)
defer conn.Close()
wg.Add(1)
go func() {
// This will guarantee the side that closes first
// marks its direction's goroutine as finished.
// Whichever direction's goroutine finishes first
// will call wg.Done() once more explicitly to
// hang up on the other side so the client
// exits immediately on an EOF from either side.
defer wg.Done()
// io.Copy() expects EOF so this will
// exit with inerr == nil
_, inerr := io.Copy(os.Stdout, conn)
if inerr != nil {
if inerr.Error() != "EOF" {
fmt.Println(inerr)
os.Exit(1)
}
}
fmt.Println("[Got Write EOF]")
wg.Done() // client hanging up, close server read goroutine
}()
wg.Add(1)
go func() {
defer wg.Done()
// io.Copy() expects EOF so this will
// exit with outerr == nil
_, outerr := io.Copy(conn, os.Stdin)
if outerr != nil {
if outerr.Error() != "EOF" {
fmt.Println(outerr)
os.Exit(2)
}
}
fmt.Println("[Got Read EOF]")
wg.Done() // server hung up, close client write goroutine
}()
// Wait until both stdin and stdout goroutines finish
wg.Wait()
}

View file

@ -33,16 +33,9 @@ type cmdRunner struct {
who string
arg string
authCookie string
CloseHandler func(*cmdRunner)
status int
}
func testCloseHandler(r *cmdRunner) {
fmt.Println("[testCloseHandler()]")
r.arg = "/usr/bin/touch " + r.arg
cmd(r)
}
func cmd(r *cmdRunner) {
switch r.op {
case OpR:
@ -134,7 +127,7 @@ func main() {
}(ch, eCh)
ticker := time.Tick(time.Second / 100)
var r cmdRunner
//var r cmdRunner
var connOp *byte = nil
Term:
// continuously read from the connection
@ -157,12 +150,20 @@ func main() {
fmt.Printf("[* connOp '%c']\n", *connOp)
// The CloseHandler typically handles the
// accumulated command data
r = cmdRunner{op: Op(*connOp),
who: "larissa", arg: string(data),
authCookie: "c00ki3",
CloseHandler: testCloseHandler,
status: 0}
conn.Write([]byte("SERVER OUTPUT"))
//r = cmdRunner{op: Op(*connOp),
// who: "larissa", arg: string(data),
// authCookie: "c00ki3",
// status: 0}
}
// From here, one could pass all subsequent data
// between client/server attached to an exec.Cmd,
// as data to/from a file, etc.
conn.Write([]byte("SERVER RESPONSE to '"))
conn.Write(data)
conn.Write([]byte("'\n"))
if strings.Trim(string(data), "\r\n") == "exit" {
conn.Close()
}
//fmt.Printf("Client sent %s\n", string(data))
@ -171,7 +172,6 @@ func main() {
// handle our error then exit for loop
if err.Error() == "EOF" {
fmt.Printf("[Client disconnected]\n")
r.CloseHandler(&r)
} else {
fmt.Printf("Error reading client data! (%+v)\n", err)
}