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