summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-04-03 10:25:26 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-04-03 10:25:26 +0200
commit8b0ea4b501125880bce54f20839b443973bba0c4 (patch)
tree1b87391d3ca92269a1972410938643e4c2b03e4a /lib
parentd8373622165f9dbdf12eef8c81204f35a376ff76 (diff)
parent0b99e8e8cb8dfe3de8d3fa38cc48f919acd0fe4c (diff)
downloadNim-8b0ea4b501125880bce54f20839b443973bba0c4.tar.gz
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'lib')
-rw-r--r--lib/posix/posix_linux_amd64_consts.nim3
-rw-r--r--lib/posix/posix_other_consts.nim3
-rw-r--r--lib/pure/ioselects/ioselectors_epoll.nim6
-rw-r--r--lib/pure/ioselects/ioselectors_poll.nim6
-rw-r--r--lib/pure/nativesockets.nim2
-rw-r--r--lib/pure/net.nim37
-rw-r--r--lib/pure/osproc.nim8
-rw-r--r--lib/pure/times.nim12
-rw-r--r--lib/windows/winlean.nim12
9 files changed, 79 insertions, 10 deletions
diff --git a/lib/posix/posix_linux_amd64_consts.nim b/lib/posix/posix_linux_amd64_consts.nim
index 4b693960e..ee4fac1e8 100644
--- a/lib/posix/posix_linux_amd64_consts.nim
+++ b/lib/posix/posix_linux_amd64_consts.nim
@@ -433,6 +433,9 @@ const POSIX_MADV_WILLNEED* = cint(3)
 const POSIX_MADV_DONTNEED* = cint(4)
 const MAP_POPULATE* = cint(32768)
 
+# <sys/resource.h>
+const RLIMIT_NOFILE* = cint(7)
+
 # <sys/select.h>
 const FD_SETSIZE* = cint(1024)
 
