goposixunix-socket

Failsafe way of listening on a unix-domain-socket


This code works fine on the first run:

package main

import (
    "context"
    "fmt"
    "net"
)


func main() {
    ctx := context.Background()
    udsName := "dummy.socket"
    var lc net.ListenConfig
    _, err := lc.Listen(ctx, "unix", udsName)
    if err != nil {
        panic(fmt.Sprintf("failed to listen(unix) name %s: %v", udsName, err))
    }
    fmt.Println("all is fine")
}

But it fails on the second run:

panic: failed to listen(unix) name dummy.socket: listen unix dummy.socket: bind: address already in use

I could just remove the file before Listen(), but this could be a failure, if there is already a process listening on this socket.

Is there a way to detect if there is a process listening on the socket?

Then I could remove the old dummy.socket file, if the old server is dead.


Solution

  • Delete the unix socket file prior to binding, only 'failsafe' way i know:

    package main
    
    import (
        "context"
        "fmt"
        "net"
    )
    
    
    func main() {
        ctx := context.Background()
        udsName := "dummy.socket"
        os.Remove(udsName) //delete the unix socket file
        var lc net.ListenConfig
        _, err := lc.Listen(ctx, "unix", udsName)
        if err != nil {
            panic(fmt.Sprintf("failed to listen(unix) name %s: %v", udsName, err))
        }
        fmt.Println("all is fine")
    }