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

Commit 3141f7f

Browse files
committed
move SSH master process tidyup to a deferred func
- Replace the `ssh -O exit` tidyup command with just a SIGTERM on the master - Add `exec` to the front of the SSH master cmd so it replaces the `sh` process (so we can send SIGTERM to it easier)
1 parent e646d57 commit 3141f7f

File tree

1 file changed

+27
-39
lines changed

1 file changed

+27
-39
lines changed

sshcode.go

+27-39
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os/signal"
1212
"path/filepath"
1313
"strconv"
14+
"syscall"
1415
"strings"
1516
"time"
1617

@@ -57,32 +58,36 @@ func sshCode(host, dir string, o options) error {
5758

5859
// Start SSH master connection socket. This prevents multiple password prompts from appearing as authentication
5960
// only happens on the initial connection.
60-
var sshMasterCmd *exec.Cmd
6161
if !o.noReuseConnection {
6262
newSSHFlags := fmt.Sprintf(`%v -o "ControlPath=%v"`, o.sshFlags, sshControlPath)
6363

6464
// -MN means "start a master socket and don't open a session, just connect".
65-
sshMasterCmdStr := fmt.Sprintf(`ssh %v -MN %v`, newSSHFlags, host)
66-
sshMasterCmd = exec.Command("sh", "-c", sshMasterCmdStr)
65+
sshCmdStr := fmt.Sprintf(`exec ssh %v -MN %v`, newSSHFlags, host)
66+
sshMasterCmd := exec.Command("sh", "-c", sshCmdStr)
6767
sshMasterCmd.Stdin = os.Stdin
6868
sshMasterCmd.Stdout = os.Stdout
6969
sshMasterCmd.Stderr = os.Stderr
70+
stopSSHMaster := func () {
71+
if sshMasterCmd.Process != nil {
72+
err := sshMasterCmd.Process.Signal(syscall.SIGTERM)
73+
if err != nil {
74+
flog.Error("failed to send SIGTERM to SSH master process: %v", err)
75+
}
76+
}
77+
}
78+
defer stopSSHMaster()
79+
7080
err = sshMasterCmd.Start()
7181
if err != nil {
7282
flog.Error("failed to start SSH master connection, disabling connection reuse feature: %v", err)
7383
o.noReuseConnection = true
84+
stopSSHMaster()
7485
} else {
75-
// Wait for master to be ready.
7686
err = checkSSHMaster(newSSHFlags, host)
7787
if err != nil {
78-
flog.Error("SSH master failed to start in time, disabling connection reuse feature: %v", err)
88+
flog.Error("SSH master failed to be ready in time, disabling connection reuse feature: %v", err)
7989
o.noReuseConnection = true
80-
if sshMasterCmd.Process != nil {
81-
err = sshMasterCmd.Process.Kill()
82-
if err != nil {
83-
flog.Error("failed to kill SSH master connection, ignoring: %v", err)
84-
}
85-
}
90+
stopSSHMaster()
8691
} else {
8792
sshMasterCmd.Stdin = nil
8893
o.sshFlags = newSSHFlags
@@ -183,39 +188,22 @@ func sshCode(host, dir string, o options) error {
183188
case <-ctx.Done():
184189
case <-c:
185190
}
186-
flog.Info("exiting")
187191

188-
if o.syncBack && !o.skipSync {
189-
flog.Info("synchronizing VS Code back to local")
192+
flog.Info("shutting down")
193+
if !o.syncBack || o.skipSync {
194+
return nil
195+
}
190196

191-
err = syncExtensions(o.sshFlags, host, true)
192-
if err != nil {
193-
flog.Error("failed to sync extensions back: %v", err)
194-
}
197+
flog.Info("synchronizing VS Code back to local")
195198

196-
err = syncUserSettings(o.sshFlags, host, true)
197-
if err != nil {
198-
flog.Error("failed to sync user settings settings back: %v", err)
199-
}
199+
err = syncExtensions(o.sshFlags, host, true)
200+
if err != nil {
201+
return xerrors.Errorf("failed to sync extensions back: %v", err)
200202
}
201203

202-
// Kill the master connection if we made one.
203-
if !o.noReuseConnection {
204-
// Try using the -O exit syntax first before killing the master.
205-
sshCmdStr = fmt.Sprintf(`ssh %v -O exit %v`, o.sshFlags, host)
206-
sshCmd = exec.Command("sh", "-c", sshCmdStr)
207-
sshCmd.Stdout = os.Stdout
208-
sshCmd.Stderr = os.Stderr
209-
err = sshCmd.Run()
210-
if err != nil {
211-
flog.Error("failed to gracefully stop SSH master connection, killing: %v", err)
212-
if sshMasterCmd.Process != nil {
213-
err = sshMasterCmd.Process.Kill()
214-
if err != nil {
215-
flog.Error("failed to kill SSH master connection, ignoring: %v", err)
216-
}
217-
}
218-
}
204+
err = syncUserSettings(o.sshFlags, host, true)
205+
if err != nil {
206+
return xerrors.Errorf("failed to sync user settings settings back: %v", err)
219207
}
220208

221209
return nil

0 commit comments

Comments
 (0)