mirror of
https://github.com/golang/go
synced 2024-11-18 00:04:43 -07:00
net: only remove Unix domain socket file on the first call to Close
Fixes #17131. Change-Id: I60b381687746fadce12ef18a190cbe3f435172f2 Reviewed-on: https://go-review.googlesource.com/32098 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Quentin Smith <quentin@golang.org>
This commit is contained in:
parent
87e48c5afd
commit
13558c41ff
@ -7,6 +7,7 @@ package net
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
@ -206,9 +207,10 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
|
||||
// typically use variables of type Listener instead of assuming Unix
|
||||
// domain sockets.
|
||||
type UnixListener struct {
|
||||
fd *netFD
|
||||
path string
|
||||
unlink bool
|
||||
fd *netFD
|
||||
path string
|
||||
unlink bool
|
||||
unlinkOnce sync.Once
|
||||
}
|
||||
|
||||
func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
|
||||
|
@ -173,9 +173,12 @@ func (ln *UnixListener) close() error {
|
||||
// is at least compatible with the auto-remove
|
||||
// sequence in ListenUnix. It's only non-Go
|
||||
// programs that can mess us up.
|
||||
if ln.path[0] != '@' && ln.unlink {
|
||||
syscall.Unlink(ln.path)
|
||||
}
|
||||
// Even if there are racy calls to Close, we want to unlink only for the first one.
|
||||
ln.unlinkOnce.Do(func() {
|
||||
if ln.path[0] != '@' && ln.unlink {
|
||||
syscall.Unlink(ln.path)
|
||||
}
|
||||
})
|
||||
return ln.fd.Close()
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ package net
|
||||
import (
|
||||
"bytes"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
@ -443,4 +444,15 @@ func TestUnixUnlink(t *testing.T) {
|
||||
if _, err := os.Stat(name); err == nil {
|
||||
t.Fatal("closing unix listener did not remove unix socket")
|
||||
}
|
||||
if err := ioutil.WriteFile(name, []byte("hello world"), 0666); err != nil {
|
||||
t.Fatalf("cannot recreate socket file: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(name); err != nil {
|
||||
t.Fatal("recreating unix listener as file failed: %v", err)
|
||||
}
|
||||
l.Close()
|
||||
if _, err := os.Stat(name); err != nil {
|
||||
t.Fatalf("second close of unix socket did second remove: %v", err)
|
||||
}
|
||||
os.Remove(name)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user