From 521a9af4dda24087e4ebe1f814980d9a4ab9dbb6 Mon Sep 17 00:00:00 2001 From: "Francisco A. Lozano" Date: Tue, 7 Jul 2015 06:33:41 +0900 Subject: [PATCH 1/2] Ongoing impl of select'able file descriptor --- starter.go | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/starter.go b/starter.go index 2b89842..7c1d241 100644 --- a/starter.go +++ b/starter.go @@ -188,9 +188,11 @@ func setEnv() { } } -func parsePortSpec(addr string) (string, int, error) { +func parsePortSpec(addr string) (string, int, int, error) { i := strings.IndexByte(addr, ':') portPart := "" + fdPart := "" + if i < 0 { portPart = addr addr = "" @@ -199,12 +201,26 @@ func parsePortSpec(addr string) (string, int, error) { addr = addr[:i] } + j := strings.IndexByte(portPart, '=') + if j > 0 { + fdPart = portPart[j+1:] + portPart = portPart[:j] + } + port, err := strconv.ParseInt(portPart, 10, 64) if err != nil { - return "", -1, err + return "", -1, -1, err } - return addr, int(port), nil + if fdPart == "" { + return addr, int(port), -1, nil + } else { + fd, err := strconv.ParseInt(fdPart, 10, 64) + if err != nil { + return addr, int(port), -1, err + } + return addr, int(port), int(fd), nil + } } func (s *Starter) Run() error { @@ -223,7 +239,7 @@ func (s *Starter) Run() error { for _, addr := range s.ports { var l net.Listener - host, port, err := parsePortSpec(addr) + host, port, fd, err := parsePortSpec(addr) if err != nil { fmt.Fprintf(os.Stderr, "failed to parse addr spec '%s': %s", addr, err) return err @@ -235,6 +251,20 @@ func (s *Starter) Run() error { fmt.Fprintf(os.Stderr, "failed to listen to %s:%s\n", hostport, err) return err } + if fd != -1 { + file, err := l.(*net.TCPListener).File() + if err == nil { + oldFD := file.Fd() + err = syscall.Dup2 ( int(oldFD), fd) + if err == nil { + err = syscall.Close( int(oldFD) ) + } + } + if err != nil { + fmt.Fprintf(os.Stderr, "failed to duplicate fd: %s", err) + return err + } + } spec := "" if host == "" { From 99b51ef6f120bd5dbe4093febb57c0cebd560983 Mon Sep 17 00:00:00 2001 From: "Francisco A. Lozano" Date: Tue, 7 Jul 2015 06:52:31 +0900 Subject: [PATCH 2/2] Replace listener with new listener from dup'ed FD --- starter.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/starter.go b/starter.go index 7c1d241..1da9428 100644 --- a/starter.go +++ b/starter.go @@ -255,9 +255,12 @@ func (s *Starter) Run() error { file, err := l.(*net.TCPListener).File() if err == nil { oldFD := file.Fd() - err = syscall.Dup2 ( int(oldFD), fd) + err = syscall.Dup2 (int(oldFD), fd) if err == nil { - err = syscall.Close( int(oldFD) ) + l, err = net.FileListener(os.NewFile(uintptr(fd), "")) + if err == nil { + err = syscall.Close(int(oldFD)) + } } } if err != nil {