1 package main 2 3 import ( 4 "context" 5 "errors" 6 "flag" 7 "fmt" 8 "net/http" 9 "os" 10 "os/signal" 11 ) 12 13 func main() { 14 if err := run(); err != nil { 15 fmt.Fprintf(os.Stderr, "error: %s", err) 16 } 17 } 18 19 func run() error { 20 p := flag.Uint("p", 8080, "server port") 21 flag.Parse() 22 l, err := Listen("tcp", fmt.Sprintf(":%d", *p)) 23 if err != nil { 24 return fmt.Errorf("unable to open port %d: %w", *p, err) 25 } 26 server := &http.Server{ 27 Handler: http.DefaultServeMux, 28 } 29 30 errc := make(chan error) 31 go func() { 32 if err := server.Serve(l); err != nil && !errors.Is(err, http.ErrServerClosed) { 33 errc <- err 34 } else { 35 errc <- nil 36 } 37 }() 38 39 sc := make(chan os.Signal, 1) 40 signal.Notify(sc, os.Interrupt) 41 <-sc 42 signal.Stop(sc) 43 close(sc) 44 45 server.Shutdown(context.Background()) 46 return <-errc 47 } 48