github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/internal/wasitest/testdata/tcpecho.go (about) 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 5 package main 6 7 import ( 8 "errors" 9 "net" 10 "os" 11 "syscall" 12 ) 13 14 func main() { 15 if err := run(); err != nil { 16 println(err) 17 os.Exit(1) 18 } 19 } 20 21 func 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 38 func 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 55 func 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 }