summaryrefslogtreecommitdiffhomepage
path: root/src/Plugins/Monitors/Net.hs
diff options
context:
space:
mode:
authorTomas Janousek <tomi@nomi.cz>2017-11-04 20:07:30 +0100
committerTomas Janousek <tomi@nomi.cz>2018-04-05 10:45:19 +0200
commit3b88faefe7a2a512ebf2dcde4f3cdb3e89b98393 (patch)
tree8c6b4694c3c70e3b5f2d886e9558b734cb69cd34 /src/Plugins/Monitors/Net.hs
parent40fd9dfe82a734057640b4495ed5d8d93531c4fc (diff)
downloadxmobar-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.
Diffstat (limited to 'src/Plugins/Monitors/Net.hs')
-rw-r--r--src/Plugins/Monitors/Net.hs5
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