Skip to content
This repository was archived by the owner on Jan 17, 2021. It is now read-only.

Commit 4d64fc0

Browse files
committed
add "process is running" check to checkSSHMaster()
Checks if the master process is running by sending signal 0 to it. According to kill(2), sending a signal of 0 will send no signal but will still perform error checking. To prevent the SSH master from becoming a zombie process, a wait call was added in a goroutine.
1 parent 3141f7f commit 4d64fc0

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

sshcode.go

+29-14
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"os/signal"
1212
"path/filepath"
1313
"strconv"
14-
"syscall"
1514
"strings"
15+
"syscall"
1616
"time"
1717

1818
"github.com/pkg/browser"
@@ -67,9 +67,13 @@ func sshCode(host, dir string, o options) error {
6767
sshMasterCmd.Stdin = os.Stdin
6868
sshMasterCmd.Stdout = os.Stdout
6969
sshMasterCmd.Stderr = os.Stderr
70-
stopSSHMaster := func () {
70+
stopSSHMaster := func() {
7171
if 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)
7377
if err != nil {
7478
flog.Error("failed to send SIGTERM to SSH master process: %v", err)
7579
}
@@ -78,12 +82,13 @@ func sshCode(host, dir string, o options) error {
7882
defer stopSSHMaster()
7983

8084
err = sshMasterCmd.Start()
85+
go sshMasterCmd.Wait()
8186
if err != nil {
8287
flog.Error("failed to start SSH master connection, disabling connection reuse feature: %v", err)
8388
o.noReuseConnection = true
8489
stopSSHMaster()
8590
} else {
86-
err = checkSSHMaster(newSSHFlags, host)
91+
err = checkSSHMaster(sshMasterCmd, newSSHFlags, host)
8792
if err != nil {
8893
flog.Error("SSH master failed to be ready in time, disabling connection reuse feature: %v", err)
8994
o.noReuseConnection = true
@@ -307,22 +312,32 @@ func randomPort() (string, error) {
307312

308313
// 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
313332
sshCmdStr := fmt.Sprintf(`ssh %v -O check %v`, sshFlags, host)
314333
sshCmd := 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()
320335
if err == nil {
321336
return 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
}
327342

328343
func syncUserSettings(sshFlags string, host string, back bool) error {

0 commit comments

Comments
 (0)