golang app as xinetd service

307 views
Skip to first unread message

Ted Toth

unread,
Sep 15, 2015, 10:20:13 AM9/15/15
to golang-nuts
I'm trying to run a Go http server app out of xinetd. Since xinetd passes the connected socket to the child as stdin I wrote the following:

        fi, _ := os.Stdin.Stat() // get the FileInfo struct describing the standard input.

if (fi.Mode() & os.ModeSocket) == 0 {
fmt.Printf("stdin is a socket")
} else {
fmt.Printf("stdin is not a socket")
}

listener, err := net.FileListener(os.Stdin)
if err != nil {
fmt.Printf("net.FileListener(os.Stdin) failed: %v\n", err)
return
}
err = http.Serve(listener, router)
if err != nil {
fmt.Printf("http.Serve(listener, router) failed: %v\n", err)
return
}

However when I run:

I get back:
stdin is not a socket
http.Serve(listener, router) failed: accept tcp 192.168.10.10: accept: invalid argument

How can I get an http server to use stdin as it's socket connection?

Ted

Ted Toth

unread,
Sep 15, 2015, 12:15:59 PM9/15/15
to golang-nuts
stdin is a socket my test was wrong should be:
if (fi.Mode() & os.ModeSocket) == 1 {

Also I looked at the fcgi code and I'm doing basically the same thing it does if given a nil Listener.

Ted Toth

unread,
Sep 15, 2015, 1:53:53 PM9/15/15
to golang-nuts
strace of accept error:

23045 write(3, "\0\0\0\32\0\0Z\5\0\0\0\7contactdbws: stdin", 30 <unfinished ...>
23046 select(0, NULL, NULL, NULL, {0, 20} <unfinished ...>
23045 <... write resumed> )             = 30
23045 select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout)
23045 write(3, "\0\0\0\37\0\0Z\5\0\0\0\7contactdbws: Srwxrwx"..., 35) = 35
23045 fcntl(0, F_DUPFD_CLOEXEC, 0)      = 4
23045 fcntl(4, F_GETFL)                 = 0x2 (flags O_RDWR)
23045 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
23045 getsockopt(4, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
23045 getsockname(4, {sa_family=AF_INET, sin_port=htons(10349), sin_addr=inet_addr("192.168.10.10")}, [16]) = 0
23045 getpeername(4, {sa_family=AF_INET, sin_port=htons(49196), sin_addr=inet_addr("192.168.10.10")}, [16]) = 0
23045 epoll_create1(O_CLOEXEC)          = 5
23045 epoll_ctl(5, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLOUT|EPOLLET|0x2000, {u32=4108432872, u64=139882603329000}}) = 0
23045 write(1, "*net.TCPListener\n", 17) = 17
23045 accept4(4, 0xc820101998, [112], SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EINVAL (Invalid argument)
23045 accept(4, 0xc8201019a8, [112])    = -1 EINVAL (Invalid argument)
23045 epoll_ctl(5, EPOLL_CTL_DEL, 4, {0, {u32=0, u64=0}}) = 0
23045 close(4)                          = 0
23045 write(1, "http.Serve(listener, router) fai"..., 94) = -1 ECONNRESET (Connection reset by peer)
23045 exit_group(0)                     = ?

Giulio Iotti

unread,
Sep 15, 2015, 3:08:33 PM9/15/15
to golang-nuts
On Tuesday, September 15, 2015 at 5:20:13 PM UTC+3, Ted Toth wrote:
I'm trying to run a Go http server app out of xinetd. Since xinetd passes the connected socket to the child as stdin I wrote the following:

        fi, _ := os.Stdin.Stat() // get the FileInfo struct describing the standard input.

Why _? Please dump this error too.
 
if (fi.Mode() & os.ModeSocket) == 0 {

I think it should be:
   if fi.Mode()&os.ModeSocket == os.ModeSocket {

As for the real problem you are having, I need more info. Your FileListener tries to use TCP: is that what you configured xinitd to use? Show conf.

-- 
Giulio Iotti

 

Ted Toth

unread,
Sep 15, 2015, 4:53:42 PM9/15/15
to golang-nuts

xinetd configuration

service contactdbws
{
        disable         = no
        only_from       = localhost comms 127.0.0.1
protocol = tcp
        socket_type     = stream
        wait            = no
        flags           = LABELED IPv4
        user            = contactdbws
        group           = jcdx
        instances       = 50
        per_source      = 50
        cps             = 600 1
        server          = /opt/jcdx/bin/contactdbws
}

I changed the Stat call to return any error and there is none.
I also changed the code to print the mode string from the FileInfo:
fmt.Printf( fi.Mode().String())

which is Srwxrwxrwx i.e. it's a socket.

Matt Harden

unread,
Sep 15, 2015, 10:00:36 PM9/15/15
to Ted Toth, golang-nuts
If you set wait = yes in your xinetd service, it may work.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ted Toth

unread,
Sep 16, 2015, 9:36:46 AM9/16/15
to golang-nuts
I opened a bug with a simplified example:
https://github.com/golang/go/issues/12646
Reply all
Reply to author
Forward
0 new messages