]> git.saurik.com Git - wxWidgets.git/blob - src/msw/gsocket.c
Fixed some bus in Connect()
[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 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
346
347 if (sck->m_fd == INVALID_SOCKET)
348 {
349 sck->m_error = GSOCK_IOERR;
350 return GSOCK_IOERR;
351 }
352
353 /* Bind the socket to the LOCAL address */
354 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0)
355 {
356 closesocket(sck->m_fd);
357 sck->m_fd = INVALID_SOCKET;
358 sck->m_error = GSOCK_IOERR;
359 return GSOCK_IOERR;
360 }
361
362 /* Enable listening up to 5 connections */
363 if (listen(sck->m_fd, 5) != 0)
364 {
365 closesocket(sck->m_fd);
366 sck->m_fd = INVALID_SOCKET;
367 sck->m_error = GSOCK_IOERR;
368 return GSOCK_IOERR;
369 }
370
371 return GSOCK_NOERROR;
372 }
373
374 /* GSocket_WaitConnection:
375 * Waits for an incoming client connection.
376 */
377 GSocket *GSocket_WaitConnection(GSocket *sck)
378 {
379 GSocket *connection;
380 u_long arg = 1;
381
382 assert(sck != NULL);
383
384 /* If the socket has already been created, we exit immediately */
385 if (sck->m_fd == INVALID_SOCKET || !sck->m_server)
386 {
387 sck->m_error = GSOCK_INVSOCK;
388 return NULL;
389 }
390
391 /* Create a GSocket object for the new connection */
392 connection = GSocket_new();
393
394 if (!connection)
395 {
396 sck->m_error = GSOCK_MEMERR;
397 return NULL;
398 }
399
400 /* Wait for a connection (with timeout) */
401 if (_GSocket_Input_Timeout(sck) == GSOCK_TIMEDOUT)
402 {
403 GSocket_destroy(connection);
404 /* sck->m_error set by _GSocket_Input_Timeout */
405 return NULL;
406 }
407
408 connection->m_fd = accept(sck->m_fd, NULL, NULL);
409
410 if (connection->m_fd == INVALID_SOCKET)
411 {
412 if (WSAGetLastError() == WSAEWOULDBLOCK)
413 sck->m_error = GSOCK_WOULDBLOCK;
414 else
415 sck->m_error = GSOCK_IOERR;
416
417 GSocket_destroy(connection);
418 return NULL;
419 }
420
421 /* Initialize all fields */
422 connection->m_server = FALSE;
423 connection->m_stream = TRUE;
424 connection->m_oriented = TRUE;
425
426 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
427
428 return connection;
429 }
430
431 /* Non oriented connections */
432
433 GSocketError GSocket_SetNonOriented(GSocket *sck)
434 {
435 u_long arg = 1;
436
437 assert(sck != NULL);
438
439 if (sck->m_fd != INVALID_SOCKET)
440 {
441 sck->m_error = GSOCK_INVSOCK;
442 return GSOCK_INVSOCK;
443 }
444
445 if (!sck->m_local)
446 {
447 sck->m_error = GSOCK_INVADDR;
448 return GSOCK_INVADDR;
449 }
450
451 /* Initialize all fields */
452 sck->m_stream = FALSE;
453 sck->m_server = FALSE;
454 sck->m_oriented = FALSE;
455
456 /* Create the socket */
457 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
458 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
459
460 if (sck->m_fd == INVALID_SOCKET)
461 {
462 sck->m_error = GSOCK_IOERR;
463 return GSOCK_IOERR;
464 }
465
466 /* Bind it to the LOCAL address */
467 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0)
468 {
469 closesocket(sck->m_fd);
470 sck->m_fd = INVALID_SOCKET;
471 sck->m_error = GSOCK_IOERR;
472 return GSOCK_IOERR;
473 }
474
475 return GSOCK_NOERROR;
476 }
477
478 GSocketError GSocket_SetBroadcast(GSocket *sck)
479 {
480 BOOL b;
481
482 assert(sck != NULL);
483
484 if (GSocket_SetNonOriented(sck) != GSOCK_NOERROR)
485 return sck->m_error;
486
487 b = TRUE;
488 setsockopt(sck->m_fd, SOL_SOCKET, SO_BROADCAST, (const char FAR *) &b, sizeof(b));
489
490 return GSOCK_NOERROR;
491 }
492
493 /* Client specific parts */
494
495 /* GSocket_Connect:
496 * Establishes a client connection to a server using the "Peer"
497 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
498 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
499 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
500 */
501 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
502 {
503 u_long arg = 1;
504 int type, ret, err;
505
506 assert(sck != NULL);
507
508 if (sck->m_fd != INVALID_SOCKET)
509 {
510 sck->m_error = GSOCK_INVSOCK;
511 return GSOCK_INVSOCK;
512 }
513
514 if (!sck->m_peer)
515 {
516 sck->m_error = GSOCK_INVADDR;
517 return GSOCK_INVADDR;
518 }
519
520 /* Test whether we want the socket to be a stream (e.g. TCP) */
521 sck->m_stream = (stream == GSOCK_STREAMED);
522 sck->m_oriented = TRUE;
523 sck->m_server = FALSE;
524
525 if (sck->m_stream)
526 type = SOCK_STREAM;
527 else
528 type = SOCK_DGRAM;
529
530 /* Create the socket */
531 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
532 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
533
534 if (sck->m_fd == INVALID_SOCKET)
535 {
536 sck->m_error = GSOCK_IOERR;
537 return GSOCK_IOERR;
538 }
539
540 /* Connect it to the PEER address, with a timeout (see below) */
541 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
542
543 if (ret == SOCKET_ERROR)
544 {
545 err = WSAGetLastError();
546
547 /* If connect failed with EWOULDBLOCK and the GSocket object
548 * is in blocking mode, we select() for the specified timeout
549 * checking for writability to see if the connection request
550 * completes.
551 */
552 if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking))
553 {
554 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
555 {
556 closesocket(sck->m_fd);
557 sck->m_fd = INVALID_SOCKET;
558 /* sck->m_error is set in _GSocket_Output_Timeout */
559 return GSOCK_TIMEDOUT;
560 }
561 else
562 return GSOCK_NOERROR;
563 }
564
565 /* If connect failed with EWOULDBLOCK and the GSocket object
566 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
567 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
568 * this way if the connection completes, a GSOCK_CONNECTION
569 * event will be generated, if enabled.
570 */
571 if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking))
572 {
573 sck->m_error = GSOCK_WOULDBLOCK;
574 return GSOCK_WOULDBLOCK;
575 }
576
577 /* If connect failed with an error other than EWOULDBLOCK,
578 * then the call to GSocket_Connect has failed.
579 */
580 closesocket(sck->m_fd);
581 sck->m_fd = INVALID_SOCKET;
582 sck->m_error = GSOCK_IOERR;
583 return GSOCK_IOERR;
584 }
585
586 return GSOCK_NOERROR;
587 }
588
589 /* Generic IO */
590
591 /* Like recv(), send(), ... */
592 int GSocket_Read(GSocket *socket, char *buffer, int size)
593 {
594 assert(socket != NULL);
595
596 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
597 {
598 socket->m_error = GSOCK_INVSOCK;
599 return -1;
600 }
601
602 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
603 return -1;
604
605 if (socket->m_stream)
606 return _GSocket_Recv_Stream(socket, buffer, size);
607 else
608 return _GSocket_Recv_Dgram(socket, buffer, size);
609 }
610
611 int GSocket_Write(GSocket *socket, const char *buffer, int size)
612 {
613 assert(socket != NULL);
614
615 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
616 {
617 socket->m_error = GSOCK_INVSOCK;
618 return -1;
619 }
620
621 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
622 return -1;
623
624 if (socket->m_stream)
625 return _GSocket_Send_Stream(socket, buffer, size);
626 else
627 return _GSocket_Send_Dgram(socket, buffer, size);
628 }
629
630 bool GSocket_DataAvailable(GSocket *socket)
631 {
632 fd_set read_set;
633 struct timeval tv;
634
635 assert(socket != NULL);
636
637 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
638 {
639 socket->m_error = GSOCK_INVSOCK;
640 return FALSE;
641 }
642
643 FD_ZERO(&read_set);
644 FD_SET(socket->m_fd, &read_set);
645
646 tv.tv_sec = 0;
647 tv.tv_usec = 0;
648
649 select(socket->m_fd + 1, &read_set, NULL, NULL, &tv);
650
651 return FD_ISSET(socket->m_fd, &read_set);
652 }
653
654 /* Flags */
655
656 /* GSocket_SetNonBlocking:
657 * Sets the socket in non-blocking mode. This is useful if
658 * we don't want to wait.
659 */
660 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
661 {
662 assert(socket != NULL);
663
664 socket->m_non_blocking = non_block;
665 }
666
667 /* GSocket_SetTimeout:
668 */
669 void GSocket_SetTimeout(GSocket *socket, unsigned long millisecs)
670 {
671 assert(socket != NULL);
672
673 socket->m_timeout.tv_sec = (millisecs / 1000);
674 socket->m_timeout.tv_usec = (millisecs % 1000) * 1000;
675 }
676
677 /* GSocket_GetError:
678 * Returns the last error occured for this socket.
679 */
680 GSocketError GSocket_GetError(GSocket *socket)
681 {
682 assert(socket != NULL);
683
684 return socket->m_error;
685 }
686
687 /* Callbacks */
688
689 /* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
690 * and LOST). The callbacks are called in the following situations:
691 *
692 * INPUT: There is at least one byte in the input buffer
693 * OUTPUT: The system is sure that the next write call will not block
694 * CONNECTION: Two cases are possible:
695 * Client socket -> the connection is established
696 * Server socket -> a client requests a connection
697 * LOST: The connection is lost
698 *
699 * An event is generated only once and its state is reseted when the
700 * relative IO call is requested.
701 * For example: INPUT -> GSocket_Read()
702 * CONNECTION -> GSocket_Accept()
703 */
704
705 /* GSocket_SetCallback:
706 * Enables the callbacks specified by 'event'. Note that 'event'
707 * may be a combination of flags OR'ed toghether, so the same
708 * callback function can be made to accept different events.
709 * The callback function must have the following prototype:
710 *
711 * void function(GSocket *socket, GSocketEvent event, char *cdata)
712 */
713 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
714 GSocketCallback callback, char *cdata)
715 {
716 int count;
717
718 assert (socket != NULL);
719
720 for (count = 0; count < GSOCK_MAX_EVENT; count++)
721 {
722 /* We test each flag and enable the corresponding events */
723 if ((event & (1 << count)) != 0)
724 {
725 socket->m_cbacks[count] = callback;
726 socket->m_data[count] = cdata;
727 }
728 }
729
730 _GSocket_Configure_Callbacks(socket);
731 }
732
733 /* GSocket_UnsetCallback:
734 * Disables all callbacks specified by 'event', which may be a
735 * combination of flags OR'ed toghether.
736 */
737 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
738 {
739 int count = 0;
740
741 assert(socket != NULL);
742
743 for (count = 0; count < GSOCK_MAX_EVENT; count++)
744 {
745 /* We test each flag and disable the corresponding events */
746 if ((event & (1 << count)) != 0)
747 {
748 socket->m_cbacks[count] = NULL;
749 }
750 }
751
752 _GSocket_Configure_Callbacks(socket);
753 }
754
755
756 /* Internals */
757
758 void _GSocket_Configure_Callbacks(GSocket *socket)
759 {
760 long mask = 0;
761 int count;
762
763 for (count = 0; count < GSOCK_MAX_EVENT; count++)
764 {
765 if (socket->m_cbacks[count] != NULL)
766 {
767 switch (count)
768 {
769 case GSOCK_INPUT: mask |= FD_READ; break;
770 case GSOCK_OUTPUT: mask |= FD_WRITE; break;
771 case GSOCK_CONNECTION: mask |= (FD_ACCEPT | FD_CONNECT); break;
772 case GSOCK_LOST: mask |= FD_CLOSE; break;
773 }
774 }
775 }
776
777 WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, mask);
778 }
779
780 LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd,
781 UINT uMsg,
782 WPARAM wParam,
783 LPARAM lParam)
784 {
785 GSocket *socket;
786 GSocketEvent event;
787 GSocketCallback cback;
788
789 if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1))
790 {
791 EnterCriticalSection(&critical);
792 socket = socketList[(uMsg - WM_USER)];
793 event = -1;
794 cback = NULL;
795
796 /* Check that the socket still exists (it has not been
797 * destroyed) and for safety, check that the m_fd field
798 * is what we expect it to be.
799 */
800 if ((socket != NULL) && (socket->m_fd == wParam))
801 {
802 switch WSAGETSELECTEVENT(lParam)
803 {
804 case FD_READ: event = GSOCK_INPUT; break;
805 case FD_WRITE: event = GSOCK_OUTPUT; break;
806 case FD_ACCEPT: event = GSOCK_CONNECTION; break;
807 case FD_CONNECT:
808 {
809 if (WSAGETSELECTERROR(lParam) != 0)
810 event = GSOCK_LOST;
811 else
812 event = GSOCK_CONNECTION;
813 break;
814 }
815 case FD_CLOSE: event = GSOCK_LOST; break;
816 }
817
818 if (event != -1)
819 cback = socket->m_cbacks[event];
820 }
821
822 /* OK, we can now leave the critical section because we have
823 * already obtained the callback address (we make no further
824 * accesses to socket->whatever)
825 */
826 LeaveCriticalSection(&critical);
827
828 if (cback != NULL)
829 (cback)(socket, event, socket->m_data[event]);
830
831 return (LRESULT) 0;
832 }
833 else
834 return DefWindowProc(hWnd, uMsg, wParam, lParam);
835 }
836
837
838 /* _GSocket_Input_Timeout:
839 * For blocking sockets, wait until data is available or
840 * until timeout ellapses.
841 */
842 GSocketError _GSocket_Input_Timeout(GSocket *socket)
843 {
844 fd_set readfds;
845
846 if (!socket->m_non_blocking)
847 {
848 FD_ZERO(&readfds);
849 FD_SET(socket->m_fd, &readfds);
850 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
851 {
852 socket->m_error = GSOCK_TIMEDOUT;
853 return GSOCK_TIMEDOUT;
854 }
855 }
856 return GSOCK_NOERROR;
857 }
858
859 /* _GSocket_Output_Timeout:
860 * For blocking sockets, wait until data can be sent without
861 * blocking or until timeout ellapses.
862 */
863 GSocketError _GSocket_Output_Timeout(GSocket *socket)
864 {
865 fd_set writefds;
866
867 if (!socket->m_non_blocking)
868 {
869 FD_ZERO(&writefds);
870 FD_SET(socket->m_fd, &writefds);
871 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
872 {
873 socket->m_error = GSOCK_TIMEDOUT;
874 return GSOCK_TIMEDOUT;
875 }
876 }
877 return GSOCK_NOERROR;
878 }
879
880 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
881 {
882 int ret;
883
884 ret = recv(socket->m_fd, buffer, size, 0);
885
886 if (ret == SOCKET_ERROR)
887 {
888 if (WSAGetLastError() != WSAEWOULDBLOCK)
889 socket->m_error = GSOCK_IOERR;
890 else
891 socket->m_error = GSOCK_WOULDBLOCK;
892
893 return -1;
894 }
895
896 return ret;
897 }
898
899 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
900 {
901 struct sockaddr from;
902 SOCKLEN_T fromlen;
903 int ret;
904
905 fromlen = sizeof(from);
906
907 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
908
909 if (ret == SOCKET_ERROR)
910 {
911 if (WSAGetLastError() != WSAEWOULDBLOCK)
912 socket->m_error = GSOCK_IOERR;
913 else
914 socket->m_error = GSOCK_WOULDBLOCK;
915
916 return -1;
917 }
918
919 /* Translate a system address into a GSocket address */
920 if (!socket->m_peer)
921 {
922 socket->m_peer = GAddress_new();
923 if (!socket->m_peer)
924 {
925 socket->m_error = GSOCK_MEMERR;
926 return -1;
927 }
928 }
929 if (_GAddress_translate_from(socket->m_peer, &from, fromlen) != GSOCK_NOERROR)
930 {
931 socket->m_error = GSOCK_MEMERR;
932 GAddress_destroy(socket->m_peer);
933 return -1;
934 }
935
936 return ret;
937 }
938
939 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
940 {
941 int ret;
942
943 ret = send(socket->m_fd, buffer, size, 0);
944
945 if (ret == SOCKET_ERROR)
946 {
947 if (WSAGetLastError() != WSAEWOULDBLOCK)
948 socket->m_error = GSOCK_IOERR;
949 else
950 socket->m_error = GSOCK_WOULDBLOCK;
951
952 return -1;
953 }
954 return ret;
955 }
956
957 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
958 {
959 struct sockaddr *addr;
960 int len, ret;
961
962 if (!socket->m_peer)
963 {
964 socket->m_error = GSOCK_INVADDR;
965 return -1;
966 }
967
968 if (!_GAddress_translate_to(socket->m_peer, &addr, &len))
969 {
970 socket->m_error = GSOCK_MEMERR;
971 return -1;
972 }
973
974 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
975
976 /* Frees memory allocated by _GAddress_translate_to */
977 free(addr);
978
979 if (ret == SOCKET_ERROR)
980 {
981 if (WSAGetLastError() != WSAEWOULDBLOCK)
982 socket->m_error = GSOCK_IOERR;
983 else
984 socket->m_error = GSOCK_WOULDBLOCK;
985
986 return -1;
987 }
988 return ret;
989 }
990
991
992 /*
993 * -------------------------------------------------------------------------
994 * GAddress
995 * -------------------------------------------------------------------------
996 */
997
998 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
999 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
1000 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
1001 */
1002 #define CHECK_ADDRESS(address, family, retval) \
1003 { \
1004 if (address->m_family == GSOCK_NOFAMILY) \
1005 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1006 return address->m_error; \
1007 if (address->m_family != GSOCK_##family) \
1008 { \
1009 address->m_error = GSOCK_INVADDR; \
1010 return retval; \
1011 } \
1012 }
1013
1014 GAddress *GAddress_new()
1015 {
1016 GAddress *address;
1017
1018 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1019 return NULL;
1020
1021 address->m_family = GSOCK_NOFAMILY;
1022 address->m_addr = NULL;
1023 address->m_len = 0;
1024
1025 return address;
1026 }
1027
1028 GAddress *GAddress_copy(GAddress *address)
1029 {
1030 GAddress *addr2;
1031
1032 assert(address != NULL);
1033
1034 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1035 return NULL;
1036
1037 memcpy(addr2, address, sizeof(GAddress));
1038
1039 if (address->m_addr)
1040 {
1041 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1042 if (addr2->m_addr == NULL)
1043 {
1044 free(addr2);
1045 return NULL;
1046 }
1047 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1048 }
1049
1050 return addr2;
1051 }
1052
1053 void GAddress_destroy(GAddress *address)
1054 {
1055 assert(address != NULL);
1056
1057 free(address);
1058 }
1059
1060 void GAddress_SetFamily(GAddress *address, GAddressType type)
1061 {
1062 assert(address != NULL);
1063
1064 address->m_family = type;
1065 }
1066
1067 GAddressType GAddress_GetFamily(GAddress *address)
1068 {
1069 assert(address != NULL);
1070
1071 return address->m_family;
1072 }
1073
1074 GSocketError _GAddress_translate_from(GAddress *address,
1075 struct sockaddr *addr, int len)
1076 {
1077 address->m_realfamily = addr->sa_family;
1078 switch (addr->sa_family)
1079 {
1080 case AF_INET:
1081 address->m_family = GSOCK_INET;
1082 break;
1083 case AF_UNIX:
1084 address->m_family = GSOCK_UNIX;
1085 break;
1086 #ifdef AF_INET6
1087 case AF_INET6:
1088 address->m_family = GSOCK_INET6;
1089 break;
1090 #endif
1091 default:
1092 {
1093 address->m_error = GSOCK_INVOP;
1094 return GSOCK_INVOP;
1095 }
1096 }
1097
1098 if (address->m_addr)
1099 free(address->m_addr);
1100
1101 address->m_len = len;
1102 address->m_addr = (struct sockaddr *) malloc(len);
1103
1104 if (address->m_addr == NULL)
1105 {
1106 address->m_error = GSOCK_MEMERR;
1107 return GSOCK_MEMERR;
1108 }
1109 memcpy(address->m_addr, addr, len);
1110
1111 return GSOCK_NOERROR;
1112 }
1113
1114 GSocketError _GAddress_translate_to(GAddress *address,
1115 struct sockaddr **addr, int *len)
1116 {
1117 if (!address->m_addr)
1118 {
1119 address->m_error = GSOCK_INVADDR;
1120 return GSOCK_INVADDR;
1121 }
1122
1123 *len = address->m_len;
1124 *addr = (struct sockaddr *) malloc(address->m_len);
1125 if (*addr == NULL)
1126 {
1127 address->m_error = GSOCK_MEMERR;
1128 return GSOCK_MEMERR;
1129 }
1130
1131 memcpy(*addr, address->m_addr, address->m_len);
1132 return GSOCK_NOERROR;
1133 }
1134
1135 /*
1136 * -------------------------------------------------------------------------
1137 * Internet address family
1138 * -------------------------------------------------------------------------
1139 */
1140
1141 GSocketError _GAddress_Init_INET(GAddress *address)
1142 {
1143 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1144 if (address->m_addr == NULL)
1145 {
1146 address->m_error = GSOCK_MEMERR;
1147 return GSOCK_MEMERR;
1148 }
1149
1150 address->m_len = sizeof(struct sockaddr_in);
1151 address->m_family = GSOCK_INET;
1152 address->m_realfamily = PF_INET;
1153 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1154 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1155
1156 return GSOCK_NOERROR;
1157 }
1158
1159 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1160 {
1161 struct hostent *he;
1162 struct in_addr *addr;
1163
1164 assert(address != NULL);
1165
1166 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1167
1168 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1169
1170 addr->s_addr = inet_addr(hostname);
1171
1172 /* If it is a numeric host name, convert it now */
1173 if (addr->s_addr == INADDR_NONE)
1174 {
1175 struct in_addr *array_addr;
1176
1177 /* It is a real name, we solve it */
1178 if ((he = gethostbyname(hostname)) == NULL)
1179 {
1180 address->m_error = GSOCK_NOHOST;
1181 return GSOCK_NOHOST;
1182 }
1183 array_addr = (struct in_addr *) *(he->h_addr_list);
1184 addr->s_addr = array_addr[0].s_addr;
1185 }
1186 return GSOCK_NOERROR;
1187 }
1188
1189 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1190 unsigned long hostaddr)
1191 {
1192 struct in_addr *addr;
1193
1194 assert(address != NULL);
1195
1196 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1197
1198 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1199 addr->s_addr = hostaddr;
1200
1201 return GSOCK_NOERROR;
1202 }
1203
1204 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1205 const char *protocol)
1206 {
1207 struct servent *se;
1208 struct sockaddr_in *addr;
1209
1210 assert(address != NULL);
1211 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1212
1213 if (!port)
1214 {
1215 address->m_error = GSOCK_INVPORT;
1216 return GSOCK_INVOP;
1217 }
1218
1219 se = getservbyname(port, protocol);
1220 if (!se)
1221 {
1222 if (isdigit(port[0]))
1223 {
1224 int port_int;
1225
1226 port_int = atoi(port);
1227 addr = (struct sockaddr_in *)address->m_addr;
1228 addr->sin_port = htons((u_short) port_int);
1229 return GSOCK_NOERROR;
1230 }
1231
1232 address->m_error = GSOCK_INVPORT;
1233 return GSOCK_INVPORT;
1234 }
1235
1236 addr = (struct sockaddr_in *)address->m_addr;
1237 addr->sin_port = se->s_port;
1238
1239 return GSOCK_NOERROR;
1240 }
1241
1242 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1243 {
1244 struct sockaddr_in *addr;
1245
1246 assert(address != NULL);
1247 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1248
1249 addr = (struct sockaddr_in *)address->m_addr;
1250 addr->sin_port = htons(port);
1251
1252 return GSOCK_NOERROR;
1253 }
1254
1255 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1256 {
1257 struct hostent *he;
1258 char *addr_buf;
1259 struct sockaddr_in *addr;
1260
1261 assert(address != NULL);
1262 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1263
1264 addr = (struct sockaddr_in *)address->m_addr;
1265 addr_buf = (char *)&(addr->sin_addr);
1266
1267 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1268 if (he == NULL)
1269 {
1270 address->m_error = GSOCK_NOHOST;
1271 return GSOCK_NOHOST;
1272 }
1273
1274 strncpy(hostname, he->h_name, sbuf);
1275
1276 return GSOCK_NOERROR;
1277 }
1278
1279 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1280 {
1281 struct sockaddr_in *addr;
1282
1283 assert(address != NULL);
1284 CHECK_ADDRESS(address, INET, 0);
1285
1286 addr = (struct sockaddr_in *)address->m_addr;
1287
1288 return addr->sin_addr.s_addr;
1289 }
1290
1291 unsigned short GAddress_INET_GetPort(GAddress *address)
1292 {
1293 struct sockaddr_in *addr;
1294
1295 assert(address != NULL);
1296 CHECK_ADDRESS(address, INET, 0);
1297
1298 addr = (struct sockaddr_in *)address->m_addr;
1299 return ntohs(addr->sin_port);
1300 }
1301
1302 /*
1303 * -------------------------------------------------------------------------
1304 * Unix address family
1305 * -------------------------------------------------------------------------
1306 */
1307
1308 GSocketError _GAddress_Init_UNIX(GAddress *address)
1309 {
1310 assert (address != NULL);
1311 address->m_error = GSOCK_INVADDR;
1312 return GSOCK_INVADDR;
1313 }
1314
1315 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1316 {
1317 assert (address != NULL);
1318 address->m_error = GSOCK_INVADDR;
1319 return GSOCK_INVADDR;
1320 }
1321
1322 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1323 {
1324 assert (address != NULL);
1325 address->m_error = GSOCK_INVADDR;
1326 return GSOCK_INVADDR;
1327 }
1328
1329
1330 #endif /* !defined(__WXMSW__) || (defined(__WXMSW__) && wxUSE_SOCKETS) */
1331
1332
1333
1334 /* Diferencias con la version Unix:
1335 * - El descriptor es SOCKET y no int
1336 * - Constantes -1 pasan a INVALID_SOCKET
1337 * - Errores en muchas funciones pasan de -1 o <0 a SOCKET_ERROR
1338 * - ioctl y close pasan a ioctlsocket y closesocket
1339 * - inet_addr en lugar de inet_aton
1340 * - Codigo de inicializacion y terminacion para inicializar y
1341 * terminar WinSocket y para la ventana interna.
1342 * - SetTimeout en la version MSW simplemente guarda el valor en
1343 * socket.m_timeout, por tanto no hay necesidad de llamar a
1344 * SetTimeout cada vez que se crea realmente un socket (no
1345 * un gsocket).
1346 * - Lo mismo para SetNonBlocking.
1347 */