0

I was writing an runit service to restart picom on unlock based on this answer https://unix.stackexchange.com/a/439492/161514

#!/bin/bash

OBJECT_PATH=/org/freedesktop/login1/session/$XDG_SESSION_ID BUS_NAME=org.freedesktop.login1 UNLOCK="$OBJECT_PATH: $BUS_NAME.Session.Unlock ()" MONITOR_COMMAND="gdbus monitor --system --dest $BUS_NAME --object-path $OBJECT_PATH"

log () { echo "$(date +'%F %T.%3N') [$$]" "$@" }

while read -r signal; do log $signal if [ "$signal" = "$UNLOCK" ]; then log "Restaring picom after unlock." SVDIR=$XDG_SERVICE_HOME sv restart picom fi done < <(exec $MONITOR_COMMAND)

The issue with this is that when I stop the service the gdbus process won't get killed. I can guess that it's because there will be two processes the script itself and then the gdbus and the service stop will only stop the script not gdbus.

My question is can I rewrite this service in some way to achieve what I want so that stopping the service the gdbus monitoring also stops?

1 Answers1

0

Well after searching quite a bit, I realized this is a general problem not specific to runit. I can run the monitoring as an async process with coproc and ensure in my main script that in case of any term signals I will kill my child process.

Here's the script in case anyone's interested

#!/usr/bin/env bash

OBJECT_PATH=/org/freedesktop/login1/session/$XDG_SESSION_ID BUS_NAME=org.freedesktop.login1 UNLOCK="$OBJECT_PATH: $BUS_NAME.Session.Unlock ()" MONITOR_COMMAND="gdbus monitor --system --dest $BUS_NAME --object-path $OBJECT_PATH"

log () { echo "$(date +'%F %T.%3N') [$$]" "$@" }

cleanup() { # kill all processes whose parent is this process pkill -P $$ }

for sig in INT QUIT HUP TERM; do trap " cleanup trap - $sig EXIT kill -s $sig "'"$$"' "$sig" done

coproc $MONITOR_COMMAND

while read -r signal <&"${COPROC[0]}"; do log $signal if [ "$signal" = "$UNLOCK" ]; then log "Restaring picom after unlock." SVDIR=$XDG_SERVICE_HOME sv restart picom fi done

trap cleanup EXIT