run: make launcher ownership explicit

This commit is contained in:
2026-08-14 02:43:42 +09:00
parent 05ff88c74f
commit 6a2b2bccc4
3 changed files with 201 additions and 14 deletions

View File

@@ -118,7 +118,20 @@ absent or invalid, the popup disables itself cleanly while input processing
continues. `run.sh` and `bench.sh` accept the same font-file arguments. continues. `run.sh` and `bench.sh` accept the same font-file arguments.
When `run.sh` is invoked without arguments, it uses the installed DejaVu, When `run.sh` is invoked without arguments, it uses the installed DejaVu,
Jigmo, or Noto CJK font files from the standard Arch Linux paths. Explicit Jigmo, or Noto CJK font files from the standard Arch Linux paths. Explicit
font-file arguments replace these defaults. font-file arguments replace these defaults:
```sh
./run.sh
./run.sh /path/to/primary.ttf /path/to/fallback.ttc
```
`run.sh` remains in the foreground and owns only the daemon and XIM process
that it starts. It waits for that daemon's IPC socket and IBus address file
before reporting success. With `DISPLAY` set it then starts XIM; without a
display it keeps the headless daemon in the foreground and does not start
XIM. A signal or XIM exit stops and reaps the launcher's daemon. The
launcher never replaces an existing daemon: an occupied per-user socket is a
visible startup failure.
The IPC socket is placed at `$XDG_RUNTIME_DIR/strans.sock` when The IPC socket is placed at `$XDG_RUNTIME_DIR/strans.sock` when
`XDG_RUNTIME_DIR` is an absolute path. Otherwise strans uses the per-user `XDG_RUNTIME_DIR` is an absolute path. Otherwise strans uses the per-user

View File

