]> Cypherpunks repositories - gostls13.git/commitdiff
net: only remove Unix domain socket file on the first call to Close
authorRuss Cox <rsc@golang.org>
Thu, 27 Oct 2016 00:13:33 +0000 (20:13 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 28 Oct 2016 18:29:19 +0000 (18:29 +0000)
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>
src/net/unixsock.go
src/net/unixsock_posix.go
src/net/unixsock_test.go

index fffcb87550935c552a74d1b34bb7fdba85143036..b25d492f5915bd2747a319bd8c270529e599e256 100644 (file)
@@ -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 }
index 5f0999c4c270e1773bdc33f571ef3f62f2e5e3d9..7e70c8f8ed77e130f870d86826f515748ca675dd 100644 (file)
@@ -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()
 }
 
index f0f88ed37b2bde307b5357ade6d4f7e5ec00b1a6..015036770b55e1a134b09fc782baceddfedc64c4 100644 (file)
@@ -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)
 }