diff options
Diffstat (limited to 'example/main.go')
| -rw-r--r-- | example/main.go | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/example/main.go b/example/main.go new file mode 100644 index 0000000..66eace2 --- /dev/null +++ b/example/main.go @@ -0,0 +1,125 @@ +// This implements a simple example that can be tested on a machine +// running systemd. +package main + +import ( + "bufio" + "flag" + "fmt" + "log" + "net" + "os" + "os/signal" + "strings" + "sync" + + "golang.org/x/sys/unix" + + "go.awhk.org/gosdd" +) + +var useNames = flag.Bool("use-names", false, "whether to use SDListenFDsWithNames or not") + +func main() { + flag.Parse() + log.SetFlags(log.Lshortfile) + + if !*useNames { + fds, err := gosdd.SDListenFDs(true) + if err != nil { + log.Fatalln(err) + } + log.Printf("Received %d file descriptors from systemd.", len(fds)) + listenAll(fds) + return + } + + namedFDs, err := gosdd.SDListenFDsWithNames(true) + if err != nil { + log.Fatalln(err) + } + log.Printf("Received %d named file descriptors from systemd.", len(namedFDs)) + fds := make([]*os.File, 0, len(namedFDs)) + for name, fd := range namedFDs { + log.Printf("Adding %q.", name) + fds = append(fds, fd) + } + listenAll(fds) +} + +func listenAll(fds []*os.File) { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, unix.SIGTERM) + + srvs := make([]echoServer, 0, len(fds)) + wg := &sync.WaitGroup{} + for _, fd := range fds { + ln, err := net.FileListener(fd) + if err != nil { + log.Printf("Failed to make a listener: %s.", err) + continue + } + srv := echoServer{ln, wg} + srvs = append(srvs, srv) + go srv.start() + } + + <-sig + for _, srv := range srvs { + srv.stop() + } + wg.Wait() +} + +type echoServer struct { + ln net.Listener + wg *sync.WaitGroup +} + +func (*echoServer) handle(conn net.Conn) { + defer func() { + if err := conn.Close(); err != nil { + log.Println(err) + } + }() + + log.Printf("New connection, local address is %s, remote address is %s.", conn.LocalAddr(), conn.RemoteAddr()) + if _, err := fmt.Fprintln(conn, "Hello World!"); err != nil { + log.Println(err) + return + } + r := bufio.NewReader(conn) + for { + s, err := r.ReadString('\n') + if err != nil { + log.Println(err) + return + } + s = strings.Trim(s, "\n ") + log.Printf("Received %q.", s) + if _, err := fmt.Fprintf(conn, "You said %q!\n", s); err != nil { + log.Println(err) + return + } + } +} + +func (srv *echoServer) start() { + defer srv.wg.Done() + srv.wg.Add(1) + + for { + conn, err := srv.ln.Accept() + if err != nil { + log.Println(err) + return + } + go srv.handle(conn) + } +} + +func (srv *echoServer) stop() { + if err := srv.ln.Close(); err != nil { + log.Println(err) + } +} |
