mirror of
				https://gogs.blitter.com/RLabs/xs
				synced 2024-08-14 10:26:42 +00:00 
			
		
		
		
	Fixed incomplete -x cmd output due to premature ptmx.Close for non-interactive sessions
Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
		
							parent
							
								
									a4ceaed4c5
								
							
						
					
					
						commit
						6e8156eefb
					
				
					 2 changed files with 7 additions and 17 deletions
				
			
		|  | @ -70,10 +70,9 @@ type ( | ||||||
| 
 | 
 | ||||||
| 	// Conn is a connection wrapping net.Conn with KEX & session state | 	// Conn is a connection wrapping net.Conn with KEX & session state | ||||||
| 	Conn struct { | 	Conn struct { | ||||||
| 		kex      KEXAlg      // KEX/KEM proposal (client -> server) | 		kex KEXAlg      // KEX/KEM proposal (client -> server) | ||||||
| 		m        *sync.Mutex // (internal) | 		m   *sync.Mutex // (internal) | ||||||
| 		c        *net.Conn   // which also implements io.Reader, io.Writer, ... | 		c   *net.Conn   // which also implements io.Reader, io.Writer, ... | ||||||
| 		immClose bool |  | ||||||
| 
 | 
 | ||||||
| 		logCipherText  bool // somewhat expensive, for debugging | 		logCipherText  bool // somewhat expensive, for debugging | ||||||
| 		logPlainText   bool // INSECURE and somewhat expensive, for debugging | 		logPlainText   bool // INSECURE and somewhat expensive, for debugging | ||||||
|  | @ -139,10 +138,6 @@ func (hc *Conn) SetStatus(stat CSOType) { | ||||||
| 	log.Println("closeStat:", *hc.closeStat) | 	log.Println("closeStat:", *hc.closeStat) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (hc *Conn) SetImmClose() { |  | ||||||
| 	hc.immClose = true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ConnOpts returns the cipher/hmac options value, which is sent to the | // ConnOpts returns the cipher/hmac options value, which is sent to the | ||||||
| // peer but is not itself part of the KEx. | // peer but is not itself part of the KEx. | ||||||
| // | // | ||||||
|  | @ -757,13 +752,7 @@ func (hc *Conn) Close() (err error) { | ||||||
| 	log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat) | 	log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat) | ||||||
| 	//(*hc.c).SetWriteDeadline(time.Now().Add(500 * time.Millisecond)) | 	//(*hc.c).SetWriteDeadline(time.Now().Add(500 * time.Millisecond)) | ||||||
| 	hc.WritePacket(s, CSOExitStatus) | 	hc.WritePacket(s, CSOExitStatus) | ||||||
| 	// This avoids a bug where server side may not get its last packet of | 	err = (*hc.c).Close() | ||||||
| 	// data through to a client for non-interactive commands which exit |  | ||||||
| 	// immediately. Avoiding the immediate close lets the client close its |  | ||||||
| 	// side first. |  | ||||||
| 	if hc.immClose { |  | ||||||
| 		err = (*hc.c).Close() |  | ||||||
| 	} |  | ||||||
| 	logger.LogDebug(fmt.Sprintln("[Conn Closing]")) | 	logger.LogDebug(fmt.Sprintln("[Conn Closing]")) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  | @ -1059,7 +1048,6 @@ func (hc Conn) Read(b []byte) (n int, err error) { | ||||||
| 					logger.LogDebug(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]")) | 					logger.LogDebug(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]")) | ||||||
| 					hc.SetStatus(CSETruncCSO) | 					hc.SetStatus(CSETruncCSO) | ||||||
| 				} | 				} | ||||||
| 				hc.SetImmClose() // clients can immediately close their end |  | ||||||
| 				hc.Close() | 				hc.Close() | ||||||
| 			} else if ctrlStatOp == CSOTunSetup { | 			} else if ctrlStatOp == CSOTunSetup { | ||||||
| 				// server side tunnel setup in response to client | 				// server side tunnel setup in response to client | ||||||
|  |  | ||||||
|  | @ -405,7 +405,9 @@ func runShellAs(who, hname, ttype, cmd string, interactive bool, conn *hkexnet.C | ||||||
| 			// Background jobs still may be running; close the | 			// Background jobs still may be running; close the | ||||||
| 			// pty anyway, so the client can return before | 			// pty anyway, so the client can return before | ||||||
| 			// wg.Wait() below completes (Issue #18) | 			// wg.Wait() below completes (Issue #18) | ||||||
| 			_ = ptmx.Close() | 			if interactive { | ||||||
|  | 				_ = ptmx.Close() | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		wg.Wait() // Wait on pty->stdout completion to client | 		wg.Wait() // Wait on pty->stdout completion to client | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue