Skip to content

Instantly share code, notes, and snippets.

@ryanwoodsmall
Forked from stephane-martin/inetd.go
Created August 31, 2023 03:57
Show Gist options
  • Save ryanwoodsmall/0fec977481121b719f41a0f03fd0d5bb to your computer and use it in GitHub Desktop.
Save ryanwoodsmall/0fec977481121b719f41a0f03fd0d5bb 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