Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 13558c4

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Quentin Smith <[email protected]>
1 parent 87e48c5 commit 13558c4

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

src/net/unixsock.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package net
77
import (
88
"context"
99
"os"
10+
"sync"
1011
"syscall"
1112
"time"
1213
)
@@ -206,9 +207,10 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
206207
// typically use variables of type Listener instead of assuming Unix
207208
// domain sockets.
208209
type UnixListener struct {
209-
fd *netFD
210-
path string
211-
unlink bool
210+
fd *netFD
211+
path string
212+
unlink bool
213+
unlinkOnce sync.Once
212214
}
213215

214216
func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }

src/net/unixsock_posix.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,12 @@ func (ln *UnixListener) close() error {
173173
// is at least compatible with the auto-remove
174174
// sequence in ListenUnix. It's only non-Go
175175
// programs that can mess us up.
176-
if ln.path[0] != '@' && ln.unlink {
177-
syscall.Unlink(ln.path)
178-
}
176+
// Even if there are racy calls to Close, we want to unlink only for the first one.
177+
ln.unlinkOnce.Do(func() {
178+
if ln.path[0] != '@' && ln.unlink {
179+
syscall.Unlink(ln.path)
180+
}
181+
})
179182
return ln.fd.Close()
180183
}
181184

src/net/unixsock_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package net
99
import (
1010
"bytes"
1111
"internal/testenv"
12+
"io/ioutil"
1213
"os"
1314
"reflect"
1415
"runtime"
@@ -443,4 +444,15 @@ func TestUnixUnlink(t *testing.T) {
443444
if _, err := os.Stat(name); err == nil {
444445
t.Fatal("closing unix listener did not remove unix socket")
445446
}
447+
if err := ioutil.WriteFile(name, []byte("hello world"), 0666); err != nil {
448+
t.Fatalf("cannot recreate socket file: %v", err)
449+
}
450+
if _, err := os.Stat(name); err != nil {
451+
t.Fatal("recreating unix listener as file failed: %v", err)
452+
}
453+
l.Close()
454+
if _, err := os.Stat(name); err != nil {
455+
t.Fatalf("second close of unix socket did second remove: %v", err)
456+
}
457+
os.Remove(name)
446458
}

0 commit comments

Comments
 (0)