summaryrefslogtreecommitdiffhomepage
path: root/src/Xmobar
diff options
context:
space:
mode:
authorLéana 江 <leana.jiang+git@icloud.com>2026-06-16 15:54:22 +0200
committerLéana 江 <leana.jiang+git@icloud.com>2026-06-26 21:59:27 +0200
commit5513b9100728c08789fb19d8cfc314a2c8dab876 (patch)
treeb91429dd95e94057e6cefe6495c362149929ca32 /src/Xmobar
parentd36cd2d0369efa6d32948d0713fe79a72ec5fbeb (diff)
downloadxmobar-5513b9100728c08789fb19d8cfc314a2c8dab876.tar.gz
xmobar-5513b9100728c08789fb19d8cfc314a2c8dab876.tar.bz2
remove " &" and fix zombie processes
" &" was to avoid throwing an exception when the child process has a non-empty exitcode. However, the error-throwing function is callCommand and not spawnCommand, so removing " &" shouldn't change the semantic. https://codeberg.org/xmobar/xmobar/pulls/698#issuecomment-1722323 > callCommand seems to be the closest new function to system, but there > is a difference: it raises an exception if the child process has a > non-zero exit code. To preserve the exact behavior would require > something like spawnCommand (s + "&") >>= waitForProcess. I was able to reproduce zombie processes with the following steps: + running my own xmobar configuration + spawning a command that is long running (sleep 10) + sending SIGTERM to the xmobar process After doing so, the sleep command will continue to run. This PR uses withCreateProcess, which will always wait for the process to terminate, even when the main thread is asked to exit (SIGTERM). Note that SIGKILL is not expected to terminate the children.
Diffstat (limited to 'src/Xmobar')
-rw-r--r--src/Xmobar/Plugins/Monitors/Batt/Common.hs9
-rw-r--r--src/Xmobar/Run/Actions.hs7
2 files changed, 8 insertions, 8 deletions
diff --git a/src/Xmobar/Plugins/Monitors/Batt/Common.hs b/src/Xmobar/Plugins/Monitors/Batt/Common.hs
index 2c60155..31caabc 100644
--- a/src/Xmobar/Plugins/Monitors/Batt/Common.hs
+++ b/src/Xmobar/Plugins/Monitors/Batt/Common.hs
@@ -20,7 +20,7 @@ module Xmobar.Plugins.Monitors.Batt.Common (BattOpts(..)
, maybeAlert) where
import System.Environment
-import System.Process (waitForProcess, createProcess_, shell, CreateProcess(env))
+import System.Process (waitForProcess, withCreateProcess, shell, CreateProcess(env))
import Control.Monad (unless, void)
import Xmobar.Plugins.Monitors.Common
@@ -60,8 +60,7 @@ maybeAlert opts left =
where
mkShellCmd command = do
selfEnv <- getEnvironment
- pure (shell command) { env = Just $ [("XMOBAR_BATT_LEFT", show @Int $ round $ 100 * left)] ++ selfEnv
+ pure (shell command) { env = Just $ ("XMOBAR_BATT_LEFT", show @Int $ round $ 100 * left) : selfEnv
}
- runCmd c = do
- (_,_,_,p) <- createProcess_ "maybeAlert" c
- void $ waitForProcess p
+ runCmd c = withCreateProcess c $ \_ _ _ ph ->
+ void $ waitForProcess ph
diff --git a/src/Xmobar/Run/Actions.hs b/src/Xmobar/Run/Actions.hs
index cbc10c5..a9afed9 100644
--- a/src/Xmobar/Run/Actions.hs
+++ b/src/Xmobar/Run/Actions.hs
@@ -16,7 +16,7 @@ module Xmobar.Run.Actions ( Button
, runAction'
, stripActions) where
-import System.Process (spawnCommand, waitForProcess)
+import System.Process (shell, withCreateProcess, waitForProcess)
import Control.Monad (void)
import Text.Regex (Regex, subRegex, mkRegex, matchRegex)
import Data.Word (Word32)
@@ -26,11 +26,12 @@ type Button = Word32
data Action = Spawn [Button] String deriving (Eq, Read, Show)
runAction :: Action -> IO ()
-runAction (Spawn _ s) = void $ spawnCommand (s ++ " &") >>= waitForProcess
+runAction (Spawn _ s) = withCreateProcess (shell s) $ \_ _ _ ph ->
+ void $ waitForProcess ph
-- | Run action with stdout redirected to stderr
runAction' :: Action -> IO ()
-runAction' (Spawn _ s) = void $ spawnCommand (s ++ " 1>&2 &") >>= waitForProcess
+runAction' (Spawn btn s) = runAction (Spawn btn (s ++ " 1>&2"))
stripActions :: String -> String
stripActions s = case matchRegex actionRegex s of