| 1 | /* ------------------------------------------------------------------------- |
| 2 | * Project: GSocket (Generic Socket) |
| 3 | * Name: gsocket.h |
| 4 | * Author: Guilhem Lavaux |
| 5 | * Guillermo Rodriguez Garcia <guille@iies.es> (maintainer) |
| 6 | * Purpose: GSocket include file (system independent) |
| 7 | * CVSID: $Id$ |
| 8 | * ------------------------------------------------------------------------- |
| 9 | */ |
| 10 | |
| 11 | #ifndef __GSOCKET_H |
| 12 | #define __GSOCKET_H |
| 13 | |
| 14 | #ifndef __GSOCKET_STANDALONE__ |
| 15 | #include "wx/setup.h" |
| 16 | #endif |
| 17 | |
| 18 | #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) |
| 19 | |
| 20 | #include <stddef.h> |
| 21 | #ifndef __WXMAC__ |
| 22 | #include <sys/types.h> |
| 23 | #endif |
| 24 | |
| 25 | #ifdef __cplusplus |
| 26 | extern "C" { |
| 27 | #endif |
| 28 | |
| 29 | typedef struct _GSocket GSocket; |
| 30 | typedef struct _GAddress GAddress; |
| 31 | |
| 32 | typedef enum { |
| 33 | GSOCK_NOFAMILY = 0, |
| 34 | GSOCK_INET, |
| 35 | GSOCK_INET6, |
| 36 | GSOCK_UNIX |
| 37 | } GAddressType; |
| 38 | |
| 39 | typedef enum { |
| 40 | GSOCK_STREAMED, |
| 41 | GSOCK_UNSTREAMED |
| 42 | } GSocketStream; |
| 43 | |
| 44 | typedef enum { |
| 45 | GSOCK_NOERROR = 0, |
| 46 | GSOCK_INVOP, |
| 47 | GSOCK_IOERR, |
| 48 | GSOCK_INVADDR, |
| 49 | GSOCK_INVSOCK, |
| 50 | GSOCK_NOHOST, |
| 51 | GSOCK_INVPORT, |
| 52 | GSOCK_WOULDBLOCK, |
| 53 | GSOCK_TIMEDOUT, |
| 54 | GSOCK_MEMERR |
| 55 | } GSocketError; |
| 56 | |
| 57 | /* See below for an explanation on how events work. |
| 58 | */ |
| 59 | typedef enum { |
| 60 | GSOCK_INPUT = 0, |
| 61 | GSOCK_OUTPUT = 1, |
| 62 | GSOCK_CONNECTION = 2, |
| 63 | GSOCK_LOST = 3, |
| 64 | GSOCK_MAX_EVENT = 4 |
| 65 | } GSocketEvent; |
| 66 | |
| 67 | enum { |
| 68 | GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT, |
| 69 | GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT, |
| 70 | GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION, |
| 71 | GSOCK_LOST_FLAG = 1 << GSOCK_LOST |
| 72 | }; |
| 73 | |
| 74 | typedef int GSocketEventFlags; |
| 75 | |
| 76 | typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event, |
| 77 | char *cdata); |
| 78 | |
| 79 | |
| 80 | /* Global initializers */ |
| 81 | |
| 82 | /* GSocket_Init() must be called at the beginning */ |
| 83 | int GSocket_Init(void); |
| 84 | |
| 85 | /* GSocket_Cleanup() must be called at the end */ |
| 86 | void GSocket_Cleanup(void); |
| 87 | |
| 88 | |
| 89 | /* Constructors / Destructors */ |
| 90 | |
| 91 | GSocket *GSocket_new(void); |
| 92 | void GSocket_destroy(GSocket *socket); |
| 93 | |
| 94 | |
| 95 | |
| 96 | /* GSocket_Shutdown: |
| 97 | * Disallow further read/write operations on this socket, close |
| 98 | * the fd and disable all callbacks. |
| 99 | */ |
| 100 | void GSocket_Shutdown(GSocket *socket); |
| 101 | |
| 102 | /* Address handling */ |
| 103 | |
| 104 | /* GSocket_SetLocal: |
| 105 | * GSocket_GetLocal: |
| 106 | * GSocket_SetPeer: |
| 107 | * GSocket_GetPeer: |
| 108 | * Set or get the local or peer address for this socket. The 'set' |
| 109 | * functions return GSOCK_NOERROR on success, an error code otherwise. |
| 110 | * The 'get' functions return a pointer to a GAddress object on success, |
| 111 | * or NULL otherwise, in which case they set the error code of the |
| 112 | * corresponding GSocket. |
| 113 | * |
| 114 | * Error codes: |
| 115 | * GSOCK_INVSOCK - the socket is not valid. |
| 116 | * GSOCK_INVADDR - the address is not valid. |
| 117 | */ |
| 118 | GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address); |
| 119 | GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address); |
| 120 | GAddress *GSocket_GetLocal(GSocket *socket); |
| 121 | GAddress *GSocket_GetPeer(GSocket *socket); |
| 122 | |
| 123 | /* Server specific parts */ |
| 124 | |
| 125 | /* GSocket_SetServer: |
| 126 | * Sets up this socket as a server. The local address must have been |
| 127 | * set with GSocket_SetLocal() before GSocket_SetServer() is called. |
| 128 | * Returns GSOCK_NOERROR on success, one of the following otherwise: |
| 129 | * |
| 130 | * Error codes: |
| 131 | * GSOCK_INVSOCK - the socket is in use. |
| 132 | * GSOCK_INVADDR - the local address has not been set. |
| 133 | * GSOCK_IOERR - low-level error. |
| 134 | */ |
| 135 | GSocketError GSocket_SetServer(GSocket *socket); |
| 136 | |
| 137 | /* GSocket_WaitConnection: |
| 138 | * Waits for an incoming client connection. Returns a pointer to |
| 139 | * a GSocket object, or NULL if there was an error, in which case |
| 140 | * the last error field will be updated for the calling GSocket. |
| 141 | * |
| 142 | * Error codes (set in the calling GSocket) |
| 143 | * GSOCK_INVSOCK - the socket is not valid or not a server. |
| 144 | * GSOCK_TIMEDOUT - timeout, no incoming connections. |
| 145 | * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking. |
| 146 | * GSOCK_MEMERR - couldn't allocate memory. |
| 147 | * GSOCK_IOERR - low-level error. |
| 148 | */ |
| 149 | GSocket *GSocket_WaitConnection(GSocket *socket); |
| 150 | |
| 151 | |
| 152 | /* Client specific parts */ |
| 153 | |
| 154 | /* GSocket_Connect: |
| 155 | * For stream (connection oriented) sockets, GSocket_Connect() tries |
| 156 | * to establish a client connection to a server using the peer address |
| 157 | * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the |
| 158 | * connection has been succesfully established, or one of the error |
| 159 | * codes listed below. Note that for nonblocking sockets, a return |
| 160 | * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection |
| 161 | * request can be completed later; you should use GSocket_Select() |
| 162 | * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the |
| 163 | * corresponding asynchronous events. |
| 164 | * |
| 165 | * For datagram (non connection oriented) sockets, GSocket_Connect() |
| 166 | * just sets the peer address established with GSocket_SetPeer() as |
| 167 | * default destination. |
| 168 | * |
| 169 | * Error codes: |
| 170 | * GSOCK_INVSOCK - the socket is in use or not valid. |
| 171 | * GSOCK_INVADDR - the peer address has not been established. |
| 172 | * GSOCK_TIMEDOUT - timeout, the connection failed. |
| 173 | * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only) |
| 174 | * GSOCK_MEMERR - couldn't allocate memory. |
| 175 | * GSOCK_IOERR - low-level error. |
| 176 | */ |
| 177 | GSocketError GSocket_Connect(GSocket *socket, GSocketStream stream); |
| 178 | |
| 179 | |
| 180 | /* Datagram sockets */ |
| 181 | |
| 182 | /* GSocket_SetNonOriented: |
| 183 | * Sets up this socket as a non-connection oriented (datagram) socket. |
| 184 | * Before using this function, the local address must have been set |
| 185 | * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR |
| 186 | * on success, or one of the following otherwise. |
| 187 | * |
| 188 | * Error codes: |
| 189 | * GSOCK_INVSOCK - the socket is in use. |
| 190 | * GSOCK_INVADDR - the local address has not been set. |
| 191 | * GSOCK_IOERR - low-level error. |
| 192 | */ |
| 193 | GSocketError GSocket_SetNonOriented(GSocket *socket); |
| 194 | |
| 195 | |
| 196 | /* Generic IO */ |
| 197 | |
| 198 | /* Like recv(), send(), ... */ |
| 199 | |
| 200 | /* For datagram sockets, the incoming / outgoing addresses |
| 201 | * are stored as / read from the 'peer' address field. |
| 202 | */ |
| 203 | int GSocket_Read(GSocket *socket, char *buffer, int size); |
| 204 | int GSocket_Write(GSocket *socket, const char *buffer, |
| 205 | int size); |
| 206 | |
| 207 | /* GSocket_Select: |
| 208 | * Polls the socket to determine its status. This function will |
| 209 | * check for the events specified in the 'flags' parameter, and |
| 210 | * it will return a mask indicating which operations can be |
| 211 | * performed. This function won't block, regardless of the |
| 212 | * mode (blocking | nonblocking) of the socket. |
| 213 | */ |
| 214 | GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags); |
| 215 | |
| 216 | |
| 217 | /* Attributes */ |
| 218 | |
| 219 | /* GSocket_SetNonBlocking: |
| 220 | * Sets the socket to non-blocking mode. All IO calls will return |
| 221 | * immediately. |
| 222 | */ |
| 223 | void GSocket_SetNonBlocking(GSocket *socket, int non_block); |
| 224 | |
| 225 | /* GSocket_SetTimeout: |
| 226 | * Sets the timeout for blocking calls. Time is expressed in |
| 227 | * milliseconds. |
| 228 | */ |
| 229 | void GSocket_SetTimeout(GSocket *socket, unsigned long millisec); |
| 230 | |
| 231 | /* GSocket_GetError: |
| 232 | * Returns the last error occured for this socket. Note that successful |
| 233 | * operations do not clear this back to GSOCK_NOERROR, so use it only |
| 234 | * after an error. |
| 235 | */ |
| 236 | GSocketError GSocket_GetError(GSocket *socket); |
| 237 | |
| 238 | |
| 239 | /* Callbacks */ |
| 240 | |
| 241 | /* GSOCK_INPUT: |
| 242 | * There is data to be read in the input buffer. If, after a read |
| 243 | * operation, there is still data available, the callback function will |
| 244 | * be called again. |
| 245 | * GSOCK_OUTPUT: |
| 246 | * The socket is available for writing. That is, the next write call |
| 247 | * won't block. This event is generated only once, when the connection is |
| 248 | * first established, and then only if a call failed with GSOCK_WOULDBLOCK, |
| 249 | * when the output buffer empties again. This means that the app should |
| 250 | * assume that it can write since the first OUTPUT event, and no more |
| 251 | * OUTPUT events will be generated unless an error occurs. |
| 252 | * GSOCK_CONNECTION: |
| 253 | * Connection succesfully established, for client sockets, or incoming |
| 254 | * client connection, for server sockets. Wait for this event (also watch |
| 255 | * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call. |
| 256 | * GSOCK_LOST: |
| 257 | * The connection is lost (or a connection request failed); this could |
| 258 | * be due to a failure, or due to the peer closing it gracefully. |
| 259 | */ |
| 260 | |
| 261 | /* GSocket_SetCallback: |
| 262 | * Enables the callbacks specified by 'flags'. Note that 'flags' |
| 263 | * may be a combination of flags OR'ed toghether, so the same |
| 264 | * callback function can be made to accept different events. |
| 265 | * The callback function must have the following prototype: |
| 266 | * |
| 267 | * void function(GSocket *socket, GSocketEvent event, char *cdata) |
| 268 | */ |
| 269 | void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags, |
| 270 | GSocketCallback fallback, char *cdata); |
| 271 | |
| 272 | /* GSocket_UnsetCallback: |
| 273 | * Disables all callbacks specified by 'flags', which may be a |
| 274 | * combination of flags OR'ed toghether. |
| 275 | */ |
| 276 | void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags); |
| 277 | |
| 278 | |
| 279 | /* GAddress */ |
| 280 | |
| 281 | GAddress *GAddress_new(void); |
| 282 | GAddress *GAddress_copy(GAddress *address); |
| 283 | void GAddress_destroy(GAddress *address); |
| 284 | |
| 285 | void GAddress_SetFamily(GAddress *address, GAddressType type); |
| 286 | GAddressType GAddress_GetFamily(GAddress *address); |
| 287 | |
| 288 | /* The use of any of the next functions will set the address family to |
| 289 | * the specific one. For example if you use GAddress_INET_SetHostName, |
| 290 | * address family will be implicitly set to AF_INET. |
| 291 | */ |
| 292 | |
| 293 | GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname); |
| 294 | GSocketError GAddress_INET_SetAnyAddress(GAddress *address); |
| 295 | GSocketError GAddress_INET_SetHostAddress(GAddress *address, |
| 296 | unsigned long hostaddr); |
| 297 | GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port, |
| 298 | const char *protocol); |
| 299 | GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port); |
| 300 | |
| 301 | GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, |
| 302 | size_t sbuf); |
| 303 | unsigned long GAddress_INET_GetHostAddress(GAddress *address); |
| 304 | unsigned short GAddress_INET_GetPort(GAddress *address); |
| 305 | |
| 306 | /* TODO: Define specific parts (INET6, UNIX) */ |
| 307 | |
| 308 | GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path); |
| 309 | GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf); |
| 310 | |
| 311 | #ifdef __cplusplus |
| 312 | }; |
| 313 | #endif /* __cplusplus */ |
| 314 | |
| 315 | |
| 316 | #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */ |
| 317 | |
| 318 | #endif /* __GSOCKET_H */ |