@@ -2,30 +2,97 @@
set -eu set -eu
cd "$(dirname "$0")" cd "$(dirname "$0")" || exit 1
case ${XDG_RUNTIME_DIR-} in
/) ipc=/strans.sock ;;
/*/) ipc=${XDG_RUNTIME_DIR}strans.sock ;;
/*) ipc=${XDG_RUNTIME_DIR}/strans.sock ;;
*) ipc=/tmp/strans.$(id -u) ;;
esac
if test -n "${XDG_CONFIG_HOME-}"; then
busdir=$XDG_CONFIG_HOME/ibus/bus
elif test "${HOME+x}" = x; then
busdir=$HOME/.config/ibus/bus
else
echo "bench.sh: HOME or XDG_CONFIG_HOME is required for IBus discovery" >&2
exit 1
fi
strans_pid= strans_pid=
perf_pid= perf_pid=
cleanup() cleanup()
{ {
status=$?
trap - 0 1 2 15 trap - 0 1 2 15
if test -n "$perf_pid"; then if test -n "$perf_pid"; then
kill -INT "$perf_pid" 2>/dev/null || true kill -INT "$perf_pid" 2>/dev/null || :
wait "$perf_pid" 2>/dev/null || true wait "$perf_pid" 2>/dev/null || :
perf_pid=
fi fi
if test -n "$strans_pid"; then if test -n "$strans_pid"; then
kill "$strans_pid" 2>/dev/null || true kill "$strans_pid" 2>/dev/null || :
wait "$strans_pid" 2>/dev/null || true wait "$strans_pid" 2>/dev/null || :
strans_pid=
fi fi
exit "$status"
} }
trap cleanup 0 1 2 15 ibusready()
{
for address in "$busdir"/*; do
test -f "$address" || continue
foundpid=
foundaddress=
while IFS= read -r line; do
case $line in
IBUS_DAEMON_PID="$strans_pid") foundpid=1 ;;
IBUS_ADDRESS=unix:abstract=strans-"$strans_pid",*) foundaddress=1 ;;
esac
done <"$address"
if test -n "$foundpid" && test -n "$foundaddress"; then
return 0
fi
done
return 1
}
trap cleanup 0
trap 'exit 129' 1
trap 'exit 130' 2
trap 'exit 143' 15
./strans map "$@" & ./strans map "$@" &
strans_pid=$! strans_pid=$!
sleep 1
kill -0 "$strans_pid" attempt=0
while test "$attempt" -lt 10; do
if test -S "$ipc" && ibusready; then
break
fi
if ! kill -0 "$strans_pid" 2>/dev/null; then
if wait "$strans_pid"; then
status=0
else
status=$?
fi
strans_pid=
if test "$status" -eq 0; then
status=1
fi
echo "bench.sh: daemon exited before publishing IPC and IBus endpoints" >&2
exit "$status"
fi
attempt=$((attempt + 1))
if test "$attempt" -lt 10; then
sleep 1
fi
done
if test "$attempt" -eq 10; then
echo "bench.sh: daemon did not publish IPC and IBus endpoints within 10 seconds" >&2
exit 1
fi
# warm up the renderer # warm up the renderer
./bench/bench bench/bench.keys 100 ./bench/bench bench/bench.keys 100
@@ -39,5 +106,5 @@ kill -0 "$perf_pid"
./bench/bench bench/bench.keys 100 ./bench/bench bench/bench.keys 100
kill -INT "$perf_pid" kill -INT "$perf_pid"
wait "$perf_pid" 2>/dev/null || true wait "$perf_pid" 2>/dev/null || :
perf_pid= perf_pid=

115
run.sh
View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
cd "$(dirname "$0")" cd "$(dirname "$0")" || exit 1
if test "$#" -eq 0; then if test "$#" -eq 0; then
set -- set --
@@ -20,8 +20,115 @@ if test "$#" -eq 0; then
fi fi
fi fi
pkill strans if ! test -x ./strans; then
sleep 1 echo "run.sh: ./strans is not executable; run make first" >&2
exit 1
fi
if test -n "${DISPLAY-}" && ! test -x xim/strans-xim; then
echo "run.sh: xim/strans-xim is not executable; run make first" >&2
exit 1
fi
case ${XDG_RUNTIME_DIR-} in
/) ipc=/strans.sock ;;
/*/) ipc=${XDG_RUNTIME_DIR}strans.sock ;;
/*) ipc=${XDG_RUNTIME_DIR}/strans.sock ;;
*) ipc=/tmp/strans.$(id -u) ;;
esac
if test -n "${XDG_CONFIG_HOME-}"; then
busdir=$XDG_CONFIG_HOME/ibus/bus
elif test "${HOME+x}" = x; then
busdir=$HOME/.config/ibus/bus
else
echo "run.sh: HOME or XDG_CONFIG_HOME is required for IBus discovery" >&2
exit 1
fi
strans_pid=
xim_pid=
cleanup()
{
status=$?
trap - 0 1 2 15
if test -n "$xim_pid"; then
kill "$xim_pid" 2>/dev/null || :
wait "$xim_pid" 2>/dev/null || :
xim_pid=
fi
if test -n "$strans_pid"; then
kill "$strans_pid" 2>/dev/null || :
wait "$strans_pid" 2>/dev/null || :
strans_pid=
fi
exit "$status"
}
ibusready()
{
for address in "$busdir"/*; do
test -f "$address" || continue
foundpid=
foundaddress=
while IFS= read -r line; do
case $line in
IBUS_DAEMON_PID="$strans_pid") foundpid=1 ;;
IBUS_ADDRESS=unix:abstract=strans-"$strans_pid",*) foundaddress=1 ;;
esac
done <"$address"
if test -n "$foundpid" && test -n "$foundaddress"; then
return 0
fi
done
return 1
}
trap cleanup 0
trap 'exit 129' 1
trap 'exit 130' 2
trap 'exit 143' 15
./strans map "$@" & ./strans map "$@" &
sleep 1 strans_pid=$!
attempt=0
while test "$attempt" -lt 10; do
if test -S "$ipc" && ibusready; then
break
fi
if ! kill -0 "$strans_pid" 2>/dev/null; then
wait "$strans_pid"
status=$?
strans_pid=
if test "$status" -eq 0; then
status=1
fi
echo "run.sh: daemon exited before publishing IPC and IBus endpoints" >&2
exit "$status"
fi
attempt=$((attempt + 1))
if test "$attempt" -lt 10; then
sleep 1
fi
done
if test "$attempt" -eq 10; then
echo "run.sh: daemon did not publish IPC and IBus endpoints within 10 seconds" >&2
exit 1
fi
echo "run.sh: daemon $strans_pid is ready"
if test -z "${DISPLAY-}"; then
echo "run.sh: DISPLAY is unset; XIM will not be started"
wait "$strans_pid"
status=$?
strans_pid=
exit "$status"
fi
xim/strans-xim & xim/strans-xim &
xim_pid=$!
echo "run.sh: started XIM $xim_pid; press Ctrl-C to stop both processes"
wait "$xim_pid"
status=$?
xim_pid=
exit "$status"