mirror of https://gogs.blitter.com/RLabs/xs
				
				
				
			Took a step back on cmd exec, just getting EOF/hangup on client/server ends working
This commit is contained in:
		
							parent
							
								
									ad5366bdfb
								
							
						
					
					
						commit
						cca2895526
					
				| 
						 | 
				
			
			@ -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()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue