Commit 13558c41 authored by Russ Cox's avatar Russ Cox

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: 's avatarQuentin Smith <quentin@golang.org>
parent 87e48c5a
...@@ -7,6 +7,7 @@ package net ...@@ -7,6 +7,7 @@ package net
import ( import (
"context" "context"
"os" "os"
"sync"
"syscall" "syscall"
"time" "time"
) )
...@@ -206,9 +207,10 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) { ...@@ -206,9 +207,10 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
// typically use variables of type Listener instead of assuming Unix // typically use variables of type Listener instead of assuming Unix
// domain sockets. // domain sockets.
type UnixListener struct { type UnixListener struct {
fd *netFD fd *netFD
path string path string
unlink bool unlink bool
unlinkOnce sync.Once
} }
func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil } func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
......
...@@ -173,9 +173,12 @@ func (ln *UnixListener) close() error { ...@@ -173,9 +173,12 @@ func (ln *UnixListener) close() error {
// is at least compatible with the auto-remove // is at least compatible with the auto-remove
// sequence in ListenUnix. It's only non-Go // sequence in ListenUnix. It's only non-Go
// programs that can mess us up. // programs that can mess us up.
if ln.path[0] != '@' && ln.unlink { // Even if there are racy calls to Close, we want to unlink only for the first one.
syscall.Unlink(ln.path) ln.unlinkOnce.Do(func() {
} if ln.path[0] != '@' && ln.unlink {
syscall.Unlink(ln.path)
}
})
return ln.fd.Close() return ln.fd.Close()
} }
......
...@@ -9,6 +9,7 @@ package net ...@@ -9,6 +9,7 @@ package net
import ( import (
"bytes" "bytes"
"internal/testenv" "internal/testenv"
"io/ioutil"
"os" "os"
"reflect" "reflect"
"runtime" "runtime"
...@@ -443,4 +444,15 @@ func TestUnixUnlink(t *testing.T) { ...@@ -443,4 +444,15 @@ func TestUnixUnlink(t *testing.T) {
if _, err := os.Stat(name); err == nil { if _, err := os.Stat(name); err == nil {
t.Fatal("closing unix listener did not remove unix socket") 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)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment