Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

298 lines
11 KiB
C

/*-
* Copyright (c) 2009 Mark Heily <mark@heily.com>
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD SVN Revision 197533$
*/
#ifndef _SYS_EVENT_H_
#define _SYS_EVENT_H_
#include <sys/types.h>
#ifdef __KERNEL__
#define intptr_t long
#else
#include <sys/types.h>
#if defined(_WIN32) && _MSC_VER < 1600 && !defined(__MINGW32__)
# include "../../src/windows/stdint.h"
#else
# include <stdint.h>
#endif
#define LIBKQUEUE 1
#endif
struct timespec;
/** Populate a kevent structure in the <em>changelist</em>
*
* @param[in] _kevp The kevent structure to populate.
* @param[in] _ident The unique identifier for this event.
* @param[in] _filter The unique identifier for this event.
* @param[in] _flags Filter specific flags.
* @param[in] _data Additional data for the filter.
* @param[in] _udata Opaque user data identifier. Not interpreted by libkqueue.
*/
#define EV_SET(_kevp, _ident, _filter, _flags, _fflags, _data, _udata) do { \
struct kevent *kevp = (_kevp); \
(kevp)->ident = (_ident); \
(kevp)->filter = (_filter); \
(kevp)->flags = (_flags); \
(kevp)->fflags = (_fflags); \
(kevp)->data = (_data); \
(kevp)->udata = (_udata); \
} while(0)
/** Structure to hold an event registration or notification
*
* A list of kevent structures are passed in by the application as the <em>changelist</em>
* to set which notifications the application wishes to received.
*
* A list of kevent structures are passed back to the application as the <em>eventlist</em>
* to inform the application of events which occurred or of filter states.
*/
struct kevent {
uintptr_t ident; //!< The unique identifier (within a given filter)
///< for this event, usually a PID, FD, signal or
///< other unique identifier.
///< The type of identifier passed depends on the
///< filter.
short filter; //!< Filter for this event.
unsigned short flags; //!< One or more of the EV_* macros or'd together.
unsigned int fflags; //!< Filter specific flags.
intptr_t data; //!< Additional data for the filter.
void *udata; //!< Opaque user data identifier.
};
/** @name Filters
*
* @{
*/
#define EVFILT_READ (-1) //!< Read I/O event.
#define EVFILT_WRITE (-2) //!< Write I/O event.
#define EVFILT_AIO (-3) //!< Attached to aio requests.
#define EVFILT_VNODE (-4) //!< Attached to vnodes.
#define EVFILT_PROC (-5) //!< attached to struct proc.
#define EVFILT_SIGNAL (-6) //!< Attached to struct proc.
#define EVFILT_TIMER (-7) //!< Timers.
#define EVFILT_NETDEV (-8) //!< Network devices.
#define EVFILT_FS (-9) //!< Filesystem events.
#define EVFILT_LIO (-10) //!< Attached to lio requests.
#define EVFILT_USER (-11) //!< User events.
#define EVFILT_LIBKQUEUE (-12) //!< libkqueue specific filter.
#define EVFILT_SYSCOUNT 12
/** @} */
/** @name Actions
*
* @{
*/
#define EV_ADD 0x0001 //!< Add event to kq (implies enable).
#define EV_DELETE 0x0002 //!< Delete event from kq.
#define EV_ENABLE 0x0004 //!< Enable event.
#define EV_DISABLE 0x0008 //!< Disable event (not reported).
/** @} */
/** @name Flags
*
* @{
*/
#define EV_ONESHOT 0x0010 //!< Only report one occurrence.
#define EV_CLEAR 0x0020 //!< Clear event state after reporting.
#define EV_RECEIPT 0x0040 //!< Force EV_ERROR on success, data=0.
#define EV_DISPATCH 0x0080 //!< Disable event after reporting.
#define EV_SYSFLAGS 0xF000 //!< Reserved by system.
#define EV_FLAG1 0x2000 //!< Filter-specific flag.
/** @} */
/** @name Returned values
*
* @{
*/
#define EV_EOF 0x8000 //!< EOF detected.
#define EV_ERROR 0x4000 //!< Error, data contains errno.
/** @} */
/** @name Data/hint flags/masks for EVFILT_USER
*
* On input, the top two bits of fflags specifies how the lower twenty four
* bits should be applied to the stored value of fflags.
*
* On output, the top two bits will always be set to NOTE_FFNOP and the
* remaining twenty four bits will contain the stored fflags value.
* @{
*/
#define NOTE_FFNOP 0x00000000 //!< Ignore input fflags.
#define NOTE_FFAND 0x40000000 //!< AND fflags.
#define NOTE_FFOR 0x80000000 //!< OR fflags.
#define NOTE_FFCOPY 0xc0000000 //!< Copy fflags.
#define NOTE_FFCTRLMASK 0xc0000000 //!< Masks for operations.
#define NOTE_FFLAGSMASK 0x00ffffff
#define NOTE_TRIGGER 0x01000000 //!< Cause the event to be triggered for output.
/** @} */
/** @name Data/hint flags for EVFILT_{READ|WRITE}
*
* @{
*/
#define NOTE_LOWAT 0x0001 //!< Low water mark.
#undef NOTE_LOWAT /* Not supported on Linux */
/** @} */
/** @name Data/hint flags for EVFILT_VNODE
*
* @{
*/
#define NOTE_DELETE 0x0001 //!< Vnode was removed.
#define NOTE_WRITE 0x0002 //!< Data contents changed.
#define NOTE_EXTEND 0x0004 //!< Size increased.
#define NOTE_ATTRIB 0x0008 //!< Attributes changed.
#define NOTE_LINK 0x0010 //!< Link count changed.
#define NOTE_RENAME 0x0020 //!< Vnode was renamed.
#define NOTE_REVOKE 0x0040 //!< Vnode access was revoked.
#undef NOTE_REVOKE /* Not supported on Linux */
/** @} */
/** @name Data/hint flags for EVFILT_PROC
*
* @{
*/
#define NOTE_EXIT 0x80000000 //!< Process exited.
#define NOTE_FORK 0x40000000 //!< Process forked.
#define NOTE_EXEC 0x20000000 //!< Process exec'd.
#define NOTE_PCTRLMASK 0xf0000000 //!< Mask for hint bits.
#define NOTE_PDATAMASK 0x000fffff //!< Mask for pid.
/** @} */
/** @name Additional flags for EVFILT_PROC
*
* @{
*/
#define NOTE_TRACK 0x00000001 //!< Follow across forks.
#define NOTE_TRACKERR 0x00000002 //!< Could not track child.
#define NOTE_CHILD 0x00000004 //!< Am a child process.
/** @} */
/** @name Data/hint flags for EVFILT_NETDEV
*
* @{
*/
#define NOTE_LINKUP 0x0001 //!< Link is up.
#define NOTE_LINKDOWN 0x0002 //!< Link is down.
#define NOTE_LINKINV 0x0004 //!< Link state is invalid.
/** @} */
/** @name vfsquery flags
*
* @note KLUDGE: This is from <sys/mount.h> on FreeBSD and is used by the EVFILT_FS filter.
*
* @{
*/
#define VQ_NOTRESP 0x0001 //!< Server down.
#define VQ_NEEDAUTH 0x0002 //!< server bad auth.
#define VQ_LOWDISK 0x0004 //!< we're low on space.
#define VQ_MOUNT 0x0008 //!< new filesystem arrived.
#define VQ_UNMOUNT 0x0010 //!< filesystem has left.
#define VQ_DEAD 0x0020 //!< filesystem is dead, needs force unmount.
#define VQ_ASSIST 0x0040 //!< filesystem needs assistance from external program.
#define VQ_NOTRESPLOCK 0x0080 //!< server lockd down.
/** @} */
/** @name Data/hint flags for EVFILT_TIMER as suported and defined in kevent64
*
* @{
*/
#define NOTE_SECONDS 0x0001 //!< Time specified in seconds.
#define NOTE_USECONDS 0x0002 //!< Time specified in micro seconds.
#define NOTE_NSECONDS 0x0004 //!< Time specified in nano seconds.
#define NOTE_ABSOLUTE 0x0008 //!< Data is an absolute timeout.
/** @} */
/** @name Data/hint flags for EVFILT_LIBKQUEUE
*
* @{
*/
#define NOTE_VERSION 0x0001 //!< Version number as MMmmpprr.
#define NOTE_VERSION_STR 0x0002 //!< Version number string.
#define NOTE_THREAD_SAFE 0x0003 //!< If true we lock the kq_mtx after looking up
///< a kqueue and locking the kqueue mutex.
#define NOTE_FORK_CLEANUP 0x0004 //!< Control whether we cleanup kqueues
///< and resources associated with them
///< on fork.
#define NOTE_DEBUG 0x0005 //!< Toggle debugging output.
#define NOTE_DEBUG_PREFIX 0x0006 //!< Prefix to add to all debug messages.
#define NOTE_DEBUG_FUNC 0x0007 //!< Debugging function to call to product
///< output. Function should have the signature.
///< int (*debug_func)(char const *fmt, va_list ap).
/** @} */
#ifndef __KERNEL__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#if defined (_MSC_VER) && (_MSC_VER < 1900)
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#else
#include <time.h>
#endif
__declspec(dllexport) int
kqueue(void);
__declspec(dllexport) int
kevent(int kq, const struct kevent *changelist, int nchanges,
struct kevent *eventlist, int nevents,
const struct timespec *timeout);
#ifdef MAKE_STATIC
__declspec(dllexport) int
libkqueue_init();
#endif
#else
int kqueue(void);
int kevent(int kq, const struct kevent *changelist, int nchanges,
struct kevent *eventlist, int nevents,
const struct timespec *timeout);
#ifdef MAKE_STATIC
int libkqueue_init();
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* !__KERNEL__* */
#endif /* !_SYS_EVENT_H_ */