add "process is running" check to checkSSHMaster() · coder/sshcode@4d64fc0
@@ -11,8 +11,8 @@ import (
1111"os/signal"
1212"path/filepath"
1313"strconv"
14-"syscall"
1514"strings"
15+"syscall"
1616"time"
17171818"github.com/pkg/browser"
@@ -67,9 +67,13 @@ func sshCode(host, dir string, o options) error {
6767sshMasterCmd.Stdin = os.Stdin
6868sshMasterCmd.Stdout = os.Stdout
6969sshMasterCmd.Stderr = os.Stderr
70-stopSSHMaster := func () {
70+stopSSHMaster := func() {
7171if sshMasterCmd.Process != nil {
72-err := sshMasterCmd.Process.Signal(syscall.SIGTERM)
72+err := sshMasterCmd.Process.Signal(syscall.Signal(0))
73+if err != nil {
74+return
75+ }
76+err = sshMasterCmd.Process.Signal(syscall.SIGTERM)
7377if err != nil {
7478flog.Error("failed to send SIGTERM to SSH master process: %v", err)
7579 }
@@ -78,12 +82,13 @@ func sshCode(host, dir string, o options) error {
7882defer stopSSHMaster()
79838084err = sshMasterCmd.Start()
85+go sshMasterCmd.Wait()
8186if err != nil {
8287flog.Error("failed to start SSH master connection, disabling connection reuse feature: %v", err)
8388o.noReuseConnection = true
8489stopSSHMaster()
8590 } else {
86-err = checkSSHMaster(newSSHFlags, host)
91+err = checkSSHMaster(sshMasterCmd, newSSHFlags, host)
8792if err != nil {
8893flog.Error("SSH master failed to be ready in time, disabling connection reuse feature: %v", err)
8994o.noReuseConnection = true
@@ -307,22 +312,32 @@ func randomPort() (string, error) {
307312308313// checkSSHMaster polls every second for 30 seconds to check if the SSH master
309314// is ready.
310-func checkSSHMaster(sshFlags string, host string) (err error) {
311-maxTries := 30
312-check := func() error {
315+func checkSSHMaster(sshMasterCmd *exec.Cmd, sshFlags string, host string) error {
316+var (
317+maxTries = 30
318+sleepDur = time.Second
319+err error
320+ )
321+for i := 0; i < maxTries; i++ {
322+// Check if the master is running
323+if sshMasterCmd.Process == nil {
324+return xerrors.Errorf("SSH master process not running")
325+ }
326+err = sshMasterCmd.Process.Signal(syscall.Signal(0))
327+if err != nil {
328+return xerrors.Errorf("failed to check if SSH master process was alive: %v", err)
329+ }
330+331+// Check if it's ready
313332sshCmdStr := fmt.Sprintf(`ssh %v -O check %v`, sshFlags, host)
314333sshCmd := exec.Command("sh", "-c", sshCmdStr)
315-return sshCmd.Run()
316- }
317-318-for i := 0; i < maxTries; i++ {
319-err = check()
334+err = sshCmd.Run()
320335if err == nil {
321336return nil
322337 }
323-time.Sleep(time.Second)
338+time.Sleep(sleepDur)
324339 }
325-return err
340+return xerrors.Errorf("max number of tries exceeded: %d", maxTries)
326341}
327342328343func syncUserSettings(sshFlags string, host string, back bool) error {