diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2018-12-12 23:06:08 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-12 23:06:08 +0000 |
commit | 76c214a2e95787f15a704b395de01261b8e003e3 (patch) | |
tree | 0fb18c8a38149680df517c28abe7b811fcb04fba | |
parent | e4ae7a892948304e7317e3d8cc8d00cf9a91228c (diff) | |
parent | 71e9fff364e4e2063b3c24d62dc57128f4a766fd (diff) | |
download | Nim-76c214a2e95787f15a704b395de01261b8e003e3.tar.gz |
Merge pull request #9915 from zevv/asyncnet-unix
Added basic AF_UNIX support to asyncnet.
-rw-r--r-- | lib/pure/asyncnet.nim | 55 | ||||
-rw-r--r-- | lib/pure/nativesockets.nim | 11 | ||||
-rw-r--r-- | lib/pure/net.nim | 7 |
3 files changed, 66 insertions, 7 deletions
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index e33ddeaf0..1c0681fad 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -622,6 +622,61 @@ proc bindAddr*(socket: AsyncSocket, port = Port(0), address = "") {. raiseOSError(osLastError()) freeAddrInfo(aiList) +when defined(posix): + + proc connectUnix*(socket: AsyncSocket, path: string): Future[void] = + ## Binds Unix socket to `path`. + ## This only works on Unix-style systems: Mac OS X, BSD and Linux + when not defined(nimdoc): + let retFuture = newFuture[void]("connectUnix") + result = retFuture + + proc cb(fd: AsyncFD): bool = + let ret = SocketHandle(fd).getSockOptInt(cint(SOL_SOCKET), cint(SO_ERROR)) + if ret == 0: + retFuture.complete() + return true + elif ret == EINTR: + return false + else: + retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) + return true + + var socketAddr = makeUnixAddr(path) + let ret = socket.fd.connect(cast[ptr SockAddr](addr socketAddr), + (sizeof(socketAddr.sun_family) + path.len).Socklen) + if ret == 0: + # Request to connect completed immediately. + retFuture.complete() + else: + let lastError = osLastError() + if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS: + addWrite(AsyncFD(socket.fd), cb) + else: + retFuture.fail(newException(OSError, osErrorMsg(lastError))) + + proc bindUnix*(socket: AsyncSocket, path: string) {. + tags: [ReadIOEffect].} = + ## Binds Unix socket to `path`. + ## This only works on Unix-style systems: Mac OS X, BSD and Linux + when not defined(nimdoc): + var socketAddr = makeUnixAddr(path) + if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr), + (sizeof(socketAddr.sun_family) + path.len).Socklen) != 0'i32: + raiseOSError(osLastError()) + +elif defined(nimdoc): + + proc connectUnix*(socket: AsyncSocket, path: string): Future[void] = + ## Binds Unix socket to `path`. + ## This only works on Unix-style systems: Mac OS X, BSD and Linux + discard + + proc bindUnix*(socket: AsyncSocket, path: string) = + ## Binds Unix socket to `path`. + ## This only works on Unix-style systems: Mac OS X, BSD and Linux + discard + proc close*(socket: AsyncSocket) = ## Closes the socket. defer: diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index b091f7310..f98f9a444 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -105,6 +105,7 @@ else: osInvalidSocket* = posix.INVALID_SOCKET nativeAfInet = posix.AF_INET nativeAfInet6 = posix.AF_INET6 + nativeAfUnix = posix.AF_UNIX proc `==`*(a, b: Port): bool {.borrow.} ## ``==`` for ports. @@ -482,8 +483,18 @@ proc getAddrString*(sockAddr: ptr SockAddr): string = raiseOSError(osLastError()) setLen(result, len(cstring(result))) else: + when defined(posix) and not defined(nimdoc): + if sockAddr.sa_family.cint == nativeAfUnix: + return "unix" raise newException(IOError, "Unknown socket family in getAddrString") +when defined(posix) and not defined(nimdoc): + proc makeUnixAddr*(path: string): Sockaddr_un = + result.sun_family = AF_UNIX.uint16 + if path.len >= Sockaddr_un_path_length: + raise newException(ValueError, "socket path too long") + copyMem(addr result.sun_path, path.cstring, path.len + 1) + proc getSockName*(socket: SocketHandle): Port = ## returns the socket's associated port number. var name: Sockaddr_in diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 23cd96b20..840a81f17 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -947,13 +947,6 @@ proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) { var valuei = cint(if value: 1 else: 0) setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei) -when defined(posix) and not defined(nimdoc): - proc makeUnixAddr(path: string): Sockaddr_un = - result.sun_family = AF_UNIX.uint16 - if path.len >= Sockaddr_un_path_length: - raise newException(ValueError, "socket path too long") - copyMem(addr result.sun_path, path.cstring, path.len + 1) - when defined(posix) or defined(nimdoc): proc connectUnix*(socket: Socket, path: string) = ## Connects to Unix socket on `path`. |