1#
2#
3#            Nim's Runtime Library
4#        (c) Copyright 2016 Eugene Kabanov
5#
6#    See the file "copying.txt", included in this
7#    distribution, for details about the copyright.
8#
9
10from posix import Timespec
11
12when defined(macosx) or defined(freebsd) or defined(openbsd) or
13     defined(dragonfly):
14  const
15    EVFILT_READ*     = -1
16    EVFILT_WRITE*    = -2
17    EVFILT_AIO*      = -3 ## attached to aio requests
18    EVFILT_VNODE*    = -4 ## attached to vnodes
19    EVFILT_PROC*     = -5 ## attached to struct proc
20    EVFILT_SIGNAL*   = -6 ## attached to struct proc
21    EVFILT_TIMER*    = -7 ## timers
22elif defined(netbsd):
23  const
24    EVFILT_READ*     = 0
25    EVFILT_WRITE*    = 1
26    EVFILT_AIO*      = 2 ## attached to aio requests
27    EVFILT_VNODE*    = 3 ## attached to vnodes
28    EVFILT_PROC*     = 4 ## attached to struct proc
29    EVFILT_SIGNAL*   = 5 ## attached to struct proc
30    EVFILT_TIMER*    = 6 ## timers (in ms)
31when defined(macosx):
32  const
33    EVFILT_MACHPORT* = -8  ## Mach portsets
34    EVFILT_FS*       = -9  ## filesystem events
35    EVFILT_USER*     = -10 ## user events
36    EVFILT_VM        = -12 ## virtual memory events
37elif defined(freebsd):
38  const
39    EVFILT_FS*       = -9  ## filesystem events
40    EVFILT_LIO*      = -10 ## attached to lio requests
41    EVFILT_USER*     = -11 ## user events
42elif defined(dragonfly):
43  const
44    EVFILT_EXCEPT*   = -8  ## exceptional conditions
45    EVFILT_USER*     = -9  ## user events
46    EVFILT_FS*       = -10 ## filesystem events
47
48# Actions:
49const
50  EV_ADD*      = 0x0001 ## Add event to queue (implies enable).
51                        ## Re-adding an existing element modifies it.
52  EV_DELETE*   = 0x0002 ## Delete event from queue.
53  EV_ENABLE*   = 0x0004 ## Enable event.
54  EV_DISABLE*  = 0x0008 ## Disable event (not reported).
55
56# Flags:
57const
58  EV_ONESHOT*  = 0x0010 ## Only report one occurrence.
59  EV_CLEAR*    = 0x0020 ## Clear event state after reporting.
60  EV_RECEIPT*  = 0x0040 ## Force EV_ERROR on success, data == 0
61  EV_DISPATCH* = 0x0080 ## Disable event after reporting.
62
63  EV_SYSFLAGS* = 0xF000 ## Reserved by system
64  EV_DROP*     = 0x1000 ## Not should be dropped
65  EV_FLAG1*    = 0x2000 ## Filter-specific flag
66
67# Return values:
68const
69  EV_EOF*      = 0x8000 ## EOF detected
70  EV_ERROR*    = 0x4000 ## Error, data contains errno
71  EV_NODATA*   = 0x1000 ## EOF and no more data
72
73when defined(macosx) or defined(freebsd) or defined(dragonfly):
74  # EVFILT_USER is not supported by OpenBSD and NetBSD
75  #
76  # data/hint flags/masks for EVFILT_USER, shared with userspace
77  #
78  # On input, the top two bits of fflags specifies how the lower twenty four
79  # bits should be applied to the stored value of fflags.
80  #
81  # On output, the top two bits will always be set to NOTE_FFNOP and the
82  # remaining twenty four bits will contain the stored fflags value.
83  const
84    NOTE_FFNOP*      = 0x00000000'u32 ## ignore input fflags
85    NOTE_FFAND*      = 0x40000000'u32 ## AND fflags
86    NOTE_FFOR*       = 0x80000000'u32 ## OR fflags
87    NOTE_FFCOPY*     = 0xc0000000'u32 ## copy fflags
88    NOTE_FFCTRLMASK* = 0xc0000000'u32 ## masks for operations
89    NOTE_FFLAGSMASK* = 0x00ffffff'u32
90
91    NOTE_TRIGGER*    = 0x01000000'u32 ## Cause the event to be triggered
92                                      ## for output.
93
94# data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
95const
96  NOTE_LOWAT*      = 0x0001 ## low water mark
97
98# data/hint flags for EVFILT_VNODE, shared with userspace
99const
100  NOTE_DELETE*     = 0x0001 ## vnode was removed
101  NOTE_WRITE*      = 0x0002 ## data contents changed
102  NOTE_EXTEND*     = 0x0004 ## size increased
103  NOTE_ATTRIB*     = 0x0008 ## attributes changed
104  NOTE_LINK*       = 0x0010 ## link count changed
105  NOTE_RENAME*     = 0x0020 ## vnode was renamed
106  NOTE_REVOKE*     = 0x0040 ## vnode access was revoked
107
108# data/hint flags for EVFILT_PROC, shared with userspace
109const
110  NOTE_EXIT*       = 0x80000000'u32 ## process exited
111  NOTE_FORK*       = 0x40000000'u32 ## process forked
112  NOTE_EXEC*       = 0x20000000'u32 ## process exec'd
113  NOTE_PCTRLMASK*  = 0xf0000000'u32 ## mask for hint bits
114  NOTE_PDATAMASK*  = 0x000fffff'u32 ## mask for pid
115
116# additional flags for EVFILT_PROC
117const
118  NOTE_TRACK*      = 0x00000001'u32 ## follow across forks
119  NOTE_TRACKERR*   = 0x00000002'u32 ## could not track child
120  NOTE_CHILD*      = 0x00000004'u32 ## am a child process
121
122when defined(macosx) or defined(freebsd):
123  # additional flags for EVFILE_TIMER
124  const
125    NOTE_SECONDS*    = 0x00000001'u32 ## data is seconds
126    NOTE_MSECONDS*   = 0x00000002'u32 ## data is milliseconds
127    NOTE_USECONDS*   = 0x00000004'u32 ## data is microseconds
128    NOTE_NSECONDS*   = 0x00000008'u32 ## data is nanoseconds
129else:
130  # NetBSD and OpenBSD doesn't support NOTE_{TIME} constants, but
131  # support EVFILT_TIMER with granularity of milliseconds.
132  const
133    NOTE_MSECONDS*   = 0x00000000'u32
134
135type
136  ## This define not fully satisfy NetBSD "struct kevent"
137  ## but it works and tested.
138  KEvent* {.importc: "struct kevent",
139            header: """#include <sys/types.h>
140                       #include <sys/event.h>
141                       #include <sys/time.h>""", pure, final.} = object
142    ident*  : uint     ## identifier for this event  (uintptr_t)
143    filter* : cshort   ## filter for event
144    flags*  : cushort  ## general flags
145    fflags* : cuint    ## filter-specific flags
146    data*   : int      ## filter-specific data  (intptr_t)
147    udata*  : pointer  ## opaque user data identifier
148
149proc kqueue*(): cint {.importc: "kqueue", header: "<sys/event.h>".}
150  ## Creates new queue and returns its descriptor.
151
152proc kevent*(kqFD: cint,
153             changelist: ptr KEvent, nchanges: cint,
154             eventlist: ptr KEvent, nevents: cint, timeout: ptr Timespec): cint
155     {.importc: "kevent", header: "<sys/event.h>".}
156  ## Manipulates queue for given `kqFD` descriptor.
157
158proc EV_SET*(event: ptr KEvent, ident: uint, filter: cshort, flags: cushort,
159             fflags: cuint, data: int, udata: pointer)
160     {.importc: "EV_SET", header: "<sys/event.h>".}
161  ## Fills event with given data.
162