diff options
-rw-r--r-- | lib/posix/posix.nim | 48 | ||||
-rw-r--r-- | lib/pure/sockets.nim | 21 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 12 | ||||
-rw-r--r-- | lib/wrappers/openssl.nim | 4 |
4 files changed, 55 insertions, 30 deletions
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 107129b7a..806c255ee 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -81,8 +81,7 @@ else: ## A type representing a directory stream. type - TSocketHandle* = cint # The type used to represent socket descripters - # Should this be distinct? Is this the right place? + TSocketHandle* = distinct cint # The type used to represent socket descriptors Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final, pure.} = object ## dirent_t struct @@ -1794,7 +1793,7 @@ proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "<dlfcn.h>".} proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>".} proc creat*(a1: cstring, a2: Tmode): cint {.importc, header: "<fcntl.h>".} -proc fcntl*(a1: cint, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} +proc fcntl*(a1: cint | TSocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} proc posix_fadvise*(a1: cint, a2, a3: Toff, a4: cint): cint {. importc, header: "<fcntl.h>".} @@ -2071,7 +2070,7 @@ proc access*(a1: cstring, a2: cint): cint {.importc, header: "<unistd.h>".} proc alarm*(a1: cint): cint {.importc, header: "<unistd.h>".} proc chdir*(a1: cstring): cint {.importc, header: "<unistd.h>".} proc chown*(a1: cstring, a2: Tuid, a3: Tgid): cint {.importc, header: "<unistd.h>".} -proc close*(a1: cint): cint {.importc, header: "<unistd.h>".} +proc close*(a1: cint | TSocketHandle): cint {.importc, header: "<unistd.h>".} proc confstr*(a1: cint, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".} proc crypt*(a1, a2: cstring): cstring {.importc, header: "<unistd.h>".} proc ctermid*(a1: cstring): cstring {.importc, header: "<unistd.h>".} @@ -2349,9 +2348,9 @@ proc strerror*(errnum: cint): cstring {.importc, header: "<string.h>".} proc hstrerror*(herrnum: cint): cstring {.importc, header: "<netdb.h>".} proc FD_CLR*(a1: cint, a2: var Tfd_set) {.importc, header: "<sys/select.h>".} -proc FD_ISSET*(a1: cint, a2: var Tfd_set): cint {. +proc FD_ISSET*(a1: cint | TSocketHandle, a2: var Tfd_set): cint {. importc, header: "<sys/select.h>".} -proc FD_SET*(a1: cint, a2: var Tfd_set) {.importc, header: "<sys/select.h>".} +proc FD_SET*(a1: cint | TSocketHandle, a2: var Tfd_set) {.importc, header: "<sys/select.h>".} proc FD_ZERO*(a1: var Tfd_set) {.importc, header: "<sys/select.h>".} proc pselect*(a1: cint, a2, a3, a4: ptr Tfd_set, a5: ptr ttimespec, @@ -2431,44 +2430,49 @@ proc CMSG_NXTHDR*(mhdr: ptr TMsgHdr, cmsg: ptr TCMsgHdr): ptr TCmsgHdr {. proc CMSG_FIRSTHDR*(mhdr: ptr TMsgHdr): ptr TCMsgHdr {. importc, header: "<sys/socket.h>".} -proc accept*(a1: cint, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. +const + INVALID_SOCKET* = TSocketHandle(-1) + +proc `==`*(x, y: TSocketHandle): bool {.borrow.} + +proc accept*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): TSocketHandle {. importc, header: "<sys/socket.h>".} -proc bindSocket*(a1: cint, a2: ptr Tsockaddr, a3: Tsocklen): cint {. +proc bindSocket*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: Tsocklen): cint {. importc: "bind", header: "<sys/socket.h>".} ## is Posix's ``bind``, because ``bind`` is a reserved word -proc connect*(a1: cint, a2: ptr Tsockaddr, a3: Tsocklen): cint {. +proc connect*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: Tsocklen): cint {. importc, header: "<sys/socket.h>".} -proc getpeername*(a1: cint, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. +proc getpeername*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. importc, header: "<sys/socket.h>".} -proc getsockname*(a1: cint, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. +proc getsockname*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. importc, header: "<sys/socket.h>".} -proc getsockopt*(a1, a2, a3: cint, a4: pointer, a5: ptr Tsocklen): cint {. +proc getsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: ptr Tsocklen): cint {. importc, header: "<sys/socket.h>".} -proc listen*(a1, a2: cint): cint {. +proc listen*(a1: TSocketHandle, a2: cint): cint {. importc, header: "<sys/socket.h>".} -proc recv*(a1: cint, a2: pointer, a3: int, a4: cint): int {. +proc recv*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "<sys/socket.h>".} -proc recvfrom*(a1: cint, a2: pointer, a3: int, a4: cint, +proc recvfrom*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr Tsockaddr, a6: ptr Tsocklen): int {. importc, header: "<sys/socket.h>".} -proc recvmsg*(a1: cint, a2: ptr Tmsghdr, a3: cint): int {. +proc recvmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "<sys/socket.h>".} -proc send*(a1: cint, a2: pointer, a3: int, a4: cint): int {. +proc send*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "<sys/socket.h>".} -proc sendmsg*(a1: cint, a2: ptr Tmsghdr, a3: cint): int {. +proc sendmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "<sys/socket.h>".} -proc sendto*(a1: cint, a2: pointer, a3: int, a4: cint, a5: ptr Tsockaddr, +proc sendto*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr Tsockaddr, a6: Tsocklen): int {. importc, header: "<sys/socket.h>".} -proc setsockopt*(a1, a2, a3: cint, a4: pointer, a5: Tsocklen): cint {. +proc setsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: Tsocklen): cint {. importc, header: "<sys/socket.h>".} -proc shutdown*(a1, a2: cint): cint {. +proc shutdown*(a1: TSocketHandle, a2: cint): cint {. importc, header: "<sys/socket.h>".} -proc socket*(a1, a2, a3: cint): cint {. +proc socket*(a1, a2, a3: cint): TSocketHandle {. importc, header: "<sys/socket.h>".} proc sockatmark*(a1: cint): cint {. importc, header: "<sys/socket.h>".} diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 516d0d8bc..d45c6ba3e 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -126,7 +126,19 @@ type ETimeout* = object of ESynch +let + InvalidSocket*: TSocket = nil ## invalid socket + +when defined(windows): + const + OSInvalidSocket = winlean.INVALID_SOCKET +else: + const + OSInvalidSocket = posix.INVALID_SOCKET + proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = + if fd == OSInvalidSocket: + return nil new(result) result.fd = fd result.isBuffered = isBuff @@ -134,9 +146,6 @@ proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = result.currPos = 0 result.nonblocking = false -let - InvalidSocket*: TSocket = nil ## invalid socket - proc `==`*(a, b: TPort): bool {.borrow.} ## ``==`` for ports. @@ -211,7 +220,9 @@ else: proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, protocol: TProtocol = IPPROTO_TCP, buffered = true): TSocket = - ## Creates a new socket; returns `InvalidSocket` if an error occurs. + ## Creates a new socket; returns `InvalidSocket` if an error occurs. + + # TODO: Perhaps this should just raise EOS when an error occurs. when defined(Windows): result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered) else: @@ -456,7 +467,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) - if sock < 0: + if sock == OSInvalidSocket: let err = OSLastError() when defined(windows): if err.int32 == WSAEINPROGRESS: diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 40b24cc0a..6f72319ba 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -389,8 +389,6 @@ type h_addrtype*: int16 h_length*: int16 h_addr_list*: cstringArray - - TSocketHandle* = int # Make distinct? Is this the right place for this? TFdSet* {.pure, final.} = object fd_count*: cint # unsigned @@ -411,8 +409,18 @@ type Tsocklen* = cuint +when hostCPU == "amd64": + type + TSocketHandle* = distinct int # on WIN64 `SOCKET` is UINT_PTR +else: + type + TSocketHandle* = distinct cuint # on WIN32 `SOCKET` is U_INT (unsigned int) + var SOMAXCONN* {.importc, header: "Winsock2.h".}: cint + INVALID_SOCKET* {.importc, header: "Winsock2.h".}: cint + +proc `==`*(x, y: TSocketHandle): bool {.borrow.} proc getservbyname*(name, proto: cstring): ptr TServent {. stdcall, importc: "getservbyname", dynlib: ws2dll.} diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index f310c969b..af72d04eb 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -45,6 +45,7 @@ when defined(WINDOWS): const DLLSSLName = "(ssleay32|libssl32).dll" DLLUtilName = "libeay32.dll" + from winlean import TSocketHandle else: const versions = "(|.1.0.0|.0.9.9|.0.9.8|.0.9.7|.0.9.6|.0.9.5|.0.9.4)" @@ -56,6 +57,7 @@ else: const DLLSSLName = "libssl.so" & versions DLLUtilName = "libcrypto.so" & versions + from posix import TSocketHandle type SslStruct {.final, pure.} = object @@ -225,7 +227,7 @@ proc SSL_CTX_use_PrivateKey_file*(ctx: PSSL_CTX, proc SSL_CTX_check_private_key*(ctx: PSSL_CTX): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_set_fd*(ssl: PSSL, fd: cint): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_set_fd*(ssl: PSSL, fd: TSocketHandle): cint{.cdecl, dynlib: DLLSSLName, importc.} proc SSL_shutdown*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} proc SSL_connect*(ssl: PSSL): cint{.cdecl, dynlib: DLLSSLName, importc.} |