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