diff --git a/lib/posix/posix_other_consts.nim b/lib/posix/posix_other_consts.nim
index 003414a6a..1b27fc5f6 100644
--- a/lib/posix/posix_other_consts.nim
+++ b/lib/posix/posix_other_consts.nim
@@ -451,6 +451,9 @@ var POSIX_TYPED_MEM_ALLOCATE* {.importc: "POSIX_TYPED_MEM_ALLOCATE", header: "<s
 var POSIX_TYPED_MEM_ALLOCATE_CONTIG* {.importc: "POSIX_TYPED_MEM_ALLOCATE_CONTIG", header: "<sys/mman.h>".}: cint
 var POSIX_TYPED_MEM_MAP_ALLOCATABLE* {.importc: "POSIX_TYPED_MEM_MAP_ALLOCATABLE", header: "<sys/mman.h>".}: cint
 
+# <sys/resource.h>
+var RLIMIT_NOFILE* {.importc: "RLIMIT_NOFILE", header: "<sys/resource.h>".}: cint
+
 # <sys/select.h>
 var FD_SETSIZE* {.importc: "FD_SETSIZE", header: "<sys/select.h>".}: cint
 
diff --git a/lib/pure/ioselects/ioselectors_epoll.nim b/lib/pure/ioselects/ioselectors_epoll.nim
index 98b8a2b2b..65efeabab 100644
--- a/lib/pure/ioselects/ioselectors_epoll.nim
+++ b/lib/pure/ioselects/ioselectors_epoll.nim
@@ -48,8 +48,6 @@ when not defined(android):
   proc signalfd(fd: cint, mask: var Sigset, flags: cint): cint
        {.cdecl, importc: "signalfd", header: "<sys/signalfd.h>".}
 
-var RLIMIT_NOFILE {.importc: "RLIMIT_NOFILE",
-                    header: "<sys/resource.h>".}: cint
 type
   RLimit {.importc: "struct rlimit",
            header: "<sys/resource.h>", pure, final.} = object
@@ -82,7 +80,7 @@ type
 proc newSelector*[T](): Selector[T] =
   # Retrieve the maximum fd count (for current OS) via getrlimit()
   var a = RLimit()
-  if getrlimit(RLIMIT_NOFILE, a) != 0:
+  if getrlimit(posix.RLIMIT_NOFILE, a) != 0:
     raiseOsError(osLastError())
   var maxFD = int(a.rlim_max)
   doAssert(maxFD > 0)
@@ -528,4 +526,4 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1,
     body2
 
 proc getFd*[T](s: Selector[T]): int =
-  return s.epollFd.int
\ No newline at end of file
+  return s.epollFd.int
diff --git a/lib/pure/ioselects/ioselectors_poll.nim b/lib/pure/ioselects/ioselectors_poll.nim
index 66d52b352..081c57fa6 100644
--- a/lib/pure/ioselects/ioselectors_poll.nim
+++ b/lib/pure/ioselects/ioselectors_poll.nim
@@ -40,8 +40,6 @@ type
     wfd: cint
   SelectEvent* = ptr SelectEventImpl
 
-var RLIMIT_NOFILE {.importc: "RLIMIT_NOFILE",
-                    header: "<sys/resource.h>".}: cint
 type
   rlimit {.importc: "struct rlimit",
            header: "<sys/resource.h>", pure, final.} = object
@@ -64,7 +62,7 @@ else:
 
 proc newSelector*[T](): Selector[T] =
   var a = rlimit()
-  if getrlimit(RLIMIT_NOFILE, a) != 0:
+  if getrlimit(posix.RLIMIT_NOFILE, a) != 0:
     raiseIOSelectorsError(osLastError())
   var maxFD = int(a.rlim_max)
 
@@ -317,4 +315,4 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1,
 
 
 proc getFd*[T](s: Selector[T]): int =
-  return -1
\ No newline at end of file
+  return -1
diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim
index 280c4e927..68061853b 100644
--- a/lib/pure/nativesockets.nim
+++ b/lib/pure/nativesockets.nim
@@ -31,7 +31,7 @@ else:
   export Sockaddr_storage, Sockaddr_un, Sockaddr_un_path_length
 
 export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen,
-  Sockaddr_in6,
+  Sockaddr_in6, Sockaddr_storage,
   inet_ntoa, recv, `==`, connect, send, accept, recvfrom, sendto,
   freeAddrInfo
 
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 2d1ca8a59..ccf02a1fc 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -414,6 +414,43 @@ proc isIpAddress*(address_str: string): bool {.tags: [].} =
     return false
   return true
 
+proc toSockAddr*(address: IpAddress, port: Port, sa: var Sockaddr_storage, sl: var Socklen) =
+  ## Converts `IpAddress` and `Port` to `SockAddr` and `Socklen`
+  let port = htons(uint16(port))
+  case address.family
+  of IpAddressFamily.IPv4:
+    sl = sizeof(Sockaddr_in).Socklen
+    let s = cast[ptr Sockaddr_in](addr sa)
+    s.sin_family = type(s.sin_family)(AF_INET)
+    s.sin_port = port
+    copyMem(addr s.sin_addr, unsafeAddr address.address_v4[0], sizeof(s.sin_addr))
+  of IpAddressFamily.IPv6:
+    sl = sizeof(Sockaddr_in6).Socklen
+    let s = cast[ptr Sockaddr_in6](addr sa)
+    s.sin6_family = type(s.sin6_family)(AF_INET6)
+    s.sin6_port = port
+    copyMem(addr s.sin6_addr, unsafeAddr address.address_v6[0], sizeof(s.sin6_addr))
+
+proc fromSockAddrAux(sa: ptr Sockaddr_storage, sl: Socklen, address: var IpAddress, port: var Port) =
+  if sa.ss_family.int == AF_INET.int and sl == sizeof(Sockaddr_in).Socklen:
+    address = IpAddress(family: IpAddressFamily.IPv4)
+    let s = cast[ptr Sockaddr_in](sa)
+    copyMem(addr address.address_v4[0], addr s.sin_addr, sizeof(address.address_v4))
+    port = ntohs(s.sin_port).Port
+  elif sa.ss_family.int == AF_INET6.int and sl == sizeof(Sockaddr_in6).Socklen:
+    address = IpAddress(family: IpAddressFamily.IPv6)
+    let s = cast[ptr Sockaddr_in6](sa)
+    copyMem(addr address.address_v6[0], addr s.sin6_addr, sizeof(address.address_v6))
+    port = ntohs(s.sin6_port).Port
+  else:
+    raise newException(ValueError, "Neither IPv4 nor IPv6")
+
+proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6,
+    sl: Socklen, address: var IpAddress, port: var Port) {.inline.} =
+  ## Converts `SockAddr` and `Socklen` to `IpAddress` and `Port`. Raises
+  ## `ObjectConversionError` in case of invalid `sa` and `sl` arguments.
+  fromSockAddrAux(unsafeAddr sa, sl, address, port)
+
 when defineSsl:
   CRYPTO_malloc_init()
   doAssert SslLibraryInit() == 1
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index c1c727fc6..555626514 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -494,7 +494,7 @@ when defined(Windows) and not defined(useNimRtl):
     sa.nLength = sizeof(SECURITY_ATTRIBUTES).cint
     sa.lpSecurityDescriptor = nil
     sa.bInheritHandle = 1
