//go:build linux package http import ( "fmt" "net" "os" "strconv" ) func getSystemdListeners() (Listeners, error) { pidStr := os.Getenv("LISTEN_PID") fdStr := os.Getenv("LISTEN_FDS") if pidStr == "" || fdStr == "" { return nil, nil // Not running under systemd } pid, err := strconv.Atoi(pidStr) if err != nil { // Not our activation — another process might have inherited the env. return nil, nil } if pid != os.Getpid() { return nil, fmt.Errorf("LISTEN_PID %d does not match current PID %d", pid, os.Getpid()) } defer func() { _ = os.Unsetenv("LISTEN_PID") _ = os.Unsetenv("LISTEN_FDS") }() nfds, err := strconv.ParseUint(fdStr, 10, 64) if err != nil { return nil, fmt.Errorf("invalid LISTEN_FDS: %w", err) } if nfds == 0 { return nil, nil // Nothing to do } lns := make(Listeners, 0, nfds) for i := range nfds { fd := i + 3 file := os.NewFile(uintptr(fd), fmt.Sprintf("fd_%d", fd)) if file == nil { return nil, fmt.Errorf("fd %d was nil", fd) } ln, err := net.FileListener(file) if err != nil { file.Close() return nil, fmt.Errorf("failed to create listener from fd %d: %w", fd, err) } lns = append(lns, ln) } return lns, nil }