// SPDX-License-Identifier: GPL-3.0-or-later // Package sdnotify implements the small systemd notification subset needed by // the service binary without adding a runtime dependency. package sdnotify import ( "fmt" "net" "os" "strings" ) // Notifier sends state records to the socket inherited from systemd. An empty // socket makes Notify a no-op so the agent behaves identically outside a unit. type Notifier struct { socket string } // FromEnvironment returns a notifier for systemd's NOTIFY_SOCKET contract. func FromEnvironment() Notifier { return New(os.Getenv("NOTIFY_SOCKET")) } // New constructs a notifier for an explicit socket, primarily for tests. func New(socket string) Notifier { return Notifier{socket: socket} } // Notify sends one newline-delimited systemd state record. func (n Notifier) Notify(state string) error { if n.socket == "" { return nil } if state == "" || strings.ContainsRune(state, '\x00') { return fmt.Errorf("invalid empty or NUL-containing notification") } connection, err := net.DialUnix( "unixgram", nil, &net.UnixAddr{Name: n.socket, Net: "unixgram"}, ) if err != nil { return fmt.Errorf("connect notify socket: %w", err) } defer connection.Close() if _, err := connection.Write([]byte(state)); err != nil { return fmt.Errorf("write notify socket: %w", err) } return nil }