1 /**
2  * D header file for FreeBSD.
3  *
4  * Copyright: Copyright Martin Nowak 2012.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Martin Nowak
7  */
8 
9 /*          Copyright Martin Nowak 2012.
10  * Distributed under the Boost Software License, Version 1.0.
11  *    (See accompanying file LICENSE or copy at
12  *          http://www.boost.org/LICENSE_1_0.txt)
13  */
14 module core.sys.freebsd.sys.event;
15 
16 version (FreeBSD):
17 extern (C):
18 nothrow:
19 @nogc:
20 
21 import core.sys.freebsd.config;
22 import core.stdc.stdint;    // intptr_t, uintptr_t
23 import core.sys.posix.time; // timespec
24 
25 enum
26 {
27     EVFILT_READ     =  -1,
28     EVFILT_WRITE    =  -2,
29     EVFILT_AIO      =  -3, /* attached to aio requests */
30     EVFILT_VNODE    =  -4, /* attached to vnodes */
31     EVFILT_PROC     =  -5, /* attached to struct proc */
32     EVFILT_SIGNAL   =  -6, /* attached to struct proc */
33     EVFILT_TIMER    =  -7, /* timers */
34     EVFILT_PROCDESC =  -8, /* attached to process descriptors */
35     EVFILT_FS       =  -9, /* filesystem events */
36     EVFILT_LIO      = -10, /* attached to lio requests */
37     EVFILT_USER     = -11, /* User events */
38     EVFILT_SENDFILE = -12, /* attached to sendfile requests */
39     EVFILT_SYSCOUNT =  11,
40 }
41 
42 static if (__FreeBSD_version >= 1200000)
43 {
44     struct kevent_t
45     {
46         uintptr_t ident;
47         short     filter;
48         ushort    flags;
49         uint      fflags;
50         long      data;
51         void*     udata;
52         ulong[4]  ext;
53     }
54 }
55 else
56 {
57     struct kevent_t
58     {
59         uintptr_t    ident; /* identifier for this event */
60         short       filter; /* filter for event */
61         ushort       flags;
62         uint        fflags;
63         intptr_t      data;
64         void        *udata; /* opaque user data identifier */
65     }
66 }
67 
68 extern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)
69 {
70     *kevp = kevent_t(args);
71 }
72 
73 enum
74 {
75     /* actions */
76     EV_ADD          = 0x0001, /* add event to kq (implies enable) */
77     EV_DELETE       = 0x0002, /* delete event from kq */
78     EV_ENABLE       = 0x0004, /* enable event */
79     EV_DISABLE      = 0x0008, /* disable event (not reported) */
80     EV_FORCEONESHOT = 0x0100,          /* enable _ONESHOT and force trigger */
81 
82     /* flags */
83     EV_ONESHOT      = 0x0010, /* only report one occurrence */
84     EV_CLEAR        = 0x0020, /* clear event state after reporting */
85     EV_RECEIPT      = 0x0040, /* force EV_ERROR on success, data=0 */
86     EV_DISPATCH     = 0x0080, /* disable event after reporting */
87 
88     EV_SYSFLAGS     = 0xF000, /* reserved by system */
89     EV_DROP         = 0x1000, /* note should be dropped */
90     EV_FLAG1        = 0x2000, /* filter-specific flag */
91     EV_FLAG2        = 0x4000, /* filter-specific flag */
92 
93     /* returned values */
94     EV_EOF          = 0x8000, /* EOF detected */
95     EV_ERROR        = 0x4000, /* error, data contains errno */
96 }
97 
98 enum
99 {
100     /*
101      * data/hint flags/masks for EVFILT_USER, shared with userspace
102      *
103      * On input, the top two bits of fflags specifies how the lower twenty four
104      * bits should be applied to the stored value of fflags.
105      *
106      * On output, the top two bits will always be set to NOTE_FFNOP and the
107      * remaining twenty four bits will contain the stored fflags value.
108      */
109     NOTE_FFNOP      = 0x00000000, /* ignore input fflags */
110     NOTE_FFAND      = 0x40000000, /* AND fflags */
111     NOTE_FFOR       = 0x80000000, /* OR fflags */
112     NOTE_FFCOPY     = 0xc0000000, /* copy fflags */
113     NOTE_FFCTRLMASK = 0xc0000000, /* masks for operations */
114     NOTE_FFLAGSMASK = 0x00ffffff,
115 
116     NOTE_TRIGGER    = 0x01000000, /* Cause the event to be
117                                   triggered for output. */
118 
119     /*
120      * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
121      */
122     NOTE_LOWAT      = 0x0001, /* low water mark */
123     NOTE_FILE_POLL  = 0x0002, /* behave like poll() */
124 
125     /*
126      * data/hint flags for EVFILT_VNODE, shared with userspace
127      */
128     NOTE_DELETE     = 0x0001, /* vnode was removed */
129     NOTE_WRITE      = 0x0002, /* data contents changed */
130     NOTE_EXTEND     = 0x0004, /* size increased */
131     NOTE_ATTRIB     = 0x0008, /* attributes changed */
132     NOTE_LINK       = 0x0010, /* link count changed */
133     NOTE_RENAME     = 0x0020, /* vnode was renamed */
134     NOTE_REVOKE     = 0x0040, /* vnode access was revoked */
135     NOTE_OPEN       = 0x0080, /* vnode was opened */
136     NOTE_CLOSE      = 0x0100, /* file closed, fd did not
137                                  allowed write */
138     NOTE_CLOSE_WRITE = 0x0200, /* file closed, fd did allowed
139                                   write */
140     NOTE_READ       = 0x0400, /* file was read */
141 
142     /*
143      * data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace
144      */
145     NOTE_EXIT       = 0x80000000, /* process exited */
146     NOTE_FORK       = 0x40000000, /* process forked */
147     NOTE_EXEC       = 0x20000000, /* process exec'd */
148     NOTE_PCTRLMASK  = 0xf0000000, /* mask for hint bits */
149     NOTE_PDATAMASK  = 0x000fffff, /* mask for pid */
150 
151     /* additional flags for EVFILT_PROC */
152     NOTE_TRACK      = 0x00000001, /* follow across forks */
153     NOTE_TRACKERR   = 0x00000002, /* could not track child */
154     NOTE_CHILD      = 0x00000004, /* am a child process */
155 
156     /* additional flags for EVFILT_TIMER */
157     NOTE_SECONDS    = 0x00000001, /* data is seconds */
158     NOTE_MSECONDS   = 0x00000002, /* data is milliseconds */
159     NOTE_USECONDS   = 0x00000004, /* data is microseconds */
160     NOTE_NSECONDS   = 0x00000008, /* data is nanoseconds */
161 }
162 
163 int kqueue();
164 
165 version (GNU)
166 {
167     int kevent(int kq, const kevent_t *changelist, int nchanges,
168                kevent_t *eventlist, int nevents,
169                const timespec *timeout);
170 }
171 else
172 {
173     static if (__FreeBSD_version >= 1200000)
174         pragma(mangle, "kevent@@FBSD_1.5")
175         int kevent(int kq, const kevent_t *changelist, int nchanges,
176                    kevent_t *eventlist, int nevents,
177                    const timespec *timeout);
178     else
179         pragma(mangle, "kevent@FBSD_1.0")
180         int kevent(int kq, const kevent_t *changelist, int nchanges,
181                    kevent_t *eventlist, int nevents,
182                    const timespec *timeout);
183 }