eclipse/cmd/eclipse-httpd/net.go

64 lines
1.8 KiB
Go
Raw Permalink Normal View History

2024-01-17 21:52:40 +00:00
// 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)
}
}