Skip to content

Commit 3118f8c

Browse files
authored
Fix cast[pointer] issues on nim-devel. (#381)
* Fix cast[pointer] issues on nim-devel. * More cast[T] fixes. * Fix compilation error. * Add oserrno.nim Further fixes for Windows and Linux. * MacOS fixes. * More Windows fixes and attempt to fix 1.2, 1.4 branches. * Implicitly import/export oserrno. * Replace oserrno with osdefs. * Return back oserrno. * epoll to oserrno. * datagram/stream to oserrno. * common to oserrno. * test to oserrno.
1 parent e05d2f8 commit 3118f8c

File tree

12 files changed

+1690
-294
lines changed

12 files changed

+1690
-294
lines changed

chronos/asyncloop.nim

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,15 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
152152
defined(openbsd) or defined(dragonfly) or defined(macos) or
153153
defined(linux) or defined(android) or defined(solaris):
154154
import "."/selectors2
155-
from posix import EINTR, EAGAIN, EINPROGRESS, EWOULDBLOCK, MSG_PEEK,
156-
MSG_NOSIGNAL,
155+
import "."/oserrno
156+
from posix import MSG_PEEK, MSG_NOSIGNAL,
157157
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
158158
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
159159
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE
160160
export SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
161161
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
162162
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE
163+
export oserrno
163164

164165
type
165166
CallbackFunc* = proc (arg: pointer) {.gcsafe, raises: [Defect].}
@@ -282,6 +283,12 @@ proc raiseOsDefect*(error: OSErrorCode, msg = "") {.noreturn, noinline.} =
282283
raise (ref Defect)(msg: msg & "\n[" & $int(error) & "] " & osErrorMsg(error) &
283284
"\n" & getStackTrace())
284285

286+
func toPointer(error: OSErrorCode): pointer =
287+
when sizeof(int) == 8:
288+
cast[pointer](uint64(uint32(error)))
289+
else:
290+
cast[pointer](uint32(error))
291+
285292
func toException*(v: OSErrorCode): ref OSError = newOSError(v)
286293
# This helper will allow to use `tryGet()` and raise OSError for
287294
# Result[T, OSErrorCode] values.
@@ -518,27 +525,30 @@ when defined(windows):
518525
## Closes a socket and ensures that it is unregistered.
519526
let loop = getThreadDispatcher()
520527
loop.handles.excl(fd)
521-
let param =
522-
if closeFd(SocketHandle(fd)) == 0:
523-
OSErrorCode(0)
524-
else:
525-
osLastError()
526-
if not isNil(aftercb):
527-
var acb = AsyncCallback(function: aftercb, udata: cast[pointer](param))
528-
loop.callbacks.addLast(acb)
528+
let
529+
param = toPointer(
530+
if closeFd(SocketHandle(fd)) == 0:
531+
OSErrorCode(0)
532+
else:
533+
osLastError()
534+
)
535+
if not(isNil(aftercb)):
536+
loop.callbacks.addLast(AsyncCallback(function: aftercb, udata: param))
529537

530538
proc closeHandle*(fd: AsyncFD, aftercb: CallbackFunc = nil) =
531539
## Closes a (pipe/file) handle and ensures that it is unregistered.
532540
let loop = getThreadDispatcher()
533541
loop.handles.excl(fd)
534-
let param =
535-
if closeFd(HANDLE(fd)) == 0:
536-
OSErrorCode(0)
537-
else:
538-
osLastError()
539-
if not isNil(aftercb):
540-
var acb = AsyncCallback(function: aftercb, udata: cast[pointer](param))
541-
loop.callbacks.addLast(acb)
542+
let
543+
param = toPointer(
544+
if closeFd(HANDLE(fd)) == 0:
545+
OSErrorCode(0)
546+
else:
547+
osLastError()
548+
)
549+
550+
if not(isNil(aftercb)):
551+
loop.callbacks.addLast(AsyncCallback(function: aftercb, udata: param))
542552

543553
proc contains*(disp: PDispatcher, fd: AsyncFD): bool =
544554
## Returns ``true`` if ``fd`` is registered in thread's dispatcher.
@@ -720,21 +730,22 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
720730
let loop = getThreadDispatcher()
721731

722732
proc continuation(udata: pointer) =
723-
let param =
724-
if SocketHandle(fd) in loop.selector:
725-
let ures = unregister2(fd)
726-
if ures.isErr():
727-
discard closeFd(cint(fd))
728-
ures.error()
729-
else:
730-
if closeFd(cint(fd)) != 0:
731-
osLastError()
733+
let
734+
param = toPointer(
735+
if SocketHandle(fd) in loop.selector:
736+
let ures = unregister2(fd)
737+
if ures.isErr():
738+
discard closeFd(cint(fd))
739+
ures.error()
732740
else:
733-
OSErrorCode(0)
734-
else:
735-
OSErrorCode(osdefs.EBADF)
736-
if not isNil(aftercb):
737-
aftercb(cast[pointer](param))
741+
if closeFd(cint(fd)) != 0:
742+
osLastError()
743+
else:
744+
OSErrorCode(0)
745+
else:
746+
OSErrorCode(osdefs.EBADF)
747+
)
748+
if not(isNil(aftercb)): aftercb(param)
738749

739750
withData(loop.selector, cint(fd), adata) do:
740751
# We are scheduling reader and writer callbacks to be called

chronos/ioselects/ioselectors_epoll.nim

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ proc getVirtualId[T](s: Selector[T]): SelectResult[int32] =
4242
ok(s.virtualHoles.popLast())
4343
else:
4444
if s.virtualId == low(int32):
45-
err(OSErrorCode(EMFILE))
45+
err(oserrno.EMFILE)
4646
else:
4747
dec(s.virtualId)
4848
ok(s.virtualId)
@@ -139,7 +139,7 @@ proc trigger2*(event: SelectEvent): SelectResult[void] =
139139
if res == -1:
140140
err(osLastError())
141141
elif res != sizeof(uint64):
142-
err(OSErrorCode(osdefs.EINVAL))
142+
err(oserrno.EINVAL)
143143
else:
144144
ok()
145145

@@ -521,11 +521,11 @@ proc prepareKey[T](s: Selector[T], event: EpollEvent): Opt[ReadyKey] =
521521

522522
if (event.events and EPOLLERR) != 0:
523523
rkey.events.incl(Event.Error)
524-
rkey.errorCode = OSErrorCode(ECONNRESET)
524+
rkey.errorCode = oserrno.ECONNRESET
525525

526526
if (event.events and EPOLLHUP) != 0 or (event.events and EPOLLRDHUP) != 0:
527527
rkey.events.incl(Event.Error)
528-
rkey.errorCode = OSErrorCode(ECONNRESET)
528+
rkey.errorCode = oserrno.ECONNRESET
529529

530530
if (event.events and EPOLLOUT) != 0:
531531
rkey.events.incl(Event.Write)
@@ -580,7 +580,8 @@ proc prepareKey[T](s: Selector[T], event: EpollEvent): Opt[ReadyKey] =
580580
let res = handleEintr(osdefs.read(fdi32, addr data, sizeof(uint64)))
581581
if res != sizeof(uint64):
582582
let errorCode = osLastError()
583-
if errorCode == EAGAIN:
583+
case errorCode
584+
of oserrno.EAGAIN:
584585
return Opt.none(ReadyKey)
585586
else:
586587
rkey.events.incl({Event.User, Event.Error})

chronos/ioselects/ioselectors_kqueue.nim

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ proc toString(key: int32|cint|SocketHandle|int): string =
5858
else:
5959
Base10.toString(uint32(fdi32))
6060

61+
proc toPointer(data: int32): pointer =
62+
when sizeof(int) == 8:
63+
cast[pointer](uint64(uint32(data)))
64+
else:
65+
cast[pointer](uint32(data))
66+
6167
template addKey[T](s: Selector[T], key: int32, skey: SelectorKey[T]) =
6268
if s.fds.hasKeyOrPut(key, skey):
6369
raiseAssert "Descriptor [" & key.toString() &
@@ -154,7 +160,7 @@ proc trigger2*(event: SelectEvent): SelectResult[void] =
154160
if res == -1:
155161
err(osLastError())
156162
elif res != sizeof(uint64):
157-
err(OSErrorCode(osdefs.EINVAL))
163+
err(oserrno.EINVAL)
158164
else:
159165
ok()
160166

@@ -310,7 +316,7 @@ proc registerSignal*[T](s: Selector[T], signal: int,
310316
# To be compatible with linux semantic we need to "eat" signals
311317
signal(cint(signal), SIG_IGN)
312318
changes.modifyKQueue(0, uint(signal), EVFILT_SIGNAL, EV_ADD, 0, 0,
313-
cast[pointer](uint32(fdi32)))
319+
fdi32.toPointer())
314320
if handleEintr(kevent(s.kqFd, addr(changes[0]), cint(1), nil, 0, nil)) == -1:
315321
let errorCode = osLastError()
316322
s.freeKey(fdi32)
@@ -341,7 +347,7 @@ proc registerProcess*[T](s: Selector[T], pid: int,
341347
s.addKey(fdi32, selectorKey)
342348

343349
changes.modifyKQueue(0, uint(uint32(pid)), EVFILT_PROC, flags, NOTE_EXIT,
344-
0, cast[pointer](uint32(fdi32)))
350+
0, fdi32.toPointer())
345351
if handleEintr(kevent(s.kqFd, addr(changes[0]), cint(1), nil, 0, nil)) == -1:
346352
s.freeKey(fdi32)
347353
return err(osLastError())
@@ -490,14 +496,14 @@ proc prepareKey[T](s: Selector[T], event: KEvent): Opt[ReadyKey] =
490496
of EVFILT_READ:
491497
if (event.flags and EV_EOF) != 0:
492498
rkey.events.incl(Event.Error)
493-
rkey.errorCode = OSErrorCode(ECONNRESET)
499+
rkey.errorCode = oserrno.ECONNRESET
494500

495501
if Event.User in pkey.events:
496502
var data: uint64 = 0
497503
if handleEintr(osdefs.read(cint(event.ident), addr data,
498504
sizeof(uint64))) != sizeof(uint64):
499505
let errorCode = osLastError()
500-
if errorCode == EAGAIN:
506+
if errorCode == oserrno.EAGAIN:
501507
# Someone already consumed event data
502508
return Opt.none(ReadyKey)
503509
else:
@@ -510,7 +516,7 @@ proc prepareKey[T](s: Selector[T], event: KEvent): Opt[ReadyKey] =
510516
of EVFILT_WRITE:
511517
if (event.flags and EV_EOF) != 0:
512518
rkey.events.incl(Event.Error)
513-
rkey.errorCode = OSErrorCode(ECONNRESET)
519+
rkey.errorCode = oserrno.ECONNRESET
514520

515521
rkey.events.incl(Event.Write)
516522

@@ -577,7 +583,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
577583
maxEventsCount, ptrTimeout)
578584
if res < 0:
579585
let errorCode = osLastError()
580-
if errorCode == EINTR:
586+
if errorCode == oserrno.EINTR:
581587
continue
582588
return err(errorCode)
583589
else:

