diff options
author | Jaremy Creechley <creechley@gmail.com> | 2022-12-22 13:43:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-22 21:43:27 +0100 |
commit | 3bba2b34fd632a4c01a6eb0e6f13d4e3a20bf104 (patch) | |
tree | e11f49bbb0d9e1fc7ddc4eff6315062e90fb8327 /lib | |
parent | 18c115c8d0b38e6dbb7fae5bdda94bfca1a0ecef (diff) | |
download | Nim-3bba2b34fd632a4c01a6eb0e6f13d4e3a20bf104.tar.gz |
fix socket send for string types (#21155)
* fix socket send for string types * include windows version Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/net.nim | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 1dfdbbbe6..be9f2e48c 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -1735,15 +1735,36 @@ proc send*(socket: Socket, data: pointer, size: int): int {. result = send(socket.fd, data, size, int32(MSG_NOSIGNAL)) proc send*(socket: Socket, data: string, - flags = {SocketFlag.SafeDisconn}) {.tags: [WriteIOEffect].} = - ## sends data to a socket. - let sent = send(socket, cstring(data), data.len) - if sent < 0: - let lastError = osLastError() - socketError(socket, lastError = lastError, flags = flags) - - if sent != data.len: - raiseOSError(osLastError(), "Could not send all data.") + flags = {SocketFlag.SafeDisconn}, maxRetries = 100) {.tags: [WriteIOEffect].} = + ## Sends data to a socket. Will try to send all the data by handling interrupts + ## and incomplete writes up to `maxRetries`. + var written = 0 + var attempts = 0 + while data.len - written > 0: + let sent = send(socket, cstring(data), data.len) + + if sent < 0: + let lastError = osLastError() + let isBlockingErr = + when defined(nimdoc): + false + elif useWinVersion: + lastError.int32 == WSAEINTR or + lastError.int32 == WSAEWOULDBLOCK + else: + lastError.int32 == EINTR or + lastError.int32 == EWOULDBLOCK or + lastError.int32 == EAGAIN + + if not isBlockingErr: + let lastError = osLastError() + socketError(socket, lastError = lastError, flags = flags) + else: + attempts.inc() + if attempts > maxRetries: + raiseOSError(osLastError(), "Could not send all data.") + else: + written.inc(sent) template `&=`*(socket: Socket; data: typed) = ## an alias for 'send'. |