forked from robustirc/bridge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsocket_activation.go
77 lines (70 loc) · 1.77 KB
/
socket_activation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//go:build !windows
// +build !windows
package main
import (
"context"
"log"
"net"
"os"
"strconv"
"strings"
"sync"
"syscall"
"time"
)
// nfds returns the number of listening file descriptors as passed by systemd
// when this application is started using systemd socket activation.
func nfds() int {
pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
if err != nil || pid != os.Getpid() {
return 0
}
n, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
if err != nil {
return 0
}
return n
}
// handleSocketActivation handles listening on the systemd-provided sockets.
// It can return an error to differentiate between this implementation and
// the no-op on Windows.
func handleSocketActivation(ctx context.Context, n int, connWG *sync.WaitGroup) error {
names := strings.Split(os.Getenv("LISTEN_FDNAMES"), ":")
os.Unsetenv("LISTEN_PID")
os.Unsetenv("LISTEN_FDS")
os.Unsetenv("LISTEN_FDNAMES")
p := newBridge(*network)
const listenFdsStart = 3 // SD_LISTEN_FDS_START
for fd := listenFdsStart; fd < listenFdsStart+n; fd++ {
syscall.CloseOnExec(fd)
name := "LISTEN_FD_" + strconv.Itoa(fd)
offset := fd - listenFdsStart
if offset < len(names) && len(names[offset]) > 0 {
name = names[offset]
}
log.Printf("RobustIRC IRC bridge listening on file descriptor %d (%s)", fd, name)
f := os.NewFile(uintptr(fd), name)
ln, err := net.FileListener(f)
if err != nil {
log.Fatal(err)
}
f.Close()
go func() {
for {
conn, err := ln.Accept()
if err != nil {
log.Printf("Could not accept IRC client connection: %v\n", err)
// Avoid flooding the logs with failed Accept()s.
time.Sleep(1 * time.Second)
continue
}
connWG.Add(1)
go func() {
defer connWG.Done()
p.handleIRC(ctx, conn)
}()
}
}()
}
return nil
}