From b7ffbd3b47da4290a4af2ccd253c74c2c22bfabf Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 16 Nov 2024 17:04:03 +0100 Subject: [PATCH] Bugfix: use filepath package when connecting to UNIX sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code before this commit is non-portable: it only works on UNIX systems where path.Join() is close enough to filepath.Join(). However, path.Join() is the wrong choice: UNIX domain sockets are identified via their file system name, so — conceptually and in practice — we need to use the filepath package instead. This commit fixes connecting to a PostgreSQL database that is listening on a UNIX domain socket on Windows. If you are surprised to see UNIX domain sockets on Windows, they were introduced with Windows 10, i.e. are widely available now: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ filepath.IsAbs() is equivalent to strings.HasPrefix(s, "/") on UNIX, but also works on Windows, where absolute paths start with e.g. C:\ Similarly, filepath.Join() uses the correct path separator. Also recognize UNIX domain sockets in the abstract name space (represented by a leading @ character) while here. related to https://github.com/zombiezen/postgrestest/issues/3 --- conn.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/conn.go b/conn.go index bc098360..1d9e4a22 100644 --- a/conn.go +++ b/conn.go @@ -15,7 +15,6 @@ import ( "net" "os" "os/user" - "path" "path/filepath" "strconv" "strings" @@ -437,8 +436,10 @@ func dial(ctx context.Context, d Dialer, o values) (net.Conn, error) { func network(o values) (string, string) { host := o["host"] - if strings.HasPrefix(host, "/") { - sockPath := path.Join(host, ".s.PGSQL."+o["port"]) + // UNIX domain sockets are either represented by an (absolute) file system + // path or they live in the abstract name space (starting with an @). + if filepath.IsAbs(host) || strings.HasPrefix(host, "@") { + sockPath := filepath.Join(host, ".s.PGSQL."+o["port"]) return "unix", sockPath }