From 36189e2704fa29d6ad1dc20466374c5ebce9e78a Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 15 Feb 2021 08:59:53 -0800 Subject: [PATCH] wgengine/monitor: prevent shutdown hang in darwin link monitor --- wgengine/monitor/monitor_darwin_tailscaled.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/wgengine/monitor/monitor_darwin_tailscaled.go b/wgengine/monitor/monitor_darwin_tailscaled.go index 2d53fc77e..f7123cf65 100644 --- a/wgengine/monitor/monitor_darwin_tailscaled.go +++ b/wgengine/monitor/monitor_darwin_tailscaled.go @@ -8,8 +8,10 @@ import ( "bufio" + "errors" "os/exec" + "tailscale.com/syncs" "tailscale.com/types/logger" ) @@ -29,12 +31,14 @@ func newOSMon(logf logger.Logf) (osMon, error) { // we can just shell out to "route -n monitor". It waits for any input // but doesn't parse it. Then we poll to see if something is different. type routeMonitorSubProcMon struct { - cmd *exec.Cmd // of "/sbin/route -n monitor" - br *bufio.Reader - buf []byte + closed syncs.AtomicBool + cmd *exec.Cmd // of "/sbin/route -n monitor" + br *bufio.Reader + buf []byte } func (m *routeMonitorSubProcMon) Close() error { + m.closed.Set(true) if m.cmd != nil { m.cmd.Process.Kill() m.cmd = nil @@ -43,6 +47,9 @@ func (m *routeMonitorSubProcMon) Close() error { } func (m *routeMonitorSubProcMon) Receive() (message, error) { + if m.closed.Get() { + return nil, errors.New("monitor closed") + } if m.cmd == nil { cmd := exec.Command("/sbin/route", "-n", "monitor") outPipe, err := cmd.StdoutPipe()