diff options
| author | Yasuhiro Matsumoto <mattn.jp@gmail.com> | 2018-07-23 01:47:11 +0900 |
|---|---|---|
| committer | Alex Brainman <alex.brainman@gmail.com> | 2018-08-28 09:26:45 +0000 |
| commit | 76c45877c9e72ccc84db787dc08299e0182e0efb (patch) | |
| tree | ce7f3169335049a4918df6a5b465a0ea1d727721 /src/syscall | |
| parent | ded941158042d8b09164a9f8049fd7108b715680 (diff) | |
| download | go-76c45877c9e72ccc84db787dc08299e0182e0efb.tar.xz | |
syscall: implement Unix Socket for Windows
Add implementation of AF_UNIX. This works only on Windows 10.
https://blogs.msdn.microsoft.com/commandline/2017/12/19/af_unix-comes-to-windows/
Fixes #26072
Change-Id: I76a96a472385a17901885271622fbe55d66bb720
Reviewed-on: https://go-review.googlesource.com/125456
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src/syscall')
| -rw-r--r-- | src/syscall/syscall_windows.go | 58 | ||||
| -rw-r--r-- | src/syscall/types_windows.go | 2 |
2 files changed, 56 insertions, 4 deletions
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go index 638a81882a..528ef4f26d 100644 --- a/src/syscall/syscall_windows.go +++ b/src/syscall/syscall_windows.go @@ -634,7 +634,7 @@ type RawSockaddr struct { type RawSockaddrAny struct { Addr RawSockaddr - Pad [96]int8 + Pad [100]int8 } type Sockaddr interface { @@ -683,19 +683,69 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil } +type RawSockaddrUnix struct { + Family uint16 + Path [UNIX_PATH_MAX]int8 +} + type SockaddrUnix struct { Name string + raw RawSockaddrUnix } func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { - // TODO(brainman): implement SockaddrUnix.sockaddr() - return nil, 0, EWINDOWS + name := sa.Name + n := len(name) + if n > len(sa.raw.Path) { + return nil, 0, EINVAL + } + if n == len(sa.raw.Path) && name[0] != '@' { + return nil, 0, EINVAL + } + sa.raw.Family = AF_UNIX + for i := 0; i < n; i++ { + sa.raw.Path[i] = int8(name[i]) + } + // length is family (uint16), name, NUL. + sl := int32(2) + if n > 0 { + sl += int32(n) + 1 + } + if sa.raw.Path[0] == '@' { + sa.raw.Path[0] = 0 + // Don't count trailing NUL for abstract address. + sl-- + } + + return unsafe.Pointer(&sa.raw), sl, nil } func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { switch rsa.Addr.Family { case AF_UNIX: - return nil, EWINDOWS + pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) + sa := new(SockaddrUnix) + if pp.Path[0] == 0 { + // "Abstract" Unix domain socket. + // Rewrite leading NUL as @ for textual display. + // (This is the standard convention.) + // Not friendly to overwrite in place, + // but the callers below don't care. + pp.Path[0] = '@' + } + + // Assume path ends at NUL. + // This is not technically the Linux semantics for + // abstract Unix domain sockets--they are supposed + // to be uninterpreted fixed-size binary blobs--but + // everyone uses this convention. + n := 0 + for n < len(pp.Path) && pp.Path[n] != 0 { + n++ + } + bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] + sa.Name = string(bytes) + return sa, nil case AF_INET: pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) diff --git a/src/syscall/types_windows.go b/src/syscall/types_windows.go index 6911fe509c..0b839339d2 100644 --- a/src/syscall/types_windows.go +++ b/src/syscall/types_windows.go @@ -1139,3 +1139,5 @@ const ( SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 _SYMLINK_FLAG_RELATIVE = 1 ) + +const UNIX_PATH_MAX = 108 // defined in afunix.h |
