//go:build linux package control import ( "context" "log/slog" "net" "os" "time" ) // sockPath lives in the unit's RuntimeDirectory; mode 0666 lets every // local user ask, nothing can reach it from off the machine. const sockPath = "/run/gpu-turnstile/control.sock" // Serve starts the socket listener in the background and returns; only a // setup failure is reported. Each client connection is answered in its own // goroutine. func Serve(ctx context.Context, h Handler, log *slog.Logger) error { os.Remove(sockPath) // stale socket from a previous run ln, err := net.Listen("unix", sockPath) if err != nil { return err } if err := os.Chmod(sockPath, 0o666); err != nil { ln.Close() return err } go func() { <-ctx.Done() ln.Close() }() go func() { for { c, err := ln.Accept() if err != nil { return // shutting down } go serveConn(c, h) } }() return nil } // Ask sends one command to the running service and returns its reply. func Ask(cmd string) (string, error) { c, err := net.DialTimeout("unix", sockPath, 2*time.Second) if err != nil { return "", ErrUnavailable } defer c.Close() return readReply(c, cmd) }