summaryrefslogtreecommitdiffhomepage
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
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.
-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