]> git.saurik.com Git - wxWidgets.git/blob - src/msw/gsocket.c
Added prototypes to eliminate BC++ warnings
[wxWidgets.git] / src / msw / gsocket.c
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
3 * Name: gsocket.c
4 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
5 * Purpose: GSocket main MSW file
6 * CVSID: $Id$
7 * -------------------------------------------------------------------------
8 */
9
10 /*
11 * PLEASE don't put C++ comments here - this is a C source file.
12 */
13
14 #ifndef __GSOCKET_STANDALONE__
15 #include "wx/setup.h"
16 #endif
17
18 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
19
20 #ifndef __GSOCKET_STANDALONE__
21
22 #include "wx/msw/gsockmsw.h"
23 #include "wx/gsocket.h"
24
25 #else
26
27 #include "gsockmsw.h"
28 #include "gsocket.h"
29
30 #endif /* __GSOCKET_STANDALONE__ */
31
32 #include <assert.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stddef.h>
37 #include <ctype.h>
38 #include <winsock.h>
39
40 /* if we use configure for MSW SOCKLEN_T will be already defined */
41 #ifndef SOCKLEN_T
42 #define SOCKLEN_T int
43 #endif
44
45 #if defined(__BORLANDC__)
46 GAddress *GAddress_new(void);
47 GSocket *GSocket_new(void);
48 #endif
49
50 #ifdef _MSC_VER
51 /* using FD_SET results in this warning */
52 #pragma warning(disable:4127) /* conditional expression is constant */
53 #endif /* Visual C++ */
54
55
56 /* Constructors / Destructors for GSocket */
57
58 GSocket *GSocket_new()
59 {
60 int i;
61 GSocket *socket;
62
63 if ((socket = (GSocket *) malloc(sizeof(GSocket))) == NULL)
64 return NULL;
65
66 socket->m_fd = INVALID_SOCKET;
67 for (i = 0; i < GSOCK_MAX_EVENT; i++)
68 {
69 socket->m_cbacks[i] = NULL;
70 }
71 socket->m_local = NULL;
72 socket->m_peer = NULL;
73 socket->m_error = GSOCK_NOERROR;
74 socket->m_server = FALSE;
75 socket->m_stream = TRUE;
76 socket->m_non_blocking = FALSE;
77 socket->m_timeout.tv_sec = 10 * 60; /* 10 minutes */
78 socket->m_timeout.tv_usec = 0;
79 socket->m_detected = 0;
80
81 /* Per-socket GUI-specific initialization */
82 if (!_GSocket_GUI_Init(socket))
83 {
84 free(socket);
85 return NULL;
86 }
87
88 return socket;
89 }
90
91 void GSocket_destroy(GSocket *socket)
92 {
93 assert(socket != NULL);
94
95 /* Per-socket GUI-specific cleanup */
96 _GSocket_GUI_Destroy(socket);
97
98 /* Check that the socket is really shutdowned */
99 if (socket->m_fd != INVALID_SOCKET)
100 GSocket_Shutdown(socket);
101
102 /* Destroy private addresses */
103 if (socket->m_local)
104 GAddress_destroy(socket->m_local);
105
106 if (socket->m_peer)
107 GAddress_destroy(socket->m_peer);
108
109 /* Destroy the socket itself */
110 free(socket);
111 }
112
113 /* GSocket_Shutdown:
114 * Disallow further read/write operations on this socket, close
115 * the fd and disable all callbacks.
116 */
117 void GSocket_Shutdown(GSocket *socket)
118 {
119 int evt;
120
121 assert(socket != NULL);
122
123 /* If socket has been created, shutdown it */
124 if (socket->m_fd != INVALID_SOCKET)
125 {
126 shutdown(socket->m_fd, 2);
127 closesocket(socket->m_fd);
128 socket->m_fd = INVALID_SOCKET;
129 }
130
131 /* Disable GUI callbacks */
132 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
133 socket->m_cbacks[evt] = NULL;
134
135 socket->m_detected = GSOCK_LOST_FLAG;
136 _GSocket_Disable_Events(socket);
137 }
138
139 /* Address handling */
140
141 /* GSocket_SetLocal:
142 * GSocket_GetLocal:
143 * GSocket_SetPeer:
144 * GSocket_GetPeer:
145 * Set or get the local or peer address for this socket. The 'set'
146 * functions return GSOCK_NOERROR on success, an error code otherwise.
147 * The 'get' functions return a pointer to a GAddress object on success,
148 * or NULL otherwise, in which case they set the error code of the
149 * corresponding GSocket.
150 *
151 * Error codes:
152 * GSOCK_INVSOCK - the socket is not valid.
153 * GSOCK_INVADDR - the address is not valid.
154 */
155 GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
156 {
157 assert(socket != NULL);
158
159 /* the socket must be initialized, or it must be a server */
160 if (socket->m_fd != INVALID_SOCKET && !socket->m_server)
161 {
162 socket->m_error = GSOCK_INVSOCK;
163 return GSOCK_INVSOCK;
164 }
165
166 /* check address */
167 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
168 {
169 socket->m_error = GSOCK_INVADDR;
170 return GSOCK_INVADDR;
171 }
172
173 if (socket->m_local)
174 GAddress_destroy(socket->m_local);
175
176 socket->m_local = GAddress_copy(address);
177
178 return GSOCK_NOERROR;
179 }
180
181 GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
182 {
183 assert(socket != NULL);
184
185 /* check address */
186 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
187 {
188 socket->m_error = GSOCK_INVADDR;
189 return GSOCK_INVADDR;
190 }
191
192 if (socket->m_peer)
193 GAddress_destroy(socket->m_peer);
194
195 socket->m_peer = GAddress_copy(address);
196
197 return GSOCK_NOERROR;
198 }
199
200 GAddress *GSocket_GetLocal(GSocket *socket)
201 {
202 GAddress *address;
203 struct sockaddr addr;
204 SOCKLEN_T size = sizeof(addr);
205 GSocketError err;
206
207 assert(socket != NULL);
208
209 /* try to get it from the m_local var first */
210 if (socket->m_local)
211 return GAddress_copy(socket->m_local);
212
213 /* else, if the socket is initialized, try getsockname */
214 if (socket->m_fd == INVALID_SOCKET)
215 {
216 socket->m_error = GSOCK_INVSOCK;
217 return NULL;
218 }
219
220 if (getsockname(socket->m_fd, &addr, &size) == SOCKET_ERROR)
221 {
222 socket->m_error = GSOCK_IOERR;
223 return NULL;
224 }
225
226 /* got a valid address from getsockname, create a GAddress object */
227 if ((address = GAddress_new()) == NULL)
228 {
229 socket->m_error = GSOCK_MEMERR;
230 return NULL;
231 }
232
233 if ((err = _GAddress_translate_from(address, &addr, size)) != GSOCK_NOERROR)
234 {
235 GAddress_destroy(address);
236 socket->m_error = err;
237 return NULL;
238 }
239
240 return address;
241 }
242
243 GAddress *GSocket_GetPeer(GSocket *socket)
244 {
245 assert(socket != NULL);
246
247 /* try to get it from the m_peer var */
248 if (socket->m_peer)
249 return GAddress_copy(socket->m_peer);
250
251 return NULL;
252 }
253
254 /* Server specific parts */
255
256 /* GSocket_SetServer:
257 * Sets up this socket as a server. The local address must have been
258 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
259 * Returns GSOCK_NOERROR on success, one of the following otherwise:
260 *
261 * Error codes:
262 * GSOCK_INVSOCK - the socket is in use.
263 * GSOCK_INVADDR - the local address has not been set.
264 * GSOCK_IOERR - low-level error.
265 */
266 GSocketError GSocket_SetServer(GSocket *sck)
267 {
268 u_long arg = 1;
269
270 assert(sck != NULL);
271
272 /* must not be in use */
273 if (sck->m_fd != INVALID_SOCKET)
274 {
275 sck->m_error = GSOCK_INVSOCK;
276 return GSOCK_INVSOCK;
277 }
278
279 /* the local addr must have been set */
280 if (!sck->m_local)
281 {
282 sck->m_error = GSOCK_INVADDR;
283 return GSOCK_INVADDR;
284 }
285
286 /* Initialize all fields */
287 sck->m_server = TRUE;
288 sck->m_stream = TRUE;
289 sck->m_oriented = TRUE;
290
291 /* Create the socket */
292 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
293
294 if (sck->m_fd == INVALID_SOCKET)
295 {
296 sck->m_error = GSOCK_IOERR;
297 return GSOCK_IOERR;
298 }
299
300 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
301 _GSocket_Enable_Events(sck);
302
303 /* Bind to the local address,
304 * retrieve the actual address bound,
305 * and listen up to 5 connections.
306 */
307 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
308 (getsockname(sck->m_fd,
309 sck->m_local->m_addr,
310 (SOCKLEN_T *)&sck->m_local->m_len) != 0) ||
311 (listen(sck->m_fd, 5) != 0))
312 {
313 closesocket(sck->m_fd);
314 sck->m_fd = INVALID_SOCKET;
315 sck->m_error = GSOCK_IOERR;
316 return GSOCK_IOERR;
317 }
318
319 return GSOCK_NOERROR;
320 }
321
322 /* GSocket_WaitConnection:
323 * Waits for an incoming client connection. Returns a pointer to
324 * a GSocket object, or NULL if there was an error, in which case
325 * the last error field will be updated for the calling GSocket.
326 *
327 * Error codes (set in the calling GSocket)
328 * GSOCK_INVSOCK - the socket is not valid or not a server.
329 * GSOCK_TIMEDOUT - timeout, no incoming connections.
330 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
331 * GSOCK_MEMERR - couldn't allocate memory.
332 * GSOCK_IOERR - low-level error.
333 */
334 GSocket *GSocket_WaitConnection(GSocket *sck)
335 {
336 GSocket *connection;
337 struct sockaddr from;
338 SOCKLEN_T fromlen = sizeof(from);
339 GSocketError err;
340 u_long arg = 1;
341
342 assert(sck != NULL);
343
344 /* Reenable CONNECTION events */
345 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
346
347 /* If the socket has already been created, we exit immediately */
348 if (sck->m_fd == INVALID_SOCKET || !sck->m_server)
349 {
350 sck->m_error = GSOCK_INVSOCK;
351 return NULL;
352 }
353
354 /* Create a GSocket object for the new connection */
355 connection = GSocket_new();
356
357 if (!connection)
358 {
359 sck->m_error = GSOCK_MEMERR;
360 return NULL;
361 }
362
363 /* Wait for a connection (with timeout) */
364 if (_GSocket_Input_Timeout(sck) == GSOCK_TIMEDOUT)
365 {
366 GSocket_destroy(connection);
367 /* sck->m_error set by _GSocket_Input_Timeout */
368 return NULL;
369 }
370
371 connection->m_fd = accept(sck->m_fd, &from, &fromlen);
372
373 if (connection->m_fd == INVALID_SOCKET)
374 {
375 if (WSAGetLastError() == WSAEWOULDBLOCK)
376 sck->m_error = GSOCK_WOULDBLOCK;
377 else
378 sck->m_error = GSOCK_IOERR;
379
380 GSocket_destroy(connection);
381 return NULL;
382 }
383
384 /* Initialize all fields */
385 connection->m_server = FALSE;
386 connection->m_stream = TRUE;
387 connection->m_oriented = TRUE;
388
389 /* Setup the peer address field */
390 connection->m_peer = GAddress_new();
391 if (!connection->m_peer)
392 {
393 GSocket_destroy(connection);
394 sck->m_error = GSOCK_MEMERR;
395 return NULL;
396 }
397 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
398 if (err != GSOCK_NOERROR)
399 {
400 GAddress_destroy(connection->m_peer);
401 GSocket_destroy(connection);
402 sck->m_error = err;
403 return NULL;
404 }
405
406 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
407 _GSocket_Enable_Events(connection);
408
409 return connection;
410 }
411
412 /* Client specific parts */
413
414 /* GSocket_Connect:
415 * For stream (connection oriented) sockets, GSocket_Connect() tries
416 * to establish a client connection to a server using the peer address
417 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
418 * connection has been succesfully established, or one of the error
419 * codes listed below. Note that for nonblocking sockets, a return
420 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
421 * request can be completed later; you should use GSocket_Select()
422 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
423 * corresponding asynchronous events.
424 *
425 * For datagram (non connection oriented) sockets, GSocket_Connect()
426 * just sets the peer address established with GSocket_SetPeer() as
427 * default destination.
428 *
429 * Error codes:
430 * GSOCK_INVSOCK - the socket is in use or not valid.
431 * GSOCK_INVADDR - the peer address has not been established.
432 * GSOCK_TIMEDOUT - timeout, the connection failed.
433 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
434 * GSOCK_MEMERR - couldn't allocate memory.
435 * GSOCK_IOERR - low-level error.
436 */
437 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
438 {
439 int ret, err;
440 u_long arg = 1;
441
442 assert(sck != NULL);
443
444 /* Enable CONNECTION events (needed for nonblocking connections) */
445 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
446
447 if (sck->m_fd != INVALID_SOCKET)
448 {
449 sck->m_error = GSOCK_INVSOCK;
450 return GSOCK_INVSOCK;
451 }
452
453 if (!sck->m_peer)
454 {
455 sck->m_error = GSOCK_INVADDR;
456 return GSOCK_INVADDR;
457 }
458
459 /* Streamed or dgram socket? */
460 sck->m_stream = (stream == GSOCK_STREAMED);
461 sck->m_oriented = TRUE;
462 sck->m_server = FALSE;
463
464 /* Create the socket */
465 sck->m_fd = socket(sck->m_peer->m_realfamily,
466 sck->m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
467
468 if (sck->m_fd == INVALID_SOCKET)
469 {
470 sck->m_error = GSOCK_IOERR;
471 return GSOCK_IOERR;
472 }
473
474 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
475 _GSocket_Enable_Events(sck);
476
477 /* Connect it to the peer address, with a timeout (see below) */
478 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
479
480 if (ret == SOCKET_ERROR)
481 {
482 err = WSAGetLastError();
483
484 /* If connect failed with EWOULDBLOCK and the GSocket object
485 * is in blocking mode, we select() for the specified timeout
486 * checking for writability to see if the connection request
487 * completes.
488 */
489 if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking))
490 {
491 err = _GSocket_Connect_Timeout(sck);
492
493 if (err != GSOCK_NOERROR)
494 {
495 closesocket(sck->m_fd);
496 sck->m_fd = INVALID_SOCKET;
497 /* sck->m_error is set in _GSocket_Connect_Timeout */
498 }
499
500 return err;
501 }
502
503 /* If connect failed with EWOULDBLOCK and the GSocket object
504 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
505 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
506 * this way if the connection completes, a GSOCK_CONNECTION
507 * event will be generated, if enabled.
508 */
509 if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking))
510 {
511 sck->m_error = GSOCK_WOULDBLOCK;
512 return GSOCK_WOULDBLOCK;
513 }
514
515 /* If connect failed with an error other than EWOULDBLOCK,
516 * then the call to GSocket_Connect() has failed.
517 */
518 closesocket(sck->m_fd);
519 sck->m_fd = INVALID_SOCKET;
520 sck->m_error = GSOCK_IOERR;
521 return GSOCK_IOERR;
522 }
523
524 return GSOCK_NOERROR;
525 }
526
527 /* Datagram sockets */
528
529 /* GSocket_SetNonOriented:
530 * Sets up this socket as a non-connection oriented (datagram) socket.
531 * Before using this function, the local address must have been set
532 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
533 * on success, or one of the following otherwise.
534 *
535 * Error codes:
536 * GSOCK_INVSOCK - the socket is in use.
537 * GSOCK_INVADDR - the local address has not been set.
538 * GSOCK_IOERR - low-level error.
539 */
540 GSocketError GSocket_SetNonOriented(GSocket *sck)
541 {
542 u_long arg = 1;
543
544 assert(sck != NULL);
545
546 if (sck->m_fd != INVALID_SOCKET)
547 {
548 sck->m_error = GSOCK_INVSOCK;
549 return GSOCK_INVSOCK;
550 }
551
552 if (!sck->m_local)
553 {
554 sck->m_error = GSOCK_INVADDR;
555 return GSOCK_INVADDR;
556 }
557
558 /* Initialize all fields */
559 sck->m_stream = FALSE;
560 sck->m_server = FALSE;
561 sck->m_oriented = FALSE;
562
563 /* Create the socket */
564 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
565
566 if (sck->m_fd == INVALID_SOCKET)
567 {
568 sck->m_error = GSOCK_IOERR;
569 return GSOCK_IOERR;
570 }
571
572 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
573 _GSocket_Enable_Events(sck);
574
575 /* Bind to the local address,
576 * and retrieve the actual address bound.
577 */
578 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
579 (getsockname(sck->m_fd,
580 sck->m_local->m_addr,
581 (SOCKLEN_T *)&sck->m_local->m_len) != 0))
582 {
583 closesocket(sck->m_fd);
584 sck->m_fd = INVALID_SOCKET;
585 sck->m_error = GSOCK_IOERR;
586 return GSOCK_IOERR;
587 }
588
589 return GSOCK_NOERROR;
590 }
591
592 /* Generic IO */
593
594 /* Like recv(), send(), ... */
595 int GSocket_Read(GSocket *socket, char *buffer, int size)
596 {
597 int ret;
598
599 assert(socket != NULL);
600
601 /* Reenable INPUT events */
602 socket->m_detected &= ~GSOCK_INPUT_FLAG;
603
604 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
605 {
606 socket->m_error = GSOCK_INVSOCK;
607 return -1;
608 }
609
610 /* If the socket is blocking, wait for data (with a timeout) */
611 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
612 return -1;
613
614 /* Read the data */
615 if (socket->m_stream)
616 ret = _GSocket_Recv_Stream(socket, buffer, size);
617 else
618 ret = _GSocket_Recv_Dgram(socket, buffer, size);
619
620 if (ret == SOCKET_ERROR)
621 {
622 if (WSAGetLastError() != WSAEWOULDBLOCK)
623 socket->m_error = GSOCK_IOERR;
624 else
625 socket->m_error = GSOCK_WOULDBLOCK;
626 return -1;
627 }
628
629 return ret;
630 }
631
632 int GSocket_Write(GSocket *socket, const char *buffer, int size)
633 {
634 int ret;
635
636 assert(socket != NULL);
637
638 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
639 {
640 socket->m_error = GSOCK_INVSOCK;
641 return -1;
642 }
643
644 /* If the socket is blocking, wait for writability (with a timeout) */
645 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
646 return -1;
647
648 /* Write the data */
649 if (socket->m_stream)
650 ret = _GSocket_Send_Stream(socket, buffer, size);
651 else
652 ret = _GSocket_Send_Dgram(socket, buffer, size);
653
654 if (ret == SOCKET_ERROR)
655 {
656 if (WSAGetLastError() != WSAEWOULDBLOCK)
657 socket->m_error = GSOCK_IOERR;
658 else
659 socket->m_error = GSOCK_WOULDBLOCK;
660
661 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
662 * does). Once the first OUTPUT event is received, users can assume
663 * that the socket is writable until a read operation fails. Only then
664 * will further OUTPUT events be posted.
665 */
666 socket->m_detected &= ~GSOCK_OUTPUT_FLAG;
667 return -1;
668 }
669
670 return ret;
671 }
672
673 /* GSocket_Select:
674 * Polls the socket to determine its status. This function will
675 * check for the events specified in the 'flags' parameter, and
676 * it will return a mask indicating which operations can be
677 * performed. This function won't block, regardless of the
678 * mode (blocking | nonblocking) of the socket.
679 */
680 GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
681 {
682 assert(socket != NULL);
683
684 return flags & socket->m_detected;
685 }
686
687 /* Attributes */
688
689 /* GSocket_SetNonBlocking:
690 * Sets the socket to non-blocking mode. All IO calls will return
691 * immediately.
692 */
693 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
694 {
695 assert(socket != NULL);
696
697 socket->m_non_blocking = non_block;
698 }
699
700 /* GSocket_SetTimeout:
701 * Sets the timeout for blocking calls. Time is expressed in
702 * milliseconds.
703 */
704 void GSocket_SetTimeout(GSocket *socket, unsigned long millis)
705 {
706 assert(socket != NULL);
707
708 socket->m_timeout.tv_sec = (millis / 1000);
709 socket->m_timeout.tv_usec = (millis % 1000) * 1000;
710 }
711
712 /* GSocket_GetError:
713 * Returns the last error occured for this socket. Note that successful
714 * operations do not clear this back to GSOCK_NOERROR, so use it only
715 * after an error.
716 */
717 GSocketError GSocket_GetError(GSocket *socket)
718 {
719 assert(socket != NULL);
720
721 return socket->m_error;
722 }
723
724 /* Callbacks */
725
726 /* GSOCK_INPUT:
727 * There is data to be read in the input buffer. If, after a read
728 * operation, there is still data available, the callback function will
729 * be called again.
730 * GSOCK_OUTPUT:
731 * The socket is available for writing. That is, the next write call
732 * won't block. This event is generated only once, when the connection is
733 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
734 * when the output buffer empties again. This means that the app should
735 * assume that it can write since the first OUTPUT event, and no more
736 * OUTPUT events will be generated unless an error occurs.
737 * GSOCK_CONNECTION:
738 * Connection succesfully established, for client sockets, or incoming
739 * client connection, for server sockets. Wait for this event (also watch
740 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
741 * GSOCK_LOST:
742 * The connection is lost (or a connection request failed); this could
743 * be due to a failure, or due to the peer closing it gracefully.
744 */
745
746 /* GSocket_SetCallback:
747 * Enables the callbacks specified by 'flags'. Note that 'flags'
748 * may be a combination of flags OR'ed toghether, so the same
749 * callback function can be made to accept different events.
750 * The callback function must have the following prototype:
751 *
752 * void function(GSocket *socket, GSocketEvent event, char *cdata)
753 */
754 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
755 GSocketCallback callback, char *cdata)
756 {
757 int count;
758
759 assert(socket != NULL);
760
761 for (count = 0; count < GSOCK_MAX_EVENT; count++)
762 {
763 if ((flags & (1 << count)) != 0)
764 {
765 socket->m_cbacks[count] = callback;
766 socket->m_data[count] = cdata;
767 }
768 }
769 }
770
771 /* GSocket_UnsetCallback:
772 * Disables all callbacks specified by 'flags', which may be a
773 * combination of flags OR'ed toghether.
774 */
775 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
776 {
777 int count;
778
779 assert(socket != NULL);
780
781 for (count = 0; count < GSOCK_MAX_EVENT; count++)
782 {
783 if ((flags & (1 << count)) != 0)
784 {
785 socket->m_cbacks[count] = NULL;
786 socket->m_data[count] = NULL;
787 }
788 }
789 }
790
791 /* Internals (IO) */
792
793 /* _GSocket_Input_Timeout:
794 * For blocking sockets, wait until data is available or
795 * until timeout ellapses.
796 */
797 GSocketError _GSocket_Input_Timeout(GSocket *socket)
798 {
799 fd_set readfds;
800
801 if (!socket->m_non_blocking)
802 {
803 FD_ZERO(&readfds);
804 FD_SET(socket->m_fd, &readfds);
805 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
806 {
807 socket->m_error = GSOCK_TIMEDOUT;
808 return GSOCK_TIMEDOUT;
809 }
810 }
811 return GSOCK_NOERROR;
812 }
813
814 /* _GSocket_Output_Timeout:
815 * For blocking sockets, wait until data can be sent without
816 * blocking or until timeout ellapses.
817 */
818 GSocketError _GSocket_Output_Timeout(GSocket *socket)
819 {
820 fd_set writefds;
821
822 if (!socket->m_non_blocking)
823 {
824 FD_ZERO(&writefds);
825 FD_SET(socket->m_fd, &writefds);
826 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
827 {
828 socket->m_error = GSOCK_TIMEDOUT;
829 return GSOCK_TIMEDOUT;
830 }
831 }
832 return GSOCK_NOERROR;
833 }
834
835 /* _GSocket_Connect_Timeout:
836 * For blocking sockets, wait until the connection is
837 * established or fails, or until timeout ellapses.
838 */
839 GSocketError _GSocket_Connect_Timeout(GSocket *socket)
840 {
841 fd_set writefds;
842 fd_set exceptfds;
843
844 FD_ZERO(&writefds);
845 FD_ZERO(&exceptfds);
846 FD_SET(socket->m_fd, &writefds);
847 FD_SET(socket->m_fd, &exceptfds);
848 if (select(0, NULL, &writefds, &exceptfds, &socket->m_timeout) == 0)
849 {
850 socket->m_error = GSOCK_TIMEDOUT;
851 return GSOCK_TIMEDOUT;
852 }
853 if (!FD_ISSET(socket->m_fd, &writefds))
854 {
855 socket->m_error = GSOCK_IOERR;
856 return GSOCK_IOERR;
857 }
858
859 return GSOCK_NOERROR;
860 }
861
862 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
863 {
864 return recv(socket->m_fd, buffer, size, 0);
865 }
866
867 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
868 {
869 struct sockaddr from;
870 SOCKLEN_T fromlen = sizeof(from);
871 int ret;
872 GSocketError err;
873
874 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
875
876 if (ret == SOCKET_ERROR)
877 return SOCKET_ERROR;
878
879 /* Translate a system address into a GSocket address */
880 if (!socket->m_peer)
881 {
882 socket->m_peer = GAddress_new();
883 if (!socket->m_peer)
884 {
885 socket->m_error = GSOCK_MEMERR;
886 return -1;
887 }
888 }
889 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
890 if (err != GSOCK_NOERROR)
891 {
892 GAddress_destroy(socket->m_peer);
893 socket->m_peer = NULL;
894 socket->m_error = err;
895 return -1;
896 }
897
898 return ret;
899 }
900
901 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
902 {
903 return send(socket->m_fd, buffer, size, 0);
904 }
905
906 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
907 {
908 struct sockaddr *addr;
909 int len, ret;
910 GSocketError err;
911
912 if (!socket->m_peer)
913 {
914 socket->m_error = GSOCK_INVADDR;
915 return -1;
916 }
917
918 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
919 if (err != GSOCK_NOERROR)
920 {
921 socket->m_error = err;
922 return -1;
923 }
924
925 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
926
927 /* Frees memory allocated by _GAddress_translate_to */
928 free(addr);
929
930 return ret;
931 }
932
933
934 /*
935 * -------------------------------------------------------------------------
936 * GAddress
937 * -------------------------------------------------------------------------
938 */
939
940 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
941 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
942 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
943 */
944 #define CHECK_ADDRESS(address, family, retval) \
945 { \
946 if (address->m_family == GSOCK_NOFAMILY) \
947 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
948 return address->m_error; \
949 if (address->m_family != GSOCK_##family) \
950 { \
951 address->m_error = GSOCK_INVADDR; \
952 return retval; \
953 } \
954 }
955
956 GAddress *GAddress_new()
957 {
958 GAddress *address;
959
960 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
961 return NULL;
962
963 address->m_family = GSOCK_NOFAMILY;
964 address->m_addr = NULL;
965 address->m_len = 0;
966
967 return address;
968 }
969
970 GAddress *GAddress_copy(GAddress *address)
971 {
972 GAddress *addr2;
973
974 assert(address != NULL);
975
976 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
977 return NULL;
978
979 memcpy(addr2, address, sizeof(GAddress));
980
981 if (address->m_addr)
982 {
983 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
984 if (addr2->m_addr == NULL)
985 {
986 free(addr2);
987 return NULL;
988 }
989 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
990 }
991
992 return addr2;
993 }
994
995 void GAddress_destroy(GAddress *address)
996 {
997 assert(address != NULL);
998
999 free(address);
1000 }
1001
1002 void GAddress_SetFamily(GAddress *address, GAddressType type)
1003 {
1004 assert(address != NULL);
1005
1006 address->m_family = type;
1007 }
1008
1009 GAddressType GAddress_GetFamily(GAddress *address)
1010 {
1011 assert(address != NULL);
1012
1013 return address->m_family;
1014 }
1015
1016 GSocketError _GAddress_translate_from(GAddress *address,
1017 struct sockaddr *addr, int len)
1018 {
1019 address->m_realfamily = addr->sa_family;
1020 switch (addr->sa_family)
1021 {
1022 case AF_INET:
1023 address->m_family = GSOCK_INET;
1024 break;
1025 case AF_UNIX:
1026 address->m_family = GSOCK_UNIX;
1027 break;
1028 #ifdef AF_INET6
1029 case AF_INET6:
1030 address->m_family = GSOCK_INET6;
1031 break;
1032 #endif
1033 default:
1034 {
1035 address->m_error = GSOCK_INVOP;
1036 return GSOCK_INVOP;
1037 }
1038 }
1039
1040 if (address->m_addr)
1041 free(address->m_addr);
1042
1043 address->m_len = len;
1044 address->m_addr = (struct sockaddr *) malloc(len);
1045
1046 if (address->m_addr == NULL)
1047 {
1048 address->m_error = GSOCK_MEMERR;
1049 return GSOCK_MEMERR;
1050 }
1051 memcpy(address->m_addr, addr, len);
1052
1053 return GSOCK_NOERROR;
1054 }
1055
1056 GSocketError _GAddress_translate_to(GAddress *address,
1057 struct sockaddr **addr, int *len)
1058 {
1059 if (!address->m_addr)
1060 {
1061 address->m_error = GSOCK_INVADDR;
1062 return GSOCK_INVADDR;
1063 }
1064
1065 *len = address->m_len;
1066 *addr = (struct sockaddr *) malloc(address->m_len);
1067 if (*addr == NULL)
1068 {
1069 address->m_error = GSOCK_MEMERR;
1070 return GSOCK_MEMERR;
1071 }
1072
1073 memcpy(*addr, address->m_addr, address->m_len);
1074 return GSOCK_NOERROR;
1075 }
1076
1077 /*
1078 * -------------------------------------------------------------------------
1079 * Internet address family
1080 * -------------------------------------------------------------------------
1081 */
1082
1083 GSocketError _GAddress_Init_INET(GAddress *address)
1084 {
1085 address->m_len = sizeof(struct sockaddr_in);
1086 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1087 if (address->m_addr == NULL)
1088 {
1089 address->m_error = GSOCK_MEMERR;
1090 return GSOCK_MEMERR;
1091 }
1092
1093 address->m_family = GSOCK_INET;
1094 address->m_realfamily = PF_INET;
1095 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1096 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1097
1098 return GSOCK_NOERROR;
1099 }
1100
1101 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1102 {
1103 struct hostent *he;
1104 struct in_addr *addr;
1105
1106 assert(address != NULL);
1107
1108 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1109
1110 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1111
1112 addr->s_addr = inet_addr(hostname);
1113
1114 /* If it is a numeric host name, convert it now */
1115 if (addr->s_addr == INADDR_NONE)
1116 {
1117 struct in_addr *array_addr;
1118
1119 /* It is a real name, we solve it */
1120 if ((he = gethostbyname(hostname)) == NULL)
1121 {
1122 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1123 address->m_error = GSOCK_NOHOST;
1124 return GSOCK_NOHOST;
1125 }
1126 array_addr = (struct in_addr *) *(he->h_addr_list);
1127 addr->s_addr = array_addr[0].s_addr;
1128 }
1129 return GSOCK_NOERROR;
1130 }
1131
1132 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1133 {
1134 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1135 }
1136
1137 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1138 unsigned long hostaddr)
1139 {
1140 struct in_addr *addr;
1141
1142 assert(address != NULL);
1143
1144 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1145
1146 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1147 addr->s_addr = hostaddr;
1148
1149 return GSOCK_NOERROR;
1150 }
1151
1152 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1153 const char *protocol)
1154 {
1155 struct servent *se;
1156 struct sockaddr_in *addr;
1157
1158 assert(address != NULL);
1159 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1160
1161 if (!port)
1162 {
1163 address->m_error = GSOCK_INVPORT;
1164 return GSOCK_INVPORT;
1165 }
1166
1167 se = getservbyname(port, protocol);
1168 if (!se)
1169 {
1170 if (isdigit(port[0]))
1171 {
1172 int port_int;
1173
1174 port_int = atoi(port);
1175 addr = (struct sockaddr_in *)address->m_addr;
1176 addr->sin_port = htons((u_short) port_int);
1177 return GSOCK_NOERROR;
1178 }
1179
1180 address->m_error = GSOCK_INVPORT;
1181 return GSOCK_INVPORT;
1182 }
1183
1184 addr = (struct sockaddr_in *)address->m_addr;
1185 addr->sin_port = se->s_port;
1186
1187 return GSOCK_NOERROR;
1188 }
1189
1190 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1191 {
1192 struct sockaddr_in *addr;
1193
1194 assert(address != NULL);
1195 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1196
1197 addr = (struct sockaddr_in *)address->m_addr;
1198 addr->sin_port = htons(port);
1199
1200 return GSOCK_NOERROR;
1201 }
1202
1203 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1204 {
1205 struct hostent *he;
1206 char *addr_buf;
1207 struct sockaddr_in *addr;
1208
1209 assert(address != NULL);
1210 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1211
1212 addr = (struct sockaddr_in *)address->m_addr;
1213 addr_buf = (char *)&(addr->sin_addr);
1214
1215 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1216 if (he == NULL)
1217 {
1218 address->m_error = GSOCK_NOHOST;
1219 return GSOCK_NOHOST;
1220 }
1221
1222 strncpy(hostname, he->h_name, sbuf);
1223
1224 return GSOCK_NOERROR;
1225 }
1226
1227 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1228 {
1229 struct sockaddr_in *addr;
1230
1231 assert(address != NULL);
1232 CHECK_ADDRESS(address, INET, 0);
1233
1234 addr = (struct sockaddr_in *)address->m_addr;
1235
1236 return addr->sin_addr.s_addr;
1237 }
1238
1239 unsigned short GAddress_INET_GetPort(GAddress *address)
1240 {
1241 struct sockaddr_in *addr;
1242
1243 assert(address != NULL);
1244 CHECK_ADDRESS(address, INET, 0);
1245
1246 addr = (struct sockaddr_in *)address->m_addr;
1247 return ntohs(addr->sin_port);
1248 }
1249
1250 /*
1251 * -------------------------------------------------------------------------
1252 * Unix address family
1253 * -------------------------------------------------------------------------
1254 */
1255
1256 #ifdef _MSC_VER
1257 #pragma warning(disable:4100) /* unreferenced formal parameter */
1258 #endif /* Visual C++ */
1259
1260 GSocketError _GAddress_Init_UNIX(GAddress *address)
1261 {
1262 assert (address != NULL);
1263 address->m_error = GSOCK_INVADDR;
1264 return GSOCK_INVADDR;
1265 }
1266
1267 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1268 {
1269 assert (address != NULL);
1270 address->m_error = GSOCK_INVADDR;
1271 return GSOCK_INVADDR;
1272 }
1273
1274 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1275 {
1276 assert (address != NULL);
1277 address->m_error = GSOCK_INVADDR;
1278 return GSOCK_INVADDR;
1279 }
1280
1281 #else /* !wxUSE_SOCKETS */
1282
1283 /*
1284 * Translation unit shouldn't be empty, so include this typedef to make the
1285 * compiler (VC++ 6.0, for example) happy
1286 */
1287 typedef (*wxDummy)();
1288
1289 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */