Closed as not planned
Closed as not planned
Description
Go version
go version go1.23.4 linux/amd64
Output of go env
in your module/workspace:
env really doesn't matter here, this bug have years.
I initially thought it was Gin bug ( https://github.com/gin-gonic/gin/issues/3817 ) but I digged deeper
What did you do?
Running this code
func main() {
u, err := net.Listen("unix", "sock_raw")
fmt.Println(err)
if err == nil {
defer u.Close()
}
}
over and over will work every time unless killed by SIGKILL because u.Close()
cleans up the socket.
but adding http.Serve in the mix:
package main
import (
"fmt"
"net"
"net/http"
)
type H struct{}
func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
func main() {
u, err := net.Listen("unix", "sock_http")
fmt.Println(err)
if err == nil {
defer u.Close()
fmt.Println("press C-c and run me again")
fmt.Println(http.Serve(u, &H{}))
}
}
will fail after first run because of leftover socket that now for some reason is not cleared by u.Close()
. Even if cleanup is added manually by defer os.Remove()
...
func main() {
u, err := net.Listen("unix", "sock_http")
defer os.Remove("sock_http") # <-- here
fmt.Println(err)
if err == nil {
defer u.Close()
fmt.Println("press C-c and run me again")
fmt.Println(http.Serve(u, &H{}))
}
}
the result is still the same:
-> ᛯ go run main.go 1
<nil>
press C-c and run me again
^Csignal: interrupt
-> ᛯ go run main.go 1
listen unix sock_http: bind: address already in use
[20:44:53] ^ [/tmp/g]
-> ᛯ
I even tried adding
defer func() {
c := exec.Command("/bin/rm", "sock_http")
c.Run()
}()
but that didn't remove it either. Also tried adding signal handler so it gets clean os.Exit
:
package main
import (
"fmt"
"net"
"net/http"
"os"
"os/signal"
)
func main() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for _ = range c {
fmt.Println("exiting")
os.Exit(1)
}
}()
u, err := net.Listen("unix", "sock_http")
fmt.Println(err)
if err == nil {
defer u.Close()
fmt.Println("press C-c and run me again")
fmt.Println(http.Serve(u, nil))
}
with same result:
-> ᛯ go run main.go
<nil>
press C-c and run me again
^Cexiting
exit status 1
-> ᛯ go run main.go 1
listen unix sock_http: bind: address already in use
What did you see happen?
Socket not being removed when http.Serve uses it
What did you expect to see?
I'd expect one of 2 things to happen:
net.Listen
user pre-created socket if it can, which allows to, for example, set the permissions to the socket before listening on it which might desirable security-wise- the socket is correctly cleared if removed when http.Serve is using it
Metadata
Metadata
Assignees
Labels
No labels