title: How to handle EOF / Ctrl+D in Go crypto/ssh session.Wait()
body: <p>When I use <code>session.Shell()</code> to start a new shell on a remote server and then <code>session.Wait()</code> to run the session until the remote end exits the session does not gracefully handle using Ctrl+D to end the session.</p>
  
  <p>I can make this work using <code>os/exec</code> to launch a local child process to run whatever copy of the ssh client is available locally, but I would prefer to do this with native Go.</p>
  
  <p>Examle code snippet:</p>
  
  <pre><code>conn, err := ssh.Dial("tcp", "some-server.fqdn", sshConfig)
  if err != nil {
    return err
  }
  defer conn.Close()
  
  session, err := conn.NewSession()
  if err != nil {
    return err
  }
  defer session.Close()
  
  session.Stdout = os.Stdout
  session.Stderr = os.Stderr
  session.Stdin = os.Stdin
  
  modes := ssh.TerminalModes{
    ssh.ECHO:          0,
    ssh.TTY_OP_ISPEED: 14400,
    ssh.TTY_OP_OSPEED: 14400,
  }
  
  err = session.RequestPty("xterm", 80, 40, modes)
  if err != nil {
    return err
  }
  
  err = session.Shell()
  if err != nil {
    return err
  }
  session.Wait()
  </code></pre>
  
  <p>Running <code>exit</code> on the remote server gracefully hangs up the remote end and <code>session.Wait()</code> returns as expected, but sending an EOF with Ctrl+D causes the remote end to hang up but the call to <code>session.Wait()</code> is stuck blocking. I have to use Ctrl+C to SIGINT the Go program.
  I would like to get both to gracefully exit the <code>session.Wait()</code> call as that is expected behavior for most interactive ssh sessions.</p>