chronos/osdefs.nim

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,60 @@
66
# Licensed under either of
77
# Apache License, version 2.0, (LICENSE-APACHEv2)
88
# MIT license (LICENSE-MIT)
9-
10-
from std/os import osLastError, osErrorMsg, OSErrorCode, raiseOSError,
11-
newOSError
12-
export osLastError, osErrorMsg, OSError, OSErrorCode, raiseOSError, newOSError
9+
import oserrno
10+
export oserrno
1311

1412
when defined(windows):
15-
from std/winlean import SocketHandle, SockLen, SockAddr, InAddr,
16-
In6_addr, Sockaddr_in, Sockaddr_in6, Sockaddr_storage,
17-
AddrInfo
18-
export SocketHandle, SockLen, SockAddr, InAddr,
19-
In6_addr, Sockaddr_in, Sockaddr_in6, Sockaddr_storage, AddrInfo
20-
2113
# Prerequisites for constants
2214
template WSAIORW*(x, y): untyped = (IOC_INOUT or x or y)
2315
template WSAIOW*(x, y): untyped =
2416
clong(-2147483648) or
2517
((clong(sizeof(int32)) and clong(IOCPARM_MASK)) shl 16) or (x shl 8) or y
2618

2719
type
20+
Sockaddr_storage* {.final, pure.} = object
21+
ss_family*: uint16
22+
ss_pad1: array[6, byte]
23+
ss_align: int64
24+
ss_pad2: array[112, byte]
25+
26+
InAddr* {.final, pure, union.} = object
27+
s_addr*: uint32
28+
29+
In6Addr* {.final, pure, union.} = object
30+
s_addr*: array[16, byte]
31+
32+
Sockaddr_in* {.final, pure.} = object
33+
sin_family*: uint16
34+
sin_port*: uint16
35+
sin_addr*: InAddr
36+
sin_zero*: array[0..7, char]
37+
38+
Sockaddr_in6* {.final, pure.} = object
39+
sin6_family*: uint16
40+
sin6_port*: uint16
41+
sin6_flowinfo*: uint32
42+
sin6_addr*: In6Addr
43+
sin6_scope_id*: uint32
44+
45+
SockLen* = cuint
46+
47+
SockAddr* {.final, pure.} = object
48+
sa_family*: uint16
49+
sa_data*: array[14, char]
50+
51+
AddrInfo* {.final, pure.} = object
52+
ai_flags*: cint ## Input flags.
53+
ai_family*: cint ## Address family of socket.
54+
ai_socktype*: cint ## Socket type.
55+
ai_protocol*: cint ## Protocol of socket.
56+
ai_addrlen*: csize_t ## Length of socket address.
57+
ai_canonname*: pointer ## Canonical name of service location.
58+
ai_addr*: ptr SockAddr ## Socket address of socket.
59+
ai_next*: ptr AddrInfo ## Pointer to next in list.
60+
61+
SocketHandle* = distinct int
62+
2863
HANDLE* = distinct uint
2964
GUID* {.final, pure.} = object
3065
D1*: uint32
@@ -104,36 +139,6 @@ when defined(windows):
104139
PIPE_UNLIMITED_INSTANCES* = 255'u32
105140
DEFAULT_PIPE_SIZE* = 65536'u32
106141

