// Copyright (C) 2023-2024 Umorpha Systems // SPDX-License-Identifier: AGPL-3.0-or-later package main import ( "fmt" "net" "os" "strconv" "strings" sd "git.lukeshu.com/go/libsystemd/sd_daemon" ) // netListen is like [net.Listen], but with support for our special // "fd" address family. // // The purpose of doing this is that for development I really want to // be able to have it listen on a TCP port, but for actual deployment // I want it to be able to accept an already-opened socket from // systemd, and so I wrote a reasonably genereral solution. // // Did I avoid unnecessary complexity writing special-purpose code, or // did I introduce it by failing to remember that YAGNI? func netListen(stype, saddr string) (net.Listener, error) { switch stype { case "fd": switch saddr { case "stdin", "0": return net.FileListener(os.Stdin) case "stdout", "1": return net.FileListener(os.Stdout) case "stderr", "2": return net.FileListener(os.Stderr) case "systemd": sdFds := sd.ListenFds(true) if len(sdFds) == 0 { return nil, fmt.Errorf("fd:systemd given, but no systemd file descriptors passed in") } return net.FileListener(sdFds[0]) default: if fd, _ := strconv.Atoi(saddr); fd > 0 { return net.FileListener(os.NewFile(uintptr(fd), fmt.Sprintf("/dev/fd/%d", fd))) } if name, ok := strings.CutPrefix(saddr, "systemd:"); ok { sdFiles := sd.ListenFds(true) for _, file := range sdFiles { if file.Name() == name { return net.FileListener(file) } } if n, err := strconv.Atoi(name); err == nil && n >= 0 && n < len(sdFiles) { return net.FileListener(sdFiles[n]) } return nil, fmt.Errorf("does not match any systemd file descriptor: %q", name) } return nil, fmt.Errorf("invalid file descriptor name: %q", saddr) } default: return net.Listen(stype, saddr) } }