Annotation of embedaddon/sudo/include/sudo_event.h, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (c) 2013 Todd C. Miller <Todd.Miller@courtesan.com>
                      3:  *
                      4:  * Permission to use, copy, modify, and distribute this software for any
                      5:  * purpose with or without fee is hereby granted, provided that the above
                      6:  * copyright notice and this permission notice appear in all copies.
                      7:  *
                      8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                      9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     15:  */
                     16: 
                     17: #ifndef _SUDO_EVENT_H
                     18: #define _SUDO_EVENT_H
                     19: 
                     20: #include "queue.h"
                     21: 
                     22: /* Event types */
                     23: #define SUDO_EV_TIMEOUT                0x01    /* fire after timeout */
                     24: #define SUDO_EV_READ           0x02    /* fire when readable */
                     25: #define SUDO_EV_WRITE          0x04    /* fire when writable */
                     26: #define SUDO_EV_PERSIST                0x08    /* persist until deleted */
                     27: 
                     28: /* Event flags (internal) */
                     29: #define SUDO_EVQ_INSERTED      0x01    /* event is on the event queue */
                     30: #define SUDO_EVQ_ACTIVE                0x02    /* event is on the active queue */
                     31: #define SUDO_EVQ_TIMEOUTS      0x04    /* event is on the timeouts queue */
                     32: 
                     33: /* Event loop flags */
                     34: #define SUDO_EVLOOP_ONCE       0x01    /* Only run once through the loop */
                     35: #define SUDO_EVLOOP_NONBLOCK   0x02    /* Do not block in event loop */
                     36: 
                     37: /* Event base flags (internal) */
                     38: #define SUDO_EVBASE_LOOPEXIT   0x01
                     39: #define SUDO_EVBASE_LOOPBREAK  0x02
                     40: #define SUDO_EVBASE_LOOPCONT   0x04
                     41: #define SUDO_EVBASE_GOT_EXIT   0x10
                     42: #define SUDO_EVBASE_GOT_BREAK  0x20
                     43: #define SUDO_EVBASE_GOT_MASK   0xf0
                     44: 
                     45: typedef void (*sudo_ev_callback_t)(int fd, int what, void *closure);
                     46: 
                     47: /* Member of struct sudo_event_base. */
                     48: struct sudo_event {
                     49:     TAILQ_ENTRY(sudo_event) entries;
                     50:     TAILQ_ENTRY(sudo_event) active_entries;
                     51:     TAILQ_ENTRY(sudo_event) timeouts_entries;
                     52:     struct sudo_event_base *base; /* base this event belongs to */
                     53:     int fd;                    /* fd we are interested in */
                     54:     short events;              /* SUDO_EV_* flags (in) */
                     55:     short revents;             /* SUDO_EV_* flags (out) */
                     56:     short flags;               /* internal event flags */
                     57:     short pfd_idx;             /* index into pfds array (XXX) */
                     58:     sudo_ev_callback_t callback;/* user-provided callback */
                     59:     struct timeval timeout;    /* for SUDO_EV_TIMEOUT */
                     60:     void *closure;             /* user-provided data pointer */
                     61: };
                     62: 
                     63: TAILQ_HEAD(sudo_event_list, sudo_event);
                     64: 
                     65: struct sudo_event_base {
                     66:     struct sudo_event_list events; /* tail queue of all events */
                     67:     struct sudo_event_list active; /* tail queue of active events */
                     68:     struct sudo_event_list timeouts; /* tail queue of timeout events */
                     69: #ifdef HAVE_POLL
                     70:     struct pollfd *pfds;       /* array of struct pollfd */
                     71:     int pfd_max;               /* size of the pfds array */
                     72:     int pfd_high;              /* highest slot used */
                     73:     int pfd_free;              /* idx of next free entry or pfd_max if full */
                     74: #else
                     75:     fd_set *readfds_in;                /* read I/O descriptor set (in) */
                     76:     fd_set *writefds_in;       /* write I/O descriptor set (in) */
                     77:     fd_set *readfds_out;       /* read I/O descriptor set (out) */
                     78:     fd_set *writefds_out;      /* write I/O descriptor set (out) */
                     79:     int maxfd;                 /* max fd we can store in readfds/writefds */
                     80:     int highfd;                        /* highest fd to pass as 1st arg to select */
                     81: #endif /* HAVE_POLL */
                     82:     unsigned int flags;                /* SUDO_EVBASE_* */
                     83: };
                     84: 
                     85: /* Allocate a new event base. */
                     86: struct sudo_event_base *sudo_ev_base_alloc(void);
                     87: 
                     88: /* Free an event base. */
                     89: void sudo_ev_base_free(struct sudo_event_base *base);
                     90: 
                     91: /* Allocate a new event. */
                     92: struct sudo_event *sudo_ev_alloc(int fd, short events, sudo_ev_callback_t callback, void *closure);
                     93: 
                     94: /* Free an event. */
                     95: void sudo_ev_free(struct sudo_event *ev);
                     96: 
                     97: /* Add an event, returns 0 on success, -1 on error */
                     98: int sudo_ev_add(struct sudo_event_base *head, struct sudo_event *ev, struct timeval *timo, bool tohead);
                     99: 
                    100: /* Delete an event, returns 0 on success, -1 on error */
                    101: int sudo_ev_del(struct sudo_event_base *head, struct sudo_event *ev);
                    102: 
                    103: /* Main event loop, returns SUDO_CB_SUCCESS, SUDO_CB_BREAK or SUDO_CB_ERROR */
                    104: int sudo_ev_loop(struct sudo_event_base *head, int flags);
                    105: 
                    106: /* Return the remaining timeout associated with an event. */
                    107: int sudo_ev_get_timeleft(struct sudo_event *ev, struct timeval *tv);
                    108: 
                    109: /* Cause the event loop to exit after one run through. */
                    110: void sudo_ev_loopexit(struct sudo_event_base *base);
                    111: 
                    112: /* Break out of the event loop right now. */
                    113: void sudo_ev_loopbreak(struct sudo_event_base *base);
                    114: 
                    115: /* Rescan for events and restart the event loop. */
                    116: void sudo_ev_loopcontinue(struct sudo_event_base *base);
                    117: 
                    118: /* Returns true if event loop stopped due to sudo_ev_loopexit(). */
                    119: bool sudo_ev_got_exit(struct sudo_event_base *base);
                    120: 
                    121: /* Returns true if event loop stopped due to sudo_ev_loopbreak(). */
                    122: bool sudo_ev_got_break(struct sudo_event_base *base);
                    123: 
                    124: /* Return the fd associated with an event. */
                    125: #define sudo_ev_get_fd(_ev) ((_ev) ? (_ev)->fd : -1)
                    126: 
                    127: /* Return the (absolute) timeout associated with an event or NULL. */
                    128: #define sudo_ev_get_timeout(_ev) \
                    129:     (ISSET((_ev)->flags, SUDO_EVQ_TIMEOUTS) ? &(_ev)->timeout : NULL)
                    130: 
                    131: /* Return the base an event is associated with or NULL. */
                    132: #define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL)
                    133: 
                    134: /* Magic pointer value to use self pointer as callback arg. */
                    135: #define sudo_ev_self_cbarg() ((void *)-1)
                    136: 
                    137: /*
                    138:  * Backend implementation.
                    139:  */
                    140: int sudo_ev_base_alloc_impl(struct sudo_event_base *base);
                    141: void sudo_ev_base_free_impl(struct sudo_event_base *base);
                    142: int sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev);
                    143: int sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev);
                    144: int sudo_ev_scan_impl(struct sudo_event_base *base, int flags);
                    145: 
                    146: #endif /* _SUDO_EVENT_H */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>