-    if createPipe(rdHandle, wrHandle, sa, 1024) == 0'i32:
+    if createPipe(rdHandle, wrHandle, sa, 0) == 0'i32:
       raiseOSError(osLastError())
 
   proc fileClose(h: Handle) {.inline.} =
@@ -524,6 +524,12 @@ when defined(Windows) and not defined(useNimRtl):
           he = ho
         else:
           createPipeHandles(he, si.hStdError)
+          if setHandleInformation(he, DWORD(1), DWORD(0)) == 0'i32:
+            raiseOsError(osLastError())
+        if setHandleInformation(hi, DWORD(1), DWORD(0)) == 0'i32:
+          raiseOsError(osLastError())  
+        if setHandleInformation(ho, DWORD(1), DWORD(0)) == 0'i32:
+          raiseOsError(osLastError())
       else:
         createAllPipeHandles(si, hi, ho, he, cast[int](result))
       result.inHandle = FileHandle(hi)
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 6c1e1fe87..75b5bac43 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -274,6 +274,18 @@ proc toTime*(dt: DateTime): Time {.tags: [], raises: [], benign.} =
   # so we need to compensate for that here.
   result.inc dt.utcOffset
 
+proc `<`*(a, b: DateTime): bool =
+  ## Returns true iff ``a < b``, that is iff a happened before b.
+  return a.toTime < b.toTime
+
+proc `<=` * (a, b: DateTime): bool =
+  ## Returns true iff ``a <= b``.
+  return a.toTime <= b.toTime
+
+proc `==`*(a, b: DateTime): bool =
+  ## Returns true if ``a == b``, that is if both dates represent the same point in datetime.
+  return a.toTime == b.toTime
+
 proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
   let adjTime = zt.adjTime.int64
   let epochday = (if adjTime >= 0: adjTime else: adjTime - (secondsInDay - 1)) div secondsInDay
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index b2c1cc1f5..f40344396 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -481,6 +481,13 @@ type
     sin6_flowinfo*: int32 # unsigned
     sin6_addr*: In6_addr
 
+  Sockaddr_storage* {.importc: "SOCKADDR_STORAGE",
+                      header: "winsock2.h".} = object
+    ss_family*: int16
+    ss_pad1: array[6, byte]
+    ss_align: int64
+    ss_pad2: array[112, byte]
+
   Servent* = object
     s_name*: cstring
     s_aliases*: cstringArray
@@ -697,6 +704,11 @@ proc duplicateHandle*(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE,
                       dwDesiredAccess: DWORD, bInheritHandle: WINBOOL,
                       dwOptions: DWORD): WINBOOL{.stdcall, dynlib: "kernel32",
     importc: "DuplicateHandle".}
+
+proc setHandleInformation*(hObject: HANDLE, dwMask: DWORD,
+                           dwFlags: DWORD): WINBOOL {.stdcall,
+    dynlib: "kernel32", importc: "SetHandleInformation".}
+
 proc getCurrentProcess*(): HANDLE{.stdcall, dynlib: "kernel32",
                                    importc: "GetCurrentProcess".}