summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/posix/posix.nim48
-rw-r--r--lib/pure/sockets.nim21
-rw-r--r--lib/windows/winlean.nim12
-rw-r--r--lib/wrappers/openssl.nim4
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.}