107-
ERROR_SUCCESS* = 0
108-
ERROR_FILE_NOT_FOUND* = 2
109-
ERROR_TOO_MANY_OPEN_FILES* = 4
110-
ERROR_ACCESS_DENIED* = 5
111-
ERROR_BROKEN_PIPE* = 109
112-
ERROR_BUFFER_OVERFLOW* = 111
113-
ERROR_PIPE_BUSY* = 231
114-
ERROR_NO_DATA* = 232
115-
ERROR_PIPE_NOT_CONNECTED* = 233
116-
ERROR_PIPE_CONNECTED* = 535
117-
ERROR_OPERATION_ABORTED* = 995
118-
ERROR_IO_PENDING* = 997
119-
ERROR_CONNECTION_REFUSED* = 1225
120-
ERROR_CONNECTION_ABORTED* = 1236
121-
122-
WSAEMFILE* = 10024
123-
WSAENETDOWN* = 10050
124-
WSAENETRESET* = 10052
125-
WSAECONNABORTED* = 10053
126-
WSAECONNRESET* = 10054
127-
WSAENOBUFS* = 10055
128-
WSAETIMEDOUT* = 10060
129-
WSAEADDRINUSE* = 10048
130-
WSAEDISCON* = 10101
131-
WSANOTINITIALISED* = 10093
132-
WSAENOTSOCK* = 10038
133-
WSAEINPROGRESS* = 10036
134-
WSAEINTR* = 10004
135-
WSAEWOULDBLOCK* = 10035
136-
ERROR_NETNAME_DELETED* = 64
137142
STATUS_PENDING* = 0x103
138143

139144
IOCPARM_MASK* = 0x7f'u32
@@ -1283,8 +1288,6 @@ when defined(posix):
12831288
INVALID_SOCKET* = SocketHandle(-1)
12841289
INVALID_HANDLE_VALUE* = cint(-1)
12851290

1286-
proc `==`*(x: OSErrorCode, y: int): bool =
1287-
int(x) == y
12881291
proc `==`*(x: SocketHandle, y: int): bool =
12891292
x == SocketHandle(y)
12901293

0 commit comments

Comments
 (0)