Skip to content

Instantly share code, notes, and snippets.

@stephane-martin
Created November 21, 2018 23:03
Show Gist options
  • Save stephane-martin/57a19466633b7ce712945aaed7a0e751 to your computer and use it in GitHub Desktop.
Save stephane-martin/57a19466633b7ce712945aaed7a0e751 to your computer and use it in GitHub Desktop.
Make a net.Listener to listen on stdin for inetd enables services
package main
import (
"errors"
"net"
"os"
"sync"
)
type StdinListener struct {
connectionOnce sync.Once
closeOnce sync.Once
connChan chan net.Conn
}
func NewStdinListener() net.Listener {
l := new(StdinListener)
l.connChan = make(chan net.Conn, 1)
return l
}
type stdinConn struct {
net.Conn
l net.Listener
}
func (c stdinConn) Close() (err error) {
err = c.Conn.Close()
c.l.Close()
return err
}
func (l *StdinListener) Accept() (net.Conn, error) {
l.connectionOnce.Do(func() {
conn, err := net.FileConn(os.Stdin)
if err == nil {
l.connChan <- stdinConn{Conn: conn, l: l}
os.Stdin.Close()
} else {
l.Close()
}
})
conn, ok := <-l.connChan
if ok {
return conn, nil
} else {
return nil, errors.New("Closed")
}
}
func (l *StdinListener) Close() error {
l.closeOnce.Do(func() { close(l.connChan) })
return nil
}
func (l *StdinListener) Addr() net.Addr {
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment