diff options
author | Araq <rumpf_a@web.de> | 2010-11-18 22:26:20 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2010-11-18 22:26:20 +0100 |
commit | adf13aaea379d482ad4289d349a9d475bc2c06a6 (patch) | |
tree | 4c18d447545c35fa7c1f4ce7db566f96db67a080 /lib/pure/sockets.nim | |
parent | 8ee63f98364259b2d1b6c02d050e0efccecbcf9b (diff) | |
download | Nim-adf13aaea379d482ad4289d349a9d475bc2c06a6.tar.gz |
docgen understands and ignores *when false*
Diffstat (limited to 'lib/pure/sockets.nim')
-rwxr-xr-x | lib/pure/sockets.nim | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 85628db78..add41afd6 100755 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -9,7 +9,7 @@ ## This module implements a simple portable type-safe sockets layer. -import os +import os, parseutils when defined(Windows): import winlean @@ -146,18 +146,66 @@ proc listen*(socket: TSocket, attempts = 5) = ## listens to socket. if listen(cint(socket), cint(attempts)) < 0'i32: OSError() -proc bindAddr*(socket: TSocket, port = TPort(0)) = - ## binds a port number to a socket. +proc invalidIp4(s: string) {.noreturn, noinline.} = + raise newException(EInvalidValue, "invalid ip4 address: " & s) + +proc parseIp4*(s: string): int32 = + ## parses an IP version 4 in dotted decimal form like "a.b.c.d". + ## Raises EInvalidValue in case of an error. + var a, b, c, d: int + var i = 0 + var j = parseInt(s, a, i) + if j <= 0: invalidIp4(s) + inc(i, j) + if s[i] == '.': inc(i) + else: invalidIp4(s) + j = parseInt(s, b, i) + if j <= 0: invalidIp4(s) + inc(i, j) + if s[i] == '.': inc(i) + else: invalidIp4(s) + j = parseInt(s, c, i) + if j <= 0: invalidIp4(s) + inc(i, j) + if s[i] == '.': inc(i) + else: invalidIp4(s) + j = parseInt(s, d, i) + if j <= 0: invalidIp4(s) + inc(i, j) + if s[i] != '\0': invalidIp4(s) + result = int32(a shl 24 or b shl 16 or c shl 8 or d) + +proc bindAddr*(socket: TSocket, port = TPort(0), address = "") = + ## binds an address/port number to a socket. + ## Use address string in dotted decimal form like "a.b.c.d" + ## or leave "" for any address. var name: Tsockaddr_in when defined(Windows): name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET name.sin_port = sockets.htons(int16(port)) - name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) + if address == "": + name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) + else: + name.sin_addr.s_addr = parseIp4(address) if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)), sizeof(name)) < 0'i32: OSError() + +when false: + proc bindAddr*(socket: TSocket, port = TPort(0)) = + ## binds a port number to a socket. + var name: Tsockaddr_in + when defined(Windows): + name.sin_family = int16(ord(AF_INET)) + else: + name.sin_family = posix.AF_INET + name.sin_port = sockets.htons(int16(port)) + name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) + if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)), + sizeof(name)) < 0'i32: + OSError() proc getSockName*(socket: TSocket): TPort = ## returns the socket's associated port number. @@ -410,6 +458,33 @@ proc send*(socket: TSocket, data: string) = if send(socket, cstring(data), data.len) != data.len: OSError() when defined(Windows): + const + SOCKET_ERROR = -1 + IOCPARM_MASK = 127 + IOC_IN = int(-2147483648) + FIONBIO = int(IOC_IN or ((sizeof(int) and IOCPARM_MASK) shl 16) or + (102 shl 8) or 126) + + proc ioctlsocket(s: TWinSocket, cmd: clong, + argptr: ptr clong): cint {. + stdcall, importc:"ioctlsocket", dynlib: "ws2_32.dll".} + +proc setBlocking*(s: TSocket, blocking: bool) = + ## sets blocking mode on socket + when defined(Windows): + var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking + if SOCKET_ERROR == ioctlsocket(TWinSocket(s), FIONBIO, addr(mode)): + OSError() + else: # BSD sockets + var x: int = fcntl(cint(s), F_GETFL, 0) + if x == -1: + OSError() + else: + var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK + if fcntl(cint(s), F_SETFL, mode) == -1: + OSError() + +when defined(Windows): var wsa: TWSADATA if WSAStartup(0x0101'i16, wsa) != 0: OSError() |