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