summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndrey Sobolev <andrey.sobolev@xored.com>2015-09-16 22:01:18 +0600
committerAndrey Sobolev <andrey.sobolev@xored.com>2015-09-16 22:01:18 +0600
commit5859fcbabbe31a53635dd75e5f0b7ab3883d46fa (patch)
treec1812be42b2f7aa70a0824c3fa360d84c22e9e74 /lib
parentbbf77e1d232f6da4799a70cb9a2391163d7ed58d (diff)
parent671e5db21e49fa4efbfe46a5215673f5826b25c3 (diff)
downloadNim-5859fcbabbe31a53635dd75e5f0b7ab3883d46fa.tar.gz
Merge remote-tracking branch 'nim-lang/devel' into emscripten-support
Diffstat (limited to 'lib')
-rw-r--r--lib/posix/posix.nim2
-rw-r--r--lib/pure/net.nim12
-rw-r--r--lib/pure/rawsockets.nim70
-rw-r--r--lib/system.nim25
-rw-r--r--lib/windows/winlean.nim8
5 files changed, 107 insertions, 10 deletions
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index d264dc02a..8486fa04f 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -2316,7 +2316,7 @@ proc timer_settime*(a1: Timer, a2: cint, a3: var Itimerspec,
 proc tzset*() {.importc, header: "<time.h>".}
 
 
-proc wait*(a1: var cint): Pid {.importc, header: "<sys/wait.h>".}
+proc wait*(a1: ptr cint): Pid {.importc, discardable, header: "<sys/wait.h>".}
 proc waitid*(a1: cint, a2: Id, a3: var SigInfo, a4: cint): cint {.
   importc, header: "<sys/wait.h>".}
 proc waitpid*(a1: Pid, a2: var cint, a3: cint): Pid {.
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 141543c70..0ce5b4d25 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -533,6 +533,18 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
   var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
   result = res != 0
 
+proc getLocalAddr*(socket: Socket): (string, Port) =
+  ## Get the socket's local address and port number.
+  ##
+  ## This is high-level interface for `getsockname`:idx:.
+  getLocalAddr(socket.fd, socket.domain)
+
+proc getPeerAddr*(socket: Socket): (string, Port) =
+  ## Get the socket's peer address and port number.
+  ##
+  ## This is high-level interface for `getpeername`:idx:.
+  getPeerAddr(socket.fd, socket.domain)
+
 proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {.
   tags: [WriteIOEffect].} =
   ## Sets option ``opt`` to a boolean value specified by ``value``.
diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim
index 7873e7226..f5860ef28 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/rawsockets.nim
@@ -371,6 +371,76 @@ proc getSockName*(socket: SocketHandle): Port =
     raiseOSError(osLastError())
   result = Port(rawsockets.ntohs(name.sin_port))
 
+proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+  ## returns the socket's local address and port number.
+  ##
+  ## Similar to POSIX's `getsockname`:idx:.
+  case domain
+  of AF_INET:
+    var name: Sockaddr_in
+    when useWinVersion:
+      name.sin_family = int16(ord(AF_INET))
+    else:
+      name.sin_family = posix.AF_INET
+    var namelen = sizeof(name).SockLen
+    if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
+  of AF_INET6:
+    var name: Sockaddr_in6
+    when useWinVersion:
+      name.sin6_family = int16(ord(AF_INET6))
+    else:
+      name.sin6_family = posix.AF_INET6
+    var namelen = sizeof(name).SockLen
+    if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
+    var buf: array[64, char]
+    if inet_ntop(name.sin6_family.cint,
+                 addr name, buf.cstring, sizeof(buf).int32).isNil:
+      raiseOSError(osLastError())
+    result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
+  else:
+    raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
+proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+  ## returns the socket's peer address and port number.
+  ##
+  ## Similar to POSIX's `getpeername`:idx:
+  case domain
+  of AF_INET:
+    var name: Sockaddr_in
+    when useWinVersion:
+      name.sin_family = int16(ord(AF_INET))
+    else:
+      name.sin_family = posix.AF_INET
+    var namelen = sizeof(name).SockLen
+    if getpeername(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
+  of AF_INET6:
+    var name: Sockaddr_in6
+    when useWinVersion:
+      name.sin6_family = int16(ord(AF_INET6))
+    else:
+      name.sin6_family = posix.AF_INET6
+    var namelen = sizeof(name).SockLen
+    if getpeername(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
+    var buf: array[64, char]
+    if inet_ntop(name.sin6_family.cint,
+                 addr name, buf.cstring, sizeof(buf).int32).isNil:
+      raiseOSError(osLastError())
+    result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
+  else:
+    raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
 proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
   tags: [ReadIOEffect].} =
   ## getsockopt for integer options.
diff --git a/lib/system.nim b/lib/system.nim
index 1890ce5be..8f529b8c0 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -78,7 +78,7 @@ type
   stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates)
   typedesc* {.magic: TypeDesc.} ## meta type to denote a type description
   void* {.magic: "VoidType".}   ## meta type to denote the absence of any type
-  auto* = expr ## meta type for automatic type determination
+  auto* {.magic: Expr.} ## meta type for automatic type determination
   any* = distinct auto ## meta type for any supported type
   untyped* {.magic: Expr.} ## meta type to denote an expression that
                            ## is not resolved (for templates)
@@ -104,7 +104,7 @@ type
   SomeNumber* = SomeInteger|SomeReal
     ## type class matching all number types
 
-proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.}
+proc defined*(x: expr): bool {.magic: "Defined", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## defined.
   ## `x` is an external symbol introduced through the compiler's
@@ -125,7 +125,7 @@ when defined(nimalias):
     TNumber: SomeNumber,
     TOrdinal: SomeOrdinal].}
 
-proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.}
+proc declared*(x: expr): bool {.magic: "Defined", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## declared. `x` has to be an identifier or a qualified identifier.
   ## This can be used to check whether a library provides a certain
@@ -140,11 +140,11 @@ when defined(useNimRtl):
   {.deadCodeElim: on.}
 
 proc definedInScope*(x: expr): bool {.
-  magic: "DefinedInScope", noSideEffect, deprecated.}
+  magic: "DefinedInScope", noSideEffect, deprecated, compileTime.}
   ## **Deprecated since version 0.9.6**: Use ``declaredInScope`` instead.
 
 proc declaredInScope*(x: expr): bool {.
-  magic: "DefinedInScope", noSideEffect.}
+  magic: "DefinedInScope", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## declared in the current scope. `x` has to be an identifier.
 
@@ -160,7 +160,7 @@ proc unsafeAddr*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} =
   ## Cannot be overloaded.
   discard
 
-proc `type`*(x: expr): typeDesc {.magic: "TypeOf", noSideEffect.} =
+proc `type`*(x: expr): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
   ## Builtin 'type' operator for accessing the type of an expression.
   ## Cannot be overloaded.
   discard
@@ -239,6 +239,14 @@ type
   seq*{.magic: "Seq".}[T]  ## Generic type to construct sequences.
   set*{.magic: "Set".}[T]  ## Generic type to construct bit sets.
 
+when defined(nimArrIdx):
+  # :array|openarray|string|seq|cstring|tuple
+  proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
+    noSideEffect, magic: "ArrGet".}
+  proc `[]=`*[I: Ordinal;T,S](a: var T; i: I;
+    x: S) {.noSideEffect, magic: "ArrPut".}
+  proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
+
 type
   Slice*[T] = object ## builtin slice type
     a*, b*: T        ## the bounds
@@ -3384,7 +3392,7 @@ when hasAlloc:
       x[j+i] = item[j]
       inc(j)
 
-proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
+proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect, compileTime.} =
   ## Special compile-time procedure that checks whether `x` can be compiled
   ## without any semantic error.
   ## This can be used to check whether a type supports some operation:
@@ -3448,7 +3456,7 @@ when hasAlloc and not defined(nimscript) and not defined(JS):
 
   include "system/deepcopy"
 
-proc procCall*(x: expr) {.magic: "ProcCall".} =
+proc procCall*(x: expr) {.magic: "ProcCall", compileTime.} =
   ## special magic to prohibit dynamic binding for `method`:idx: calls.
   ## This is similar to `super`:idx: in ordinary OO languages.
   ##
@@ -3457,6 +3465,7 @@ proc procCall*(x: expr) {.magic: "ProcCall".} =
   ##   procCall someMethod(a, b)
   discard
 
+proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".}
 proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} =
   ## builtin `roof`:idx: operator that can be used for convenient array access.
   ## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a``
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 24015dd3a..84dac6d79 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -409,7 +409,7 @@ type
     bytes*: array[0..15, char]
 
   Sockaddr_in6* {.importc: "SOCKADDR_IN6",
-                   header: "winsock2.h".} = object
+                   header: "ws2tcpip.h".} = object
     sin6_family*: int16
     sin6_port*: int16 # unsigned
     sin6_flowinfo*: int32 # unsigned
@@ -511,6 +511,9 @@ proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
 proc getsockname*(s: SocketHandle, name: ptr SockAddr,
                   namelen: ptr SockLen): cint {.
   stdcall, importc: "getsockname", dynlib: ws2dll.}
+proc getpeername*(s: SocketHandle, name: ptr SockAddr,
+                  namelen: ptr SockLen): cint {.
+  stdcall, importc, dynlib: ws2dll.}
 proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
                  optlen: ptr SockLen): cint {.
   stdcall, importc: "getsockopt", dynlib: ws2dll.}
@@ -572,6 +575,9 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
 proc inet_ntoa*(i: InAddr): cstring {.
   stdcall, importc, dynlib: ws2dll.}
 
+proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
+            stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
+
 const
   MAXIMUM_WAIT_OBJECTS* = 0x00000040