diff options
author | Tomas Janousek <tomi@nomi.cz> | 2017-11-04 20:07:30 +0100 |
---|---|---|
committer | Tomas Janousek <tomi@nomi.cz> | 2018-04-05 10:45:19 +0200 |
commit | 3b88faefe7a2a512ebf2dcde4f3cdb3e89b98393 (patch) | |
tree | 8c6b4694c3c70e3b5f2d886e9558b734cb69cd34 | |
parent | 40fd9dfe82a734057640b4495ed5d8d93531c4fc (diff) | |
download | xmobar-3b88faefe7a2a512ebf2dcde4f3cdb3e89b98393.tar.gz xmobar-3b88faefe7a2a512ebf2dcde4f3cdb3e89b98393.tar.bz2 |
Net: fix race condition in netParser/readNetDev/isUp
It's possible (and happens) that netParser sees a device that is no
longer there when we get to isUp. This happens almost every time I
resume from suspend and the WWAN card (USB device) reappears, and
results in xmobar showing the exception until I restart it.
Originally I tried
tryJust (guard . isDoesNotExistError) (B.readFile (operstateDir d))
and it worked for a while but in recent kernels it's possible to open
the file and have the device disappear before we get to reading the
contents of it, so we need to surround the whole open/read block in
catchIOError and make sure it's evaluated.
-rw-r--r-- | src/Plugins/Monitors/Net.hs | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/src/Plugins/Monitors/Net.hs b/src/Plugins/Monitors/Net.hs index e290539..9819fe2 100644 --- a/src/Plugins/Monitors/Net.hs +++ b/src/Plugins/Monitors/Net.hs @@ -27,6 +27,7 @@ import Control.Monad (forM, filterM) import System.Directory (getDirectoryContents, doesFileExist) import System.FilePath ((</>)) import System.Console.GetOpt +import System.IO.Error (catchIOError) import qualified Data.ByteString.Lazy.Char8 as B @@ -105,9 +106,9 @@ existingDevs = getDirectoryContents "/sys/class/net" >>= filterM isDev excludes = [".", "..", "lo"] isUp :: String -> IO Bool -isUp d = do +isUp d = flip catchIOError (const $ return False) $ do operstate <- B.readFile (operstateDir d) - return $ (B.unpack . head . B.lines) operstate `elem` ["up", "unknown"] + return $! (B.unpack . head . B.lines) operstate `elem` ["up", "unknown"] readNetDev :: [String] -> IO NetDevRawTotal readNetDev (d:x:y:_) = do |