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"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hkex "blitter.com/herradurakex"
 | 
						hkex "blitter.com/herradurakex"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -22,6 +23,8 @@ import (
 | 
				
			||||||
// connection (app-specific, passed through to the server to use or
 | 
					// connection (app-specific, passed through to the server to use or
 | 
				
			||||||
// ignore at its discretion).
 | 
					// ignore at its discretion).
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
 | 
						var wg sync.WaitGroup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var cAlg string
 | 
						var cAlg string
 | 
				
			||||||
	var hAlg string
 | 
						var hAlg string
 | 
				
			||||||
	var server string
 | 
						var server string
 | 
				
			||||||
| 
						 | 
					@ -36,8 +39,48 @@ func main() {
 | 
				
			||||||
		fmt.Println("Err!")
 | 
							fmt.Println("Err!")
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, err = io.Copy(conn, os.Stdin)
 | 
						defer conn.Close()
 | 
				
			||||||
	if err != nil && err.Error() != "EOF" {
 | 
					
 | 
				
			||||||
		fmt.Println(err)
 | 
						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()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,18 +29,11 @@ const (
 | 
				
			||||||
type Op uint8
 | 
					type Op uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cmdRunner struct {
 | 
					type cmdRunner struct {
 | 
				
			||||||
	op           Op
 | 
						op         Op
 | 
				
			||||||
	who          string
 | 
						who        string
 | 
				
			||||||
	arg          string
 | 
						arg        string
 | 
				
			||||||
	authCookie   string
 | 
						authCookie string
 | 
				
			||||||
	CloseHandler func(*cmdRunner)
 | 
						status     int
 | 
				
			||||||
	status       int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func testCloseHandler(r *cmdRunner) {
 | 
					 | 
				
			||||||
	fmt.Println("[testCloseHandler()]")
 | 
					 | 
				
			||||||
	r.arg = "/usr/bin/touch " + r.arg
 | 
					 | 
				
			||||||
	cmd(r)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func cmd(r *cmdRunner) {
 | 
					func cmd(r *cmdRunner) {
 | 
				
			||||||
| 
						 | 
					@ -134,7 +127,7 @@ func main() {
 | 
				
			||||||
			}(ch, eCh)
 | 
								}(ch, eCh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ticker := time.Tick(time.Second / 100)
 | 
								ticker := time.Tick(time.Second / 100)
 | 
				
			||||||
			var r cmdRunner
 | 
								//var r cmdRunner
 | 
				
			||||||
			var connOp *byte = nil
 | 
								var connOp *byte = nil
 | 
				
			||||||
		Term:
 | 
							Term:
 | 
				
			||||||
			// continuously read from the connection
 | 
								// continuously read from the connection
 | 
				
			||||||
| 
						 | 
					@ -157,12 +150,20 @@ func main() {
 | 
				
			||||||
						fmt.Printf("[* connOp '%c']\n", *connOp)
 | 
											fmt.Printf("[* connOp '%c']\n", *connOp)
 | 
				
			||||||
						// The CloseHandler typically handles the
 | 
											// The CloseHandler typically handles the
 | 
				
			||||||
						// accumulated command data
 | 
											// accumulated command data
 | 
				
			||||||
						r = cmdRunner{op: Op(*connOp),
 | 
											//r = cmdRunner{op: Op(*connOp),
 | 
				
			||||||
							who: "larissa", arg: string(data),
 | 
											//	who: "larissa", arg: string(data),
 | 
				
			||||||
							authCookie:   "c00ki3",
 | 
											//	authCookie:   "c00ki3",
 | 
				
			||||||
							CloseHandler: testCloseHandler,
 | 
											//	status:       0}
 | 
				
			||||||
							status:       0}
 | 
										}
 | 
				
			||||||
						conn.Write([]byte("SERVER OUTPUT"))
 | 
										
 | 
				
			||||||
 | 
										// 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))
 | 
										//fmt.Printf("Client sent %s\n", string(data))
 | 
				
			||||||
| 
						 | 
					@ -171,7 +172,6 @@ func main() {
 | 
				
			||||||
					// handle our error then exit for loop
 | 
										// handle our error then exit for loop
 | 
				
			||||||
					if err.Error() == "EOF" {
 | 
										if err.Error() == "EOF" {
 | 
				
			||||||
						fmt.Printf("[Client disconnected]\n")
 | 
											fmt.Printf("[Client disconnected]\n")
 | 
				
			||||||
						r.CloseHandler(&r)
 | 
					 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						fmt.Printf("Error reading client data! (%+v)\n", err)
 | 
											fmt.Printf("Error reading client data! (%+v)\n", err)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue