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