1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7import (
8	"errors"
9	"net"
10	"os"
11	"syscall"
12)
13
14func main() {
15	if err := run(); err != nil {
16		println(err)
17		os.Exit(1)
18	}
19}
20
21func run() error {
22	l, err := findListener()
23	if err != nil {
24		return err
25	}
26	if l == nil {
27		return errors.New("no pre-opened sockets available")
28	}
29	defer l.Close()
30
31	c, err := l.Accept()
32	if err != nil {
33		return err
34	}
35	return handleConn(c)
36}
37
38func handleConn(c net.Conn) error {
39	defer c.Close()
40
41	var buf [128]byte
42	n, err := c.Read(buf[:])
43	if err != nil {
44		return err
45	}
46	if _, err := c.Write(buf[:n]); err != nil {
47		return err
48	}
49	if err := c.(*net.TCPConn).CloseWrite(); err != nil {
50		return err
51	}
52	return c.Close()
53}
54
55func findListener() (net.Listener, error) {
56	// We start looking for pre-opened sockets at fd=3 because 0, 1, and 2
57	// are reserved for stdio. Pre-opened directors also start at fd=3, so
58	// we skip fds that aren't sockets. Once we reach EBADF we know there
59	// are no more pre-opens.
60	for preopenFd := uintptr(3); ; preopenFd++ {
61		f := os.NewFile(preopenFd, "")
62		l, err := net.FileListener(f)
63		f.Close()
64
65		var se syscall.Errno
66		switch errors.As(err, &se); se {
67		case syscall.ENOTSOCK:
68			continue
69		case syscall.EBADF:
70			err = nil
71		}
72		return l, err
73	}
74}
75