]> git.saurik.com Git - wxWidgets.git/blob - src/msw/gsocket.c
Added GSocket_Select() and fixed some things
[wxWidgets.git] / src / msw / gsocket.c
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Purpose: GSocket main MSW file
5 * CVSID: $Id$
6 * -------------------------------------------------------------------------
7 */
8
9 #ifdef __WXMSW__
10
11 #include "wx/setup.h"
12 #include "wx/msw/gsockmsw.h"
13 #include "wx/gsocket.h"
14
15 #define INSTANCE wxhInstance
16
17 #else
18
19 #include "gsockmsw.h"
20 #include "gsocket.h"
21
22 /* If not using wxWindows, a global var called hInst must
23 * be available and it must containt the app's instance
24 * handle.
25 */
26 #define INSTANCE hInst
27
28 #endif /* __WXMSW__ */
29
30
31 #if !defined(__WXMSW__) || (defined(__WXMSW__) && wxUSE_SOCKETS)
32
33 #include <assert.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stddef.h>
38 #include <ctype.h>
39 #include <winsock.h>
40
41 #define SOCKLEN_T int
42 #define CLASSNAME "_GSocket_Internal_Window_Class"
43 #define WINDOWNAME "_GSocket_Internal_Window_Name"
44
45 /* Maximum number of different GSocket objects at a given time.
46 * This value can be modified at will, but it CANNOT be greater
47 * than (0x7FFF - WM_USER + 1)
48 */
49 #define MAXSOCKETS 1024
50
51 #if (MAXSOCKETS > (0x7FFF - WM_USER + 1))
52 #error "MAXSOCKETS is too big!"
53 #endif
54
55
56 /* Global variables */
57
58 extern HINSTANCE INSTANCE;
59 static HWND hWin;
60 static CRITICAL_SECTION critical;
61 static GSocket* socketList[MAXSOCKETS];
62 static int firstAvailable;
63
64 /* Global initializers */
65
66 bool GSocket_Init()
67 {
68 WSADATA wsaData;
69 WNDCLASS winClass;
70 int i;
71
72 /* Create internal window for event notifications */
73 winClass.style = 0;
74 winClass.lpfnWndProc = _GSocket_Internal_WinProc;
75 winClass.cbClsExtra = 0;
76 winClass.cbWndExtra = 0;
77 winClass.hInstance = INSTANCE;
78 winClass.hIcon = (HICON) NULL;
79 winClass.hCursor = (HCURSOR) NULL;
80 winClass.hbrBackground = (HBRUSH) NULL;
81 winClass.lpszMenuName = (LPCTSTR) NULL;
82 winClass.lpszClassName = CLASSNAME;
83
84 RegisterClass(&winClass);
85 hWin = CreateWindow(CLASSNAME,
86 WINDOWNAME,
87 0, 0, 0, 0, 0,
88 (HWND) NULL, (HMENU) NULL, INSTANCE, (LPVOID) NULL);
89
90 if (!hWin) return FALSE;
91
92 /* Initialize socket list */
93 InitializeCriticalSection(&critical);
94
95 for (i = 0; i < MAXSOCKETS; i++)
96 {
97 socketList[i] = NULL;
98 }
99 firstAvailable = 0;
100
101 /* Initialize WinSocket */
102 return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
103 }
104
105 void GSocket_Cleanup()
106 {
107 /* Destroy internal window */
108 DestroyWindow(hWin);
109 UnregisterClass(CLASSNAME, INSTANCE);
110
111 /* Delete critical section */
112 DeleteCriticalSection(&critical);
113
114 /* Cleanup WinSocket */
115 WSACleanup();
116 }
117
118 /* Constructors / Destructors */
119
120 GSocket *GSocket_new()
121 {
122 int i;
123 GSocket *socket;
124
125 if ((socket = (GSocket *) malloc(sizeof(GSocket))) == NULL)
126 return NULL;
127
128 socket->m_fd = INVALID_SOCKET;
129 for (i = 0; i < GSOCK_MAX_EVENT; i++)
130 {
131 socket->m_cbacks[i] = NULL;
132 }
133 socket->m_local = NULL;
134 socket->m_peer = NULL;
135 socket->m_error = GSOCK_NOERROR;
136 socket->m_server = FALSE;
137 socket->m_stream = TRUE;
138 socket->m_non_blocking = FALSE;
139 socket->m_timeout.tv_sec = 10 * 60; /* 10 minutes */
140 socket->m_timeout.tv_usec = 0;
141
142 /* Allocate a new message number for this socket */
143 EnterCriticalSection(&critical);
144
145 i = firstAvailable;
146 while (socketList[i] != NULL)
147 {
148 i = (i + 1) % MAXSOCKETS;
149
150 if (i == firstAvailable) /* abort! */
151 {
152 free(socket);
153 LeaveCriticalSection(&critical);
154 return NULL;
155 }
156 }
157 socketList[i] = socket;
158 firstAvailable = (i + 1) % MAXSOCKETS;
159 socket->m_msgnumber = (i + WM_USER);
160
161 LeaveCriticalSection(&critical);
162
163 return socket;
164 }
165
166 void GSocket_destroy(GSocket *socket)
167 {
168 assert(socket != NULL);
169
170 /* We don't want more event notifications; so first of all we
171 * remove the socket from the list (NOTE: we won't get a CLOSE
172 * event for this socket if it wasn't closed before).
173 */
174 EnterCriticalSection(&critical);
175 socketList[(socket->m_msgnumber - WM_USER)] = NULL;
176 LeaveCriticalSection(&critical);
177
178 /* We check that the socket is really shutdowned */
179 if (socket->m_fd != INVALID_SOCKET)
180 GSocket_Shutdown(socket);
181
182 /* We destroy private addresses */
183 if (socket->m_local)
184 GAddress_destroy(socket->m_local);
185
186 if (socket->m_peer)
187 GAddress_destroy(socket->m_peer);
188
189 /* We destroy socket itself */
190 free(socket);
191 }
192
193 void GSocket_Shutdown(GSocket *socket)
194 {
195 int evt;
196
197 assert(socket != NULL);
198
199 /* If socket has been created, we shutdown it */
200 if (socket->m_fd != INVALID_SOCKET)
201 {
202 shutdown(socket->m_fd, 2);
203 closesocket(socket->m_fd);
204 socket->m_fd = INVALID_SOCKET;
205 }
206
207 /* We disable GUI callbacks */
208 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
209 {
210 socket->m_cbacks[evt] = NULL;
211 }
212
213 _GSocket_Configure_Callbacks(socket);
214 }
215
216 /* Address handling */
217
218 GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
219 {
220 assert(socket != NULL);
221
222 if (socket->m_fd != INVALID_SOCKET && !socket->m_server)
223 {
224 socket->m_error = GSOCK_INVSOCK;
225 return GSOCK_INVSOCK;
226 }
227
228 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
229 {
230 socket->m_error = GSOCK_INVADDR;
231 return GSOCK_INVADDR;
232 }
233
234 if (socket->m_local)
235 GAddress_destroy(socket->m_local);
236
237 socket->m_local = GAddress_copy(address);
238
239 return GSOCK_NOERROR;
240 }
241
242 GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
243 {
244 assert(socket != NULL);
245
246 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
247 {
248 socket->m_error = GSOCK_INVADDR;
249 return GSOCK_INVADDR;
250 }
251
252 if (socket->m_peer)
253 GAddress_destroy(socket->m_peer);
254
255 socket->m_peer = GAddress_copy(address);
256
257 return GSOCK_NOERROR;
258 }
259
260 GAddress *GSocket_GetLocal(GSocket *socket)
261 {
262 GAddress *address;
263 struct sockaddr addr;
264 SOCKLEN_T size;
265
266 assert(socket != NULL);
267
268 if (socket->m_local)
269 return GAddress_copy(socket->m_local);
270
271 if (socket->m_fd == INVALID_SOCKET)
272 {
273 socket->m_error = GSOCK_INVSOCK;
274 return NULL;
275 }
276
277 size = sizeof(addr);
278
279 if (getsockname(socket->m_fd, &addr, &size) == SOCKET_ERROR)
280 {
281 socket->m_error = GSOCK_IOERR;
282 return NULL;
283 }
284
285 address = GAddress_new();
286 if (address == NULL)
287 {
288 socket->m_error = GSOCK_MEMERR;
289 return NULL;
290 }
291 if (_GAddress_translate_from(address, &addr, size) != GSOCK_NOERROR)
292 {
293 socket->m_error = GSOCK_MEMERR;
294 GAddress_destroy(address);
295 return NULL;
296 }
297
298 return address;
299 }
300
301 GAddress *GSocket_GetPeer(GSocket *socket)
302 {
303 assert(socket != NULL);
304
305 if (socket->m_peer)
306 return GAddress_copy(socket->m_peer);
307
308 return NULL;
309 }
310
311 /* Server specific parts */
312
313 /* GSocket_SetServer:
314 * Sets up the socket as a server. It uses the "Local" field of GSocket.
315 * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
316 * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
317 * been initialized, GSOCK_INVADDR if the local address has not been
318 * defined and GSOCK_IOERR for other internal errors.
319 */
320 GSocketError GSocket_SetServer(GSocket *sck)
321 {
322 u_long arg = 1;
323
324 assert(sck != NULL);
325
326 if (sck->m_fd != INVALID_SOCKET)
327 {
328 sck->m_error = GSOCK_INVSOCK;
329 return GSOCK_INVSOCK;
330 }
331
332 if (!sck->m_local)
333 {
334 sck->m_error = GSOCK_INVADDR;
335 return GSOCK_INVADDR;
336 }
337
338 /* Initialize all fields */
339 sck->m_server = TRUE;
340 sck->m_stream = TRUE;
341 sck->m_oriented = TRUE;
342
343 /* Create the socket */
344 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
345
346 if (sck->m_fd == INVALID_SOCKET)
347 {
348 sck->m_error = GSOCK_IOERR;
349 return GSOCK_IOERR;
350 }
351
352 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
353 _GSocket_Configure_Callbacks(sck);
354
355 /* Bind the socket to the LOCAL address */
356 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0)
357 {
358 closesocket(sck->m_fd);
359 sck->m_fd = INVALID_SOCKET;
360 sck->m_error = GSOCK_IOERR;
361 return GSOCK_IOERR;
362 }
363
364 /* Enable listening up to 5 connections */
365 if (listen(sck->m_fd, 5) != 0)
366 {
367 closesocket(sck->m_fd);
368 sck->m_fd = INVALID_SOCKET;
369 sck->m_error = GSOCK_IOERR;
370 return GSOCK_IOERR;
371 }
372
373 return GSOCK_NOERROR;
374 }
375
376 /* GSocket_WaitConnection:
377 * Waits for an incoming client connection.
378 */
379 GSocket *GSocket_WaitConnection(GSocket *sck)
380 {
381 GSocket *connection;
382 u_long arg = 1;
383
384 assert(sck != NULL);
385
386 /* If the socket has already been created, we exit immediately */
387 if (sck->m_fd == INVALID_SOCKET || !sck->m_server)
388 {
389 sck->m_error = GSOCK_INVSOCK;
390 return NULL;
391 }
392
393 /* Create a GSocket object for the new connection */
394 connection = GSocket_new();
395
396 if (!connection)
397 {
398 sck->m_error = GSOCK_MEMERR;
399 return NULL;
400 }
401
402 /* Wait for a connection (with timeout) */
403 if (_GSocket_Input_Timeout(sck) == GSOCK_TIMEDOUT)
404 {
405 GSocket_destroy(connection);
406 /* sck->m_error set by _GSocket_Input_Timeout */
407 return NULL;
408 }
409
410 connection->m_fd = accept(sck->m_fd, NULL, NULL);
411
412 if (connection->m_fd == INVALID_SOCKET)
413 {
414 if (WSAGetLastError() == WSAEWOULDBLOCK)
415 sck->m_error = GSOCK_WOULDBLOCK;
416 else
417 sck->m_error = GSOCK_IOERR;
418
419 GSocket_destroy(connection);
420 return NULL;
421 }
422
423 /* Initialize all fields */
424 connection->m_server = FALSE;
425 connection->m_stream = TRUE;
426 connection->m_oriented = TRUE;
427
428 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
429 _GSocket_Configure_Callbacks(connection);
430
431 return connection;
432 }
433
434 /* Non oriented connections */
435
436 GSocketError GSocket_SetNonOriented(GSocket *sck)
437 {
438 u_long arg = 1;
439
440 assert(sck != NULL);
441
442 if (sck->m_fd != INVALID_SOCKET)
443 {
444 sck->m_error = GSOCK_INVSOCK;
445 return GSOCK_INVSOCK;
446 }
447
448 if (!sck->m_local)
449 {
450 sck->m_error = GSOCK_INVADDR;
451 return GSOCK_INVADDR;
452 }
453
454 /* Initialize all fields */
455 sck->m_stream = FALSE;
456 sck->m_server = FALSE;
457 sck->m_oriented = FALSE;
458
459 /* Create the socket */
460 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
461
462 if (sck->m_fd == INVALID_SOCKET)
463 {
464 sck->m_error = GSOCK_IOERR;
465 return GSOCK_IOERR;
466 }
467
468 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
469 _GSocket_Configure_Callbacks(sck);
470
471 /* Bind it to the LOCAL address */
472 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0)
473 {
474 closesocket(sck->m_fd);
475 sck->m_fd = INVALID_SOCKET;
476 sck->m_error = GSOCK_IOERR;
477 return GSOCK_IOERR;
478 }
479
480 return GSOCK_NOERROR;
481 }
482
483 GSocketError GSocket_SetBroadcast(GSocket *sck)
484 {
485 BOOL b;
486
487 assert(sck != NULL);
488
489 if (GSocket_SetNonOriented(sck) != GSOCK_NOERROR)
490 return sck->m_error;
491
492 b = TRUE;
493 setsockopt(sck->m_fd, SOL_SOCKET, SO_BROADCAST, (const char FAR *) &b, sizeof(b));
494
495 return GSOCK_NOERROR;
496 }
497
498 /* Client specific parts */
499
500 /* GSocket_Connect:
501 * Establishes a client connection to a server using the "Peer"
502 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
503 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
504 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
505 * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
506 * the connection request can be completed later. Use GSocket_Select()
507 * to check or wait for a GSOCK_CONNECTION event.
508 */
509 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
510 {
511 u_long arg = 1;
512 int type, ret, err;
513
514 assert(sck != NULL);
515
516 if (sck->m_fd != INVALID_SOCKET)
517 {
518 sck->m_error = GSOCK_INVSOCK;
519 return GSOCK_INVSOCK;
520 }
521
522 if (!sck->m_peer)
523 {
524 sck->m_error = GSOCK_INVADDR;
525 return GSOCK_INVADDR;
526 }
527
528 /* Test whether we want the socket to be a stream (e.g. TCP) */
529 sck->m_stream = (stream == GSOCK_STREAMED);
530 sck->m_oriented = TRUE;
531 sck->m_server = FALSE;
532
533 if (sck->m_stream)
534 type = SOCK_STREAM;
535 else
536 type = SOCK_DGRAM;
537
538 /* Create the socket */
539 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
540
541 if (sck->m_fd == INVALID_SOCKET)
542 {
543 sck->m_error = GSOCK_IOERR;
544 return GSOCK_IOERR;
545 }
546
547 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
548 _GSocket_Configure_Callbacks(sck);
549
550 /* Connect it to the PEER address, with a timeout (see below) */
551 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
552
553 if (ret == SOCKET_ERROR)
554 {
555 err = WSAGetLastError();
556
557 /* If connect failed with EWOULDBLOCK and the GSocket object
558 * is in blocking mode, we select() for the specified timeout
559 * checking for writability to see if the connection request
560 * completes.
561 */
562 if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking))
563 {
564 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
565 {
566 closesocket(sck->m_fd);
567 sck->m_fd = INVALID_SOCKET;
568 /* sck->m_error is set in _GSocket_Output_Timeout */
569 return GSOCK_TIMEDOUT;
570 }
571 else
572 return GSOCK_NOERROR;
573 }
574
575 /* If connect failed with EWOULDBLOCK and the GSocket object
576 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
577 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
578 * this way if the connection completes, a GSOCK_CONNECTION
579 * event will be generated, if enabled.
580 */
581 if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking))
582 {
583 sck->m_error = GSOCK_WOULDBLOCK;
584 return GSOCK_WOULDBLOCK;
585 }
586
587 /* If connect failed with an error other than EWOULDBLOCK,
588 * then the call to GSocket_Connect has failed.
589 */
590 closesocket(sck->m_fd);
591 sck->m_fd = INVALID_SOCKET;
592 sck->m_error = GSOCK_IOERR;
593 return GSOCK_IOERR;
594 }
595
596 return GSOCK_NOERROR;
597 }
598
599 /* Generic IO */
600
601 /* Like recv(), send(), ... */
602 int GSocket_Read(GSocket *socket, char *buffer, int size)
603 {
604 assert(socket != NULL);
605
606 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
607 {
608 socket->m_error = GSOCK_INVSOCK;
609 return -1;
610 }
611
612 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
613 return -1;
614
615 if (socket->m_stream)
616 return _GSocket_Recv_Stream(socket, buffer, size);
617 else
618 return _GSocket_Recv_Dgram(socket, buffer, size);
619 }
620
621 int GSocket_Write(GSocket *socket, const char *buffer, int size)
622 {
623 assert(socket != NULL);
624
625 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
626 {
627 socket->m_error = GSOCK_INVSOCK;
628 return -1;
629 }
630
631 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
632 return -1;
633
634 if (socket->m_stream)
635 return _GSocket_Send_Stream(socket, buffer, size);
636 else
637 return _GSocket_Send_Dgram(socket, buffer, size);
638 }
639
640 /* GSocket_Select:
641 * Polls the socket to determine its status. This function will
642 * check for the events specified in the 'flags' parameter, and
643 * it will return a mask indicating which operations can be
644 * performed. This function won't block, regardless of the
645 * mode (blocking|nonblocking) of the socket.
646 */
647 GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
648 {
649 fd_set readfds, writefds, exceptfds;
650 struct timeval tv;
651 GSocketEventFlags mask;
652
653 assert(socket != NULL);
654
655 if (socket->m_fd == INVALID_SOCKET)
656 {
657 socket->m_error = GSOCK_INVSOCK;
658 return FALSE;
659 }
660
661 FD_ZERO(&readfds);
662 FD_ZERO(&writefds);
663 FD_ZERO(&exceptfds);
664 FD_SET(socket->m_fd, &readfds);
665 FD_SET(socket->m_fd, &writefds);
666 FD_SET(socket->m_fd, &exceptfds);
667
668 tv.tv_sec = 0;
669 tv.tv_usec = 0;
670 select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv);
671
672 mask = 0;
673
674 /* If select() says that the socket is readable, then we have
675 * no way to distinguish if that means 'data available' (to
676 * recv) or 'incoming connection' (to accept). The same goes
677 * for writability: we cannot distinguish between 'you can
678 * send data' and 'connection request completed'. So we will
679 * assume the following: if the flag was set upon entry,
680 * that means that the event was possible.
681 */
682 if (FD_ISSET(socket->m_fd, &readfds))
683 {
684 mask |= (flags & GSOCK_CONNECTION_FLAG);
685 mask |= (flags & GSOCK_INPUT_FLAG);
686 }
687 if (FD_ISSET(socket->m_fd, &writefds))
688 {
689 mask |= (flags & GSOCK_CONNECTION_FLAG);
690 mask |= (flags & GSOCK_OUTPUT_FLAG);
691 }
692 if (FD_ISSET(socket->m_fd, &exceptfds))
693 mask |= (flags & GSOCK_LOST_FLAG);
694
695 return mask;
696 }
697
698 /* Flags */
699
700 /* GSocket_SetNonBlocking:
701 * Sets the socket to non-blocking mode. This is useful if
702 * we don't want to wait.
703 */
704 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
705 {
706 assert(socket != NULL);
707
708 socket->m_non_blocking = non_block;
709 }
710
711 /* GSocket_SetTimeout:
712 * Sets the timeout for blocking calls. Time is
713 * expressed in milliseconds.
714 */
715 void GSocket_SetTimeout(GSocket *socket, unsigned long millisecs)
716 {
717 assert(socket != NULL);
718
719 socket->m_timeout.tv_sec = (millisecs / 1000);
720 socket->m_timeout.tv_usec = (millisecs % 1000) * 1000;
721 }
722
723 /* GSocket_GetError:
724 * Returns the last error occured for this socket.
725 */
726 GSocketError GSocket_GetError(GSocket *socket)
727 {
728 assert(socket != NULL);
729
730 return socket->m_error;
731 }
732
733 /* Callbacks */
734
735 /* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
736 * and LOST). The callbacks are called in the following situations:
737 *
738 * INPUT: There is at least one byte in the input buffer
739 * OUTPUT: The system is sure that the next write call will not block
740 * CONNECTION: Two cases are possible:
741 * Client socket -> the connection is established
742 * Server socket -> a client requests a connection
743 * LOST: The connection is lost
744 *
745 * An event is generated only once and its state is reseted when the
746 * relative IO call is requested.
747 * For example: INPUT -> GSocket_Read()
748 * CONNECTION -> GSocket_Accept()
749 */
750
751 /* GSocket_SetCallback:
752 * Enables the callbacks specified by 'flags'. Note that 'flags'
753 * may be a combination of flags OR'ed toghether, so the same
754 * callback function can be made to accept different events.
755 * The callback function must have the following prototype:
756 *
757 * void function(GSocket *socket, GSocketEvent event, char *cdata)
758 */
759 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
760 GSocketCallback callback, char *cdata)
761 {
762 int count;
763
764 assert (socket != NULL);
765
766 for (count = 0; count < GSOCK_MAX_EVENT; count++)
767 {
768 /* We test each flag and enable the corresponding events */
769 if ((flags & (1 << count)) != 0)
770 {
771 socket->m_cbacks[count] = callback;
772 socket->m_data[count] = cdata;
773 }
774 }
775
776 _GSocket_Configure_Callbacks(socket);
777 }
778
779 /* GSocket_UnsetCallback:
780 * Disables all callbacks specified by 'flags', which may be a
781 * combination of flags OR'ed toghether.
782 */
783 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
784 {
785 int count = 0;
786
787 assert(socket != NULL);
788
789 for (count = 0; count < GSOCK_MAX_EVENT; count++)
790 {
791 /* We test each flag and disable the corresponding events */
792 if ((flags & (1 << count)) != 0)
793 {
794 socket->m_cbacks[count] = NULL;
795 }
796 }
797
798 _GSocket_Configure_Callbacks(socket);
799 }
800
801
802 /* Internals */
803
804 void _GSocket_Configure_Callbacks(GSocket *socket)
805 {
806 long mask = 0;
807 int count;
808
809 if (socket->m_fd == INVALID_SOCKET)
810 return;
811
812 for (count = 0; count < GSOCK_MAX_EVENT; count++)
813 {
814 if (socket->m_cbacks[count] != NULL)
815 {
816 switch (count)
817 {
818 case GSOCK_INPUT: mask |= FD_READ; break;
819 case GSOCK_OUTPUT: mask |= FD_WRITE; break;
820 case GSOCK_CONNECTION: mask |= (FD_ACCEPT | FD_CONNECT); break;
821 case GSOCK_LOST: mask |= FD_CLOSE; break;
822 }
823 }
824 }
825
826 WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, mask);
827 }
828
829 LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd,
830 UINT uMsg,
831 WPARAM wParam,
832 LPARAM lParam)
833 {
834 GSocket *socket;
835 GSocketEvent event;
836 GSocketCallback cback;
837
838 if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1))
839 {
840 EnterCriticalSection(&critical);
841 socket = socketList[(uMsg - WM_USER)];
842 event = -1;
843 cback = NULL;
844
845 /* Check that the socket still exists (it has not been
846 * destroyed) and for safety, check that the m_fd field
847 * is what we expect it to be.
848 */
849 if ((socket != NULL) && (socket->m_fd == wParam))
850 {
851 switch WSAGETSELECTEVENT(lParam)
852 {
853 case FD_READ: event = GSOCK_INPUT; break;
854 case FD_WRITE: event = GSOCK_OUTPUT; break;
855 case FD_ACCEPT: event = GSOCK_CONNECTION; break;
856 case FD_CONNECT:
857 {
858 if (WSAGETSELECTERROR(lParam) != 0)
859 event = GSOCK_LOST;
860 else
861 event = GSOCK_CONNECTION;
862 break;
863 }
864 case FD_CLOSE: event = GSOCK_LOST; break;
865 }
866
867 if (event != -1)
868 cback = socket->m_cbacks[event];
869 }
870
871 /* OK, we can now leave the critical section because we have
872 * already obtained the callback address (we make no further
873 * accesses to socket->whatever)
874 */
875 LeaveCriticalSection(&critical);
876
877 if (cback != NULL)
878 (cback)(socket, event, socket->m_data[event]);
879
880 return (LRESULT) 0;
881 }
882 else
883 return DefWindowProc(hWnd, uMsg, wParam, lParam);
884 }
885
886
887 /* _GSocket_Input_Timeout:
888 * For blocking sockets, wait until data is available or
889 * until timeout ellapses.
890 */
891 GSocketError _GSocket_Input_Timeout(GSocket *socket)
892 {
893 fd_set readfds;
894
895 if (!socket->m_non_blocking)
896 {
897 FD_ZERO(&readfds);
898 FD_SET(socket->m_fd, &readfds);
899 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
900 {
901 socket->m_error = GSOCK_TIMEDOUT;
902 return GSOCK_TIMEDOUT;
903 }
904 }
905 return GSOCK_NOERROR;
906 }
907
908 /* _GSocket_Output_Timeout:
909 * For blocking sockets, wait until data can be sent without
910 * blocking or until timeout ellapses.
911 */
912 GSocketError _GSocket_Output_Timeout(GSocket *socket)
913 {
914 fd_set writefds;
915
916 if (!socket->m_non_blocking)
917 {
918 FD_ZERO(&writefds);
919 FD_SET(socket->m_fd, &writefds);
920 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
921 {
922 socket->m_error = GSOCK_TIMEDOUT;
923 return GSOCK_TIMEDOUT;
924 }
925 }
926 return GSOCK_NOERROR;
927 }
928
929 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
930 {
931 int ret;
932
933 ret = recv(socket->m_fd, buffer, size, 0);
934
935 if (ret == SOCKET_ERROR)
936 {
937 if (WSAGetLastError() != WSAEWOULDBLOCK)
938 socket->m_error = GSOCK_IOERR;
939 else
940 socket->m_error = GSOCK_WOULDBLOCK;
941
942 return -1;
943 }
944
945 return ret;
946 }
947
948 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
949 {
950 struct sockaddr from;
951 SOCKLEN_T fromlen;
952 int ret;
953
954 fromlen = sizeof(from);
955
956 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
957
958 if (ret == SOCKET_ERROR)
959 {
960 if (WSAGetLastError() != WSAEWOULDBLOCK)
961 socket->m_error = GSOCK_IOERR;
962 else
963 socket->m_error = GSOCK_WOULDBLOCK;
964
965 return -1;
966 }
967
968 /* Translate a system address into a GSocket address */
969 if (!socket->m_peer)
970 {
971 socket->m_peer = GAddress_new();
972 if (!socket->m_peer)
973 {
974 socket->m_error = GSOCK_MEMERR;
975 return -1;
976 }
977 }
978 if (_GAddress_translate_from(socket->m_peer, &from, fromlen) != GSOCK_NOERROR)
979 {
980 socket->m_error = GSOCK_MEMERR;
981 GAddress_destroy(socket->m_peer);
982 return -1;
983 }
984
985 return ret;
986 }
987
988 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
989 {
990 int ret;
991
992 ret = send(socket->m_fd, buffer, size, 0);
993
994 if (ret == SOCKET_ERROR)
995 {
996 if (WSAGetLastError() != WSAEWOULDBLOCK)
997 socket->m_error = GSOCK_IOERR;
998 else
999 socket->m_error = GSOCK_WOULDBLOCK;
1000
1001 return -1;
1002 }
1003 return ret;
1004 }
1005
1006 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
1007 {
1008 struct sockaddr *addr;
1009 int len, ret;
1010
1011 if (!socket->m_peer)
1012 {
1013 socket->m_error = GSOCK_INVADDR;
1014 return -1;
1015 }
1016
1017 if (!_GAddress_translate_to(socket->m_peer, &addr, &len))
1018 {
1019 socket->m_error = GSOCK_MEMERR;
1020 return -1;
1021 }
1022
1023 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1024
1025 /* Frees memory allocated by _GAddress_translate_to */
1026 free(addr);
1027
1028 if (ret == SOCKET_ERROR)
1029 {
1030 if (WSAGetLastError() != WSAEWOULDBLOCK)
1031 socket->m_error = GSOCK_IOERR;
1032 else
1033 socket->m_error = GSOCK_WOULDBLOCK;
1034
1035 return -1;
1036 }
1037 return ret;
1038 }
1039
1040
1041 /*
1042 * -------------------------------------------------------------------------
1043 * GAddress
1044 * -------------------------------------------------------------------------
1045 */
1046
1047 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
1048 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
1049 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
1050 */
1051 #define CHECK_ADDRESS(address, family, retval) \
1052 { \
1053 if (address->m_family == GSOCK_NOFAMILY) \
1054 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1055 return address->m_error; \
1056 if (address->m_family != GSOCK_##family) \
1057 { \
1058 address->m_error = GSOCK_INVADDR; \
1059 return retval; \
1060 } \
1061 }
1062
1063 GAddress *GAddress_new()
1064 {
1065 GAddress *address;
1066
1067 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1068 return NULL;
1069
1070 address->m_family = GSOCK_NOFAMILY;
1071 address->m_addr = NULL;
1072 address->m_len = 0;
1073
1074 return address;
1075 }
1076
1077 GAddress *GAddress_copy(GAddress *address)
1078 {
1079 GAddress *addr2;
1080
1081 assert(address != NULL);
1082
1083 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1084 return NULL;
1085
1086 memcpy(addr2, address, sizeof(GAddress));
1087
1088 if (address->m_addr)
1089 {
1090 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1091 if (addr2->m_addr == NULL)
1092 {
1093 free(addr2);
1094 return NULL;
1095 }
1096 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1097 }
1098
1099 return addr2;
1100 }
1101
1102 void GAddress_destroy(GAddress *address)
1103 {
1104 assert(address != NULL);
1105
1106 free(address);
1107 }
1108
1109 void GAddress_SetFamily(GAddress *address, GAddressType type)
1110 {
1111 assert(address != NULL);
1112
1113 address->m_family = type;
1114 }
1115
1116 GAddressType GAddress_GetFamily(GAddress *address)
1117 {
1118 assert(address != NULL);
1119
1120 return address->m_family;
1121 }
1122
1123 GSocketError _GAddress_translate_from(GAddress *address,
1124 struct sockaddr *addr, int len)
1125 {
1126 address->m_realfamily = addr->sa_family;
1127 switch (addr->sa_family)
1128 {
1129 case AF_INET:
1130 address->m_family = GSOCK_INET;
1131 break;
1132 case AF_UNIX:
1133 address->m_family = GSOCK_UNIX;
1134 break;
1135 #ifdef AF_INET6
1136 case AF_INET6:
1137 address->m_family = GSOCK_INET6;
1138 break;
1139 #endif
1140 default:
1141 {
1142 address->m_error = GSOCK_INVOP;
1143 return GSOCK_INVOP;
1144 }
1145 }
1146
1147 if (address->m_addr)
1148 free(address->m_addr);
1149
1150 address->m_len = len;
1151 address->m_addr = (struct sockaddr *) malloc(len);
1152
1153 if (address->m_addr == NULL)
1154 {
1155 address->m_error = GSOCK_MEMERR;
1156 return GSOCK_MEMERR;
1157 }
1158 memcpy(address->m_addr, addr, len);
1159
1160 return GSOCK_NOERROR;
1161 }
1162
1163 GSocketError _GAddress_translate_to(GAddress *address,
1164 struct sockaddr **addr, int *len)
1165 {
1166 if (!address->m_addr)
1167 {
1168 address->m_error = GSOCK_INVADDR;
1169 return GSOCK_INVADDR;
1170 }
1171
1172 *len = address->m_len;
1173 *addr = (struct sockaddr *) malloc(address->m_len);
1174 if (*addr == NULL)
1175 {
1176 address->m_error = GSOCK_MEMERR;
1177 return GSOCK_MEMERR;
1178 }
1179
1180 memcpy(*addr, address->m_addr, address->m_len);
1181 return GSOCK_NOERROR;
1182 }
1183
1184 /*
1185 * -------------------------------------------------------------------------
1186 * Internet address family
1187 * -------------------------------------------------------------------------
1188 */
1189
1190 GSocketError _GAddress_Init_INET(GAddress *address)
1191 {
1192 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1193 if (address->m_addr == NULL)
1194 {
1195 address->m_error = GSOCK_MEMERR;
1196 return GSOCK_MEMERR;
1197 }
1198
1199 address->m_len = sizeof(struct sockaddr_in);
1200 address->m_family = GSOCK_INET;
1201 address->m_realfamily = PF_INET;
1202 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1203 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1204
1205 return GSOCK_NOERROR;
1206 }
1207
1208 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1209 {
1210 struct hostent *he;
1211 struct in_addr *addr;
1212
1213 assert(address != NULL);
1214
1215 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1216
1217 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1218
1219 addr->s_addr = inet_addr(hostname);
1220
1221 /* If it is a numeric host name, convert it now */
1222 if (addr->s_addr == INADDR_NONE)
1223 {
1224 struct in_addr *array_addr;
1225
1226 /* It is a real name, we solve it */
1227 if ((he = gethostbyname(hostname)) == NULL)
1228 {
1229 address->m_error = GSOCK_NOHOST;
1230 return GSOCK_NOHOST;
1231 }
1232 array_addr = (struct in_addr *) *(he->h_addr_list);
1233 addr->s_addr = array_addr[0].s_addr;
1234 }
1235 return GSOCK_NOERROR;
1236 }
1237
1238 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1239 unsigned long hostaddr)
1240 {
1241 struct in_addr *addr;
1242
1243 assert(address != NULL);
1244
1245 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1246
1247 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1248 addr->s_addr = hostaddr;
1249
1250 return GSOCK_NOERROR;
1251 }
1252
1253 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1254 const char *protocol)
1255 {
1256 struct servent *se;
1257 struct sockaddr_in *addr;
1258
1259 assert(address != NULL);
1260 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1261
1262 if (!port)
1263 {
1264 address->m_error = GSOCK_INVPORT;
1265 return GSOCK_INVOP;
1266 }
1267
1268 se = getservbyname(port, protocol);
1269 if (!se)
1270 {
1271 if (isdigit(port[0]))
1272 {
1273 int port_int;
1274
1275 port_int = atoi(port);
1276 addr = (struct sockaddr_in *)address->m_addr;
1277 addr->sin_port = htons((u_short) port_int);
1278 return GSOCK_NOERROR;
1279 }
1280
1281 address->m_error = GSOCK_INVPORT;
1282 return GSOCK_INVPORT;
1283 }
1284
1285 addr = (struct sockaddr_in *)address->m_addr;
1286 addr->sin_port = se->s_port;
1287
1288 return GSOCK_NOERROR;
1289 }
1290
1291 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1292 {
1293 struct sockaddr_in *addr;
1294
1295 assert(address != NULL);
1296 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1297
1298 addr = (struct sockaddr_in *)address->m_addr;
1299 addr->sin_port = htons(port);
1300
1301 return GSOCK_NOERROR;
1302 }
1303
1304 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1305 {
1306 struct hostent *he;
1307 char *addr_buf;
1308 struct sockaddr_in *addr;
1309
1310 assert(address != NULL);
1311 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1312
1313 addr = (struct sockaddr_in *)address->m_addr;
1314 addr_buf = (char *)&(addr->sin_addr);
1315
1316 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1317 if (he == NULL)
1318 {
1319 address->m_error = GSOCK_NOHOST;
1320 return GSOCK_NOHOST;
1321 }
1322
1323 strncpy(hostname, he->h_name, sbuf);
1324
1325 return GSOCK_NOERROR;
1326 }
1327
1328 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1329 {
1330 struct sockaddr_in *addr;
1331
1332 assert(address != NULL);
1333 CHECK_ADDRESS(address, INET, 0);
1334
1335 addr = (struct sockaddr_in *)address->m_addr;
1336
1337 return addr->sin_addr.s_addr;
1338 }
1339
1340 unsigned short GAddress_INET_GetPort(GAddress *address)
1341 {
1342 struct sockaddr_in *addr;
1343
1344 assert(address != NULL);
1345 CHECK_ADDRESS(address, INET, 0);
1346
1347 addr = (struct sockaddr_in *)address->m_addr;
1348 return ntohs(addr->sin_port);
1349 }
1350
1351 /*
1352 * -------------------------------------------------------------------------
1353 * Unix address family
1354 * -------------------------------------------------------------------------
1355 */
1356
1357 GSocketError _GAddress_Init_UNIX(GAddress *address)
1358 {
1359 assert (address != NULL);
1360 address->m_error = GSOCK_INVADDR;
1361 return GSOCK_INVADDR;
1362 }
1363
1364 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1365 {
1366 assert (address != NULL);
1367 address->m_error = GSOCK_INVADDR;
1368 return GSOCK_INVADDR;
1369 }
1370
1371 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1372 {
1373 assert (address != NULL);
1374 address->m_error = GSOCK_INVADDR;
1375 return GSOCK_INVADDR;
1376 }
1377
1378
1379 #endif /* !defined(__WXMSW__) || (defined(__WXMSW__) && wxUSE_SOCKETS) */
1380
1381
1382
1383 /* Diferencias con la version Unix:
1384 * - El descriptor es SOCKET y no int
1385 * - Constantes -1 pasan a INVALID_SOCKET
1386 * - Errores en muchas funciones pasan de -1 o <0 a SOCKET_ERROR
1387 * - ioctl y close pasan a ioctlsocket y closesocket
1388 * - inet_addr en lugar de inet_aton
1389 * - Codigo de inicializacion y terminacion para inicializar y
1390 * terminar WinSocket y para la ventana interna.
1391 * - SetTimeout en la version MSW simplemente guarda el valor en
1392 * socket.m_timeout, por tanto no hay necesidad de llamar a
1393 * SetTimeout cada vez que se crea realmente un socket (no
1394 * un gsocket).
1395 * - Lo mismo para SetNonBlocking.
1396 */