1 /* 2 * jabberd - Jabber Open Source Server 3 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 4 * Ryan Eatmon, Robert Norris 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 19 */ 20 21 #ifndef INCL_MIO_H 22 #define INCL_MIO_H 23 24 #ifdef HAVE_CONFIG_H 25 # include <config.h> 26 #endif 27 #include "util/inaddr.h" 28 #include "ac-stdint.h" 29 30 /* jabberd2 Windows DLL */ 31 #ifndef JABBERD2_API 32 # ifdef _WIN32 33 # ifdef JABBERD2_EXPORTS 34 # define JABBERD2_API __declspec(dllexport) 35 # else /* JABBERD2_EXPORTS */ 36 # define JABBERD2_API __declspec(dllimport) 37 # endif /* JABBERD2_EXPORTS */ 38 # else /* _WIN32 */ 39 # define JABBERD2_API extern 40 # endif /* _WIN32 */ 41 #endif /* JABBERD2_API */ 42 43 #ifdef _WIN32 44 # define MIO_MAXFD FD_SETSIZE 45 #else 46 # define MIO_MAXFD 1024 47 #endif 48 49 #include <stdio.h> 50 #include <errno.h> 51 #include <stdlib.h> 52 #include <stdarg.h> 53 54 #ifdef HAVE_UNISTD_H 55 # include <unistd.h> 56 #endif 57 58 #ifdef HAVE_SYS_SOCKET_H 59 # include <sys/socket.h> 60 #endif 61 62 #ifdef HAVE_FCNTL_H 63 # include <fcntl.h> 64 #endif 65 66 #ifdef HAVE_SYS_IOCTL_H 67 # include <sys/ioctl.h> 68 #endif 69 70 #ifdef HAVE_SYS_FILIO_H 71 # include <sys/filio.h> 72 #endif 73 74 #ifdef __cplusplus 75 extern "C" { 76 #endif 77 78 /** 79 * @file mio/mio.h 80 * @brief mio - manage i/o 81 * 82 * This is the most simple fd wrapper possible. It is also customized 83 * per-app and may be limited/extended depending on needs. 84 * 85 * It's basically our own implementation of libevent or libev. 86 * 87 * Usage is pretty simple: 88 * - create a manager 89 * - add fds or tell it to listen 90 * - assign an action handler 91 * - tell mio to read or write with a fd 92 * - process accept, read, write, and close requests 93 * 94 * Note: normal fd's don't get events unless the app calls mio_read/write() first! 95 */ 96 97 /** the master mio mama */ 98 struct mio_st; 99 100 typedef struct mio_fd_st 101 { 102 int fd; 103 } *mio_fd_t; 104 105 /** these are the actions and a handler type assigned by the applicaiton using mio */ 106 typedef enum { action_ACCEPT, action_READ, action_WRITE, action_CLOSE } mio_action_t; 107 typedef int (*mio_handler_t) (struct mio_st **m, mio_action_t a, struct mio_fd_st *fd, void* data, void *arg); 108 109 typedef struct mio_st 110 { 111 void (*mio_free)(struct mio_st **m); 112 113 struct mio_fd_st *(*mio_listen)(struct mio_st **m, int port, const char *sourceip, 114 mio_handler_t app, void *arg); 115 116 struct mio_fd_st *(*mio_connect)(struct mio_st **m, int port, const char *hostip, 117 const char *srcip, mio_handler_t app, void *arg); 118 119 struct mio_fd_st *(*mio_register)(struct mio_st **m, int fd, 120 mio_handler_t app, void *arg); 121 122 void (*mio_app)(struct mio_st **m, struct mio_fd_st *fd, 123 mio_handler_t app, void *arg); 124 125 void (*mio_close)(struct mio_st **m, struct mio_fd_st *fd); 126 127 void (*mio_write)(struct mio_st **m, struct mio_fd_st *fd); 128 129 void (*mio_read)(struct mio_st **m, struct mio_fd_st *fd); 130 131 void (*mio_run)(struct mio_st **m, int timeout); 132 } **mio_t; 133 134 /** create/free the mio subsytem */ 135 JABBERD2_API mio_t mio_new(int maxfd); /* returns NULL if failed */ 136 137 #define mio_free(m) (*m)->mio_free(m) 138 139 /** for creating a new listen socket in this mio (returns new fd or <0) */ 140 #define mio_listen(m, port, sourceip, app, arg) \ 141 (*m)->mio_listen(m, port, sourceip, app, arg) 142 143 /** for creating a new socket connected to this ip:port (returns new fd or <0, use mio_read/write first) */ 144 #define mio_connect(m, port, hostip, srcip, app, arg) \ 145 (*m)->mio_connect(m, port, hostip, srcip, app, arg) 146 147 /** for adding an existing socket connected to this mio */ 148 #define mio_register(m, fd, app, arg) \ 149 (*m)->mio_register(m, fd, app, arg) 150 151 /** re-set the app handler */ 152 #define mio_app(m, fd, app, arg) (*m)->mio_app(m, fd, app, arg) 153 154 /** request that mio close this fd */ 155 #define mio_close(m, fd) (*m)->mio_close(m, fd) 156 157 /** mio should try the write action on this fd now */ 158 #define mio_write(m, fd) (*m)->mio_write(m, fd) 159 160 /** process read events for this fd */ 161 #define mio_read(m, fd) (*m)->mio_read(m, fd) 162 163 /** give some cpu time to mio to check it's sockets, 0 is non-blocking */ 164 #define mio_run(m, timeout) (*m)->mio_run(m, timeout) 165 166 /** all MIO related routines should use those for error reporting */ 167 #ifndef _WIN32 168 # define MIO_ERROR errno 169 # define MIO_SETERROR(e) (errno = e) 170 # define MIO_STRERROR(e) strerror(e) 171 # define MIO_WOULDBLOCK (errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) 172 #else /* _WIN32 */ 173 JABBERD2_API char *mio_strerror(int code); 174 # define MIO_ERROR WSAGetLastError() 175 # define MIO_SETERROR(e) WSASetLastError(e) 176 # define MIO_STRERROR(e) mio_strerror(e) 177 # define MIO_WOULDBLOCK (WSAGetLastError() == WSAEWOULDBLOCK) 178 #endif /* _WIN32 */ 179 180 #ifdef __cplusplus 181 } 182 #endif 183 184 #endif /* INCL_MIO_H */ 185 186