@@ 1,13 1,14 @@
package main
import (
- "fmt"
"context"
+ "fmt"
"log"
"os/user"
- "github.com/godbus/dbus/v5"
+ "github.com/coreos/go-systemd/v22/daemon"
systemd "github.com/coreos/go-systemd/v22/dbus"
+ "github.com/godbus/dbus/v5"
)
func StartSystemdUserUnit(unitName string) error {
@@ 30,7 31,6 @@ func ListenForSleep() {
if err != nil {
log.Fatalln("Could not connect to the system D-Bus", err)
}
- defer conn.Close()
err = conn.AddMatchSignal(
dbus.WithMatchObjectPath("/org/freedesktop/login1"),
@@ 42,16 42,21 @@ func ListenForSleep() {
}
c := make(chan *dbus.Signal, 10)
- conn.Signal(c)
- for {
- <-c
- log.Println("The system is going to sleep")
- err = StartSystemdUserUnit("sleep.target")
- if err != nil {
- log.Println("Error starting sleep.target:", err)
+ go func() {
+ for {
+ <-c
+ log.Println("The system is going to sleep")
+
+ err = StartSystemdUserUnit("sleep.target")
+ if err != nil {
+ log.Println("Error starting sleep.target:", err)
+ }
}
- }
+ }()
+
+ conn.Signal(c)
+ log.Println("Listening for sleep events...")
}
func ListenForLock(user *user.User) {
@@ 59,7 64,6 @@ func ListenForLock(user *user.User) {
if err != nil {
log.Fatalln("Could not connect to the system D-Bus", err)
}
- defer conn.Close()
err = conn.AddMatchSignal(
dbus.WithMatchInterface("org.freedesktop.login1.Session"),
@@ 71,30 75,34 @@ func ListenForLock(user *user.User) {
}
c := make(chan *dbus.Signal, 10)
- conn.Signal(c)
- for {
- v := <-c
-
- // Get the locked session...
- obj := conn.Object("org.freedesktop.login1", v.Path)
-
- name, err := obj.GetProperty("org.freedesktop.login1.Session.Name")
- if err != nil {
- log.Println("WARNING: Could not obtain details for locked session:", err)
- continue
- }
-
- // ... And check that it belongs to the current user:
- if name.Value() != user.Username {
- continue
+ go func() {
+ for {
+ v := <-c
+
+ // Get the locked session...
+ obj := conn.Object("org.freedesktop.login1", v.Path)
+
+ name, err := obj.GetProperty("org.freedesktop.login1.Session.Name")
+ if err != nil {
+ log.Println("WARNING: Could not obtain details for locked session:", err)
+ continue
+ }
+
+ // ... And check that it belongs to the current user:
+ if name.Value() != user.Username {
+ continue
+ }
+ log.Println("Session locked for current user.")
+
+ err = StartSystemdUserUnit("lock.target")
+ if err != nil {
+ log.Println("Error starting lock.target:", err)
+ }
}
- log.Println("Session locked for current user.")
+ }()
- err = StartSystemdUserUnit("lock.target")
- if err != nil {
- log.Println("Error starting lock.target:", err)
- }
- }
+ conn.Signal(c)
+ log.Println("Listening for lock events...")
}
func main() {
@@ 106,8 114,18 @@ func main() {
}
log.Println("Running for user:", user.Username)
- go ListenForSleep()
- go ListenForLock(user)
+ ListenForSleep()
+ ListenForLock(user)
+
+ log.Println("Initialization complete.")
+
+ sent, err := daemon.SdNotify(true, daemon.SdNotifyReady)
+ if !sent {
+ log.Println("Couldn't call sd_notify. Not running via systemd?")
+ }
+ if err != nil {
+ log.Println("Call to sd_notify failed:", err)
+ }
select {}
}
@@ 4,6 4,7 @@ Documentation=https://sr.ht/~whynothugo/systemd-lock-handler
[Service]
ExecStart=/usr/lib/systemd-lock-handler
+Type=notify
[Install]
WantedBy=default.target