From 8b67b395b9eb708e820bcc96c3821027f2bde360 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 13 Jun 2019 11:24:08 +0200 Subject: conf: don't crash when config directory is removed --- conf/storewatcher_windows.go | 25 ++++++++++++++++++++----- conf/zsyscall_windows.go | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/conf/storewatcher_windows.go b/conf/storewatcher_windows.go index f5cbb553..19956263 100644 --- a/conf/storewatcher_windows.go +++ b/conf/storewatcher_windows.go @@ -22,7 +22,7 @@ const ( fncSECURITY uint32 = 0x00000100 ) -//sys findFirstChangeNotification(path *uint16, watchSubtree bool, filter uint32) (handle windows.Handle, err error) = kernel32.FindFirstChangeNotificationW +//sys findFirstChangeNotification(path *uint16, watchSubtree bool, filter uint32) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = kernel32.FindFirstChangeNotificationW //sys findNextChangeNotification(handle windows.Handle) (err error) = kernel32.FindNextChangeNotification var haveStartedWatchingConfigDir bool @@ -33,18 +33,30 @@ func startWatchingConfigDir() { } haveStartedWatchingConfigDir = true go func() { + h := windows.InvalidHandle + defer func() { + if h != windows.InvalidHandle { + windows.CloseHandle(h) + } + haveStartedWatchingConfigDir = false + }() + startover: configFileDir, err := tunnelConfigurationsDirectory() if err != nil { return } - h, err := findFirstChangeNotification(windows.StringToUTF16Ptr(configFileDir), true, fncFILE_NAME|fncDIR_NAME|fncATTRIBUTES|fncSIZE|fncLAST_WRITE|fncLAST_ACCESS|fncCREATION|fncSECURITY) + h, err = findFirstChangeNotification(windows.StringToUTF16Ptr(configFileDir), true, fncFILE_NAME|fncDIR_NAME|fncATTRIBUTES|fncSIZE|fncLAST_WRITE|fncLAST_ACCESS|fncCREATION|fncSECURITY) if err != nil { - log.Fatalf("Unable to monitor config directory: %v", err) + log.Printf("Unable to monitor config directory: %v", err) + return } for { s, err := windows.WaitForSingleObject(h, windows.INFINITE) if err != nil || s == windows.WAIT_FAILED { - log.Fatalf("Unable to wait on config directory watcher: %v", err) + log.Printf("Unable to wait on config directory watcher: %v", err) + windows.CloseHandle(h) + h = windows.InvalidHandle + goto startover } for cb := range storeCallbacks { @@ -53,7 +65,10 @@ func startWatchingConfigDir() { err = findNextChangeNotification(h) if err != nil { - log.Fatalf("Unable to monitor config directory again: %v", err) + log.Printf("Unable to monitor config directory again: %v", err) + windows.CloseHandle(h) + h = windows.InvalidHandle + goto startover } } }() diff --git a/conf/zsyscall_windows.go b/conf/zsyscall_windows.go index 7ad7bbab..4cf6d0bd 100644 --- a/conf/zsyscall_windows.go +++ b/conf/zsyscall_windows.go @@ -104,7 +104,7 @@ func findFirstChangeNotification(path *uint16, watchSubtree bool, filter uint32) } r0, _, e1 := syscall.Syscall(procFindFirstChangeNotificationW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(_p0), uintptr(filter)) handle = windows.Handle(r0) - if handle == 0 { + if handle == windows.InvalidHandle { if e1 != 0 { err = errnoErr(e1) } else { -- cgit v1.2.3-59-g8ed1b