Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ body:
attributes:
label: Fiero-Hotspot version
description: Output of `fiero-hotspot version`
placeholder: fiero-hotspot v2.1.2
placeholder: fiero-hotspot v2.1.3
validations:
required: true
- type: input
Expand Down
7 changes: 6 additions & 1 deletion 99-fiero-hotspot.rules
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# NOTE: @TARGET_USER@ is dynamically replaced by install.sh during installation.
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains|USB", RUN+="/usr/bin/systemd-run --no-block --collect -- /usr/bin/su @TARGET_USER@ -c /usr/local/bin/fiero-prompt"
# KillMode=process is required: systemd-run creates a transient *service* unit,
# whose default KillMode=control-group SIGTERMs every remaining process in the
# cgroup once `su` exits. `setsid --fork` detaches fiero-prompt watch from the
# session but not from the cgroup, so without this the watcher is killed before
# the daemon emits STARTING/LIVE and lifecycle notifications never appear.
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains|USB", RUN+="/usr/bin/systemd-run --no-block --collect --property=KillMode=process -- /usr/bin/su @TARGET_USER@ -c /usr/local/bin/fiero-prompt"
# END OF FILE
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ All notable changes to this project are documented here. The format is based on

## [Unreleased]

## [2.1.3] - 2026-09-28

### Fixed
- Fixed missing `STARTING` and `LIVE` desktop notifications by adding `--property=KillMode=process` to the udev `systemd-run` rule. Prevents systemd control-group teardown from terminating the detached `fiero-prompt watch` process when the prompt script exits.

## [2.1.2] - 2026-09-28

### Changed
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Fiero-Hotspot

![Version](https://img.shields.io/badge/version-v2.1.2-blue)
![Version](https://img.shields.io/badge/version-v2.1.3-blue)
![License](https://img.shields.io/badge/license-GPL--3.0-green)
[![CI](https://github.com/Fiero1186/Fiero-Hotspot/actions/workflows/ci.yml/badge.svg)](https://github.com/Fiero1186/Fiero-Hotspot/actions/workflows/ci.yml)

Expand Down Expand Up @@ -84,7 +84,7 @@ The upstream Wi-Fi connection must be managed by NetworkManager. The daemon uses
```
udev event (AC online/offline)
└─> 99-fiero-hotspot.rules
└─> systemd-run --no-block --collect -- su - <user> -c /usr/local/bin/fiero-prompt
└─> systemd-run --no-block --collect --property=KillMode=process -- su <user> -c /usr/local/bin/fiero-prompt
├─> setsid --fork fiero-prompt watch (detached event watcher, one per session)
└─> sudo -n systemctl start/stop fiero-hotspot.service
└─> /usr/local/bin/fiero-hotspot {start|stop}
Expand All @@ -95,7 +95,7 @@ udev event (AC online/offline)
└─> notify-send (as the logged-in user)
```

The udev rule fires on any `power_supply` `change` event where `ATTR{type}=="Mains"` and `ATTR{online}` is `1` (plugged) or `0` (unplugged). This invokes `fiero-prompt.sh` as the logged-in user via `systemd-run` + `su` (so udev does not kill the long-running prompt), which presents a desktop notification action prompt and issues `sudo -n systemctl start|stop` accordingly. The first prompt run also spawns a detached, flock-serialized event watcher (`fiero-prompt watch`) that stays alive for the session.
The udev rule fires on any `power_supply` `change` event where `ATTR{type}=="Mains"` and `ATTR{online}` is `1` (plugged) or `0` (unplugged). This invokes `fiero-prompt.sh` as the logged-in user via `systemd-run` + `su` (so udev does not kill the long-running prompt), which presents a desktop notification action prompt and issues `sudo -n systemctl start|stop` accordingly. The first prompt run also spawns a detached, flock-serialized event watcher (`fiero-prompt watch`) that stays alive for the session. That watcher is a child of the transient unit, and `setsid` severs the session but **not** the cgroup, so the rule pins `KillMode=process`: the default `control-group` would SIGTERM the whole cgroup — watcher included — the moment `su` exits, silently dropping every `STARTING`/`LIVE` notification. The transient unit then lingers `inactive` for as long as the watcher runs.

### Signal Handling

Expand Down
2 changes: 1 addition & 1 deletion fiero-hotspot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set -u
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH

VERSION="2.1.2"
VERSION="2.1.3"

CONFIG_FILE="/etc/fiero-hotspot.conf"
LOCK_FILE="/run/fiero-hotspot.lock"
Expand Down
10 changes: 10 additions & 0 deletions tests/install.bats
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ install_as_tester() {
[ -x /usr/local/bin/fiero-hotspot ]
}

@test "the udev rule keeps the event watcher alive past the transient unit" {
# systemd-run builds a transient service unit whose default KillMode is
# control-group, so the setsid'd fiero-prompt watch child is SIGTERMed with
# the unit. The rule must pin KillMode=process or STARTING/LIVE
# notifications never arrive.
run install_as_tester "$ANSWERS"
[ "$status" -eq 0 ]
grep -q -- '--property=KillMode=process' /etc/udev/rules.d/99-fiero-hotspot.rules
}

@test "answering no to both timeout questions disables both fallbacks" {
run install_as_tester 'My Hotspot\ngoodpass123\ngoodpass123\n\nn\nn\n'
[ "$status" -eq 0 ]
Expand Down