func (srv *Server) socketListen() error { var la *net.TCPAddr var err error if la, err = net.ResolveTCPAddr("tcp", srv.Addr); err != nil { return err } var l *net.TCPListener if l, err = net.ListenTCP("tcp", la); err != nil { return err } srv.listener = l // setup listener to be non-blocking if we're not on windows. // this is required for hot restart to work. if runtime.GOOS != "windows" { if srv.listenerFile, err = l.File(); err != nil { return err } fd := int(srv.listenerFile.Fd()) if e := setupFDNonblock(fd); e != nil { return e } if srv.sendfile { if e := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, srv.sockOpt, 1); e != nil { return e } } } return nil }
// Re-exec this image without dropping the listener passed to this function. func Relaunch(l *net.TCPListener) error { f, err := l.File() if nil != err { return err } argv0, err := exec.LookPath(os.Args[0]) if nil != err { return err } wd, err := os.Getwd() if nil != err { return err } err = os.Setenv("GOAGAIN_FD", fmt.Sprint(f.Fd())) if nil != err { return err } err = os.Setenv("GOAGAIN_PPID", strconv.Itoa(syscall.Getpid())) if nil != err { return err } p, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{ Dir: wd, Env: os.Environ(), Files: []*os.File{os.Stdin, os.Stdout, os.Stderr, f}, Sys: &syscall.SysProcAttr{}, }) if nil != err { return err } log.Printf("spawned child %d\n", p.Pid) return nil }
// only valid on non-windows func (srv *Server) setupNonBlockingListener(err error, l *net.TCPListener) error { // FIXME: File() returns a copied pointer. we're leaking it. probably doesn't matter if srv.listenerFile, err = l.File(); err != nil { return err } fd := int(srv.listenerFile.Fd()) if e := syscall.SetNonblock(fd, true); e != nil { return e } return nil }
// only valid on non-windows func (srv *Server) setupNonBlockingListener(err error, l *net.TCPListener) error { if srv.listenerFile, err = l.File(); err != nil { return err } fd := int(srv.listenerFile.Fd()) if e := syscall.SetNonblock(fd, true); e != nil { return e } if srv.sendfile { if e := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, srv.sockOpt, 1); e != nil { return e } } return nil }
func doPrefork() (listener net.Listener) { var err error var fl *os.File var tcplistener *net.TCPListener if !*child { var addr *net.TCPAddr addr, err = net.ResolveTCPAddr("tcp", ":8080") if err != nil { log.Fatal(err) } tcplistener, err = net.ListenTCP("tcp", addr) if err != nil { log.Fatal(err) } fl, err = tcplistener.File() if err != nil { log.Fatal(err) } children := make([]*exec.Cmd, runtime.NumCPU()/2) for i := range children { children[i] = exec.Command(os.Args[0], "-prefork", "-child") children[i].Stdout = os.Stdout children[i].Stderr = os.Stderr children[i].ExtraFiles = []*os.File{fl} err = children[i].Start() if err != nil { log.Fatal(err) } } for _, ch := range children { var err error = ch.Wait() if err != nil { log.Print(err) } } os.Exit(0) } else { fl = os.NewFile(3, "") listener, err = net.FileListener(fl) if err != nil { log.Fatal(err) } runtime.GOMAXPROCS(2) } return listener }
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { t, _ := buildTcpMD5Sig(address, key) fi, err := l.File() defer fi.Close() if err != nil { return err } if l, err := net.FileListener(fi); err == nil { defer l.Close() } _, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, fi.Fd(), uintptr(syscall.IPPROTO_TCP), uintptr(TCP_MD5SIG), uintptr(unsafe.Pointer(&t)), unsafe.Sizeof(t), 0) if e > 0 { return e } return nil }
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { t, _ := buildTcpMD5Sig(address, key) fi, err := l.File() defer fi.Close() if err != nil { return err } if l, err := net.FileListener(fi); err == nil { defer l.Close() } b := *(*[unsafe.Sizeof(t)]byte)(unsafe.Pointer(&t)) if err := syscall.SetsockoptString(int(fi.Fd()), syscall.IPPROTO_TCP, TCP_MD5SIG, string(b[:])); err != nil { return err } return nil }
func (s *server) listen() error { var addr *net.TCPAddr var err error var listener *net.TCPListener if addr, err = net.ResolveTCPAddr("tcp", s.addr); err != nil { return err } if listener, err = net.ListenTCP("tcp", addr); err != nil { return err } s.listener = *listener if s.listenerFile, err = listener.File(); err != nil { return err } if e := syscall.SetNonblock(s.Fd(), true); e != nil { return e } return nil }
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { fi, err := l.File() defer fi.Close() if err != nil { return err } if l, err := net.FileListener(fi); err == nil { defer l.Close() } // always enable and assumes that the configuration is done by // setkey() if err := syscall.SetsockoptInt(int(fi.Fd()), syscall.IPPROTO_TCP, TCP_MD5SIG, 1); err != nil { return err } return nil }
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { fi, err := l.File() defer fi.Close() if err != nil { return err } if l, err := net.FileListener(fi); err == nil { defer l.Close() } t := int(1) if e := syscall.SetsockoptInt(int(fi.Fd()), syscall.IPPROTO_TCP, TCP_MD5SIG, t); e != nil { return e } if len(key) > 0 { return saAdd(address, key) } return saDelete(address) }
func (srv *Server) socketListen() os.Error { var la *net.TCPAddr var err os.Error if la, err = net.ResolveTCPAddr("tcp", srv.Addr); err != nil { return err } var l *net.TCPListener if l, err = net.ListenTCP("tcp", la); err != nil { return err } srv.listener = l if srv.listenerFile, err = l.File(); err != nil { return err } if e := syscall.SetNonblock(srv.listenerFile.Fd(), true); e != 0 { return os.Errno(e) } l.SetTimeout(3e9) return nil }
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { fi, err := l.File() defer fi.Close() if err != nil { return err } if l, err := net.FileListener(fi); err == nil { defer l.Close() } // always enable and assumes that the configuration is done by // setkey() t := int32(1) _, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, fi.Fd(), uintptr(syscall.IPPROTO_TCP), uintptr(TCP_MD5SIG), uintptr(unsafe.Pointer(&t)), unsafe.Sizeof(t), 0) if e > 0 { return e } return nil }