]> git.saurik.com Git - wxWidgets.git/blob - src/msw/gsocket.c
strange comment in gsocket_read (?)
[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 writable.
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 * XXX - this comment seems not to belong here, and also
666 * the code is not consistent with the unix version of
667 * gsocket... what to do? (GRG)
668 */
669 if (WSAGetLastError() != WSAEWOULDBLOCK)
670 {
671 socket->m_error = GSOCK_IOERR;
672 return -1;
673 }
674 else
675 {
676 socket->m_error = GSOCK_WOULDBLOCK;
677 return 0;
678 }
679 }
680
681 return ret;
682 }
683
684 int GSocket_Write(GSocket *socket, const char *buffer, int size)
685 {
686 int ret;
687
688 assert(socket != NULL);
689
690 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
691 {
692 socket->m_error = GSOCK_INVSOCK;
693 return -1;
694 }
695
696 /* If the socket is blocking, wait for writability (with a timeout) */
697 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
698 return -1;
699
700 /* Read the data */
701 if (socket->m_stream)
702 ret = _GSocket_Send_Stream(socket, buffer, size);
703 else
704 ret = _GSocket_Send_Dgram(socket, buffer, size);
705
706 if (ret == SOCKET_ERROR)
707 {
708 if (WSAGetLastError() != WSAEWOULDBLOCK)
709 socket->m_error = GSOCK_IOERR;
710 else
711 socket->m_error = GSOCK_WOULDBLOCK;
712
713 socket->m_detected &= ~GSOCK_OUTPUT_FLAG;
714 return -1;
715 }
716
717 return ret;
718 }
719
720 /* GSocket_Select:
721 * Polls the socket to determine its status. This function will
722 * check for the events specified in the 'flags' parameter, and
723 * it will return a mask indicating which operations can be
724 * performed. This function won't block, regardless of the
725 * mode (blocking|nonblocking) of the socket.
726 */
727 GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
728 {
729 assert(socket != NULL);
730
731 return (flags & socket->m_detected);
732 }
733
734 /* Flags */
735
736 /* GSocket_SetNonBlocking:
737 * Sets the socket to non-blocking mode. This is useful if
738 * we don't want to wait.
739 */
740 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
741 {
742 assert(socket != NULL);
743
744 socket->m_non_blocking = non_block;
745 }
746
747 /* GSocket_SetTimeout:
748 * Sets the timeout for blocking calls. Time is
749 * expressed in milliseconds.
750 */
751 void GSocket_SetTimeout(GSocket *socket, unsigned long millis)
752 {
753 assert(socket != NULL);
754
755 socket->m_timeout.tv_sec = (millis / 1000);
756 socket->m_timeout.tv_usec = (millis % 1000) * 1000;
757 }
758
759 /* GSocket_GetError:
760 * Returns the last error occured for this socket.
761 */
762 GSocketError GSocket_GetError(GSocket *socket)
763 {
764 assert(socket != NULL);
765
766 return socket->m_error;
767 }
768
769 /* Callbacks */
770
771 /* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
772 * and LOST). The callbacks are called in the following situations:
773 *
774 * INPUT: There is at least one byte in the input buffer
775 * OUTPUT: The system is sure that the next write call will not block
776 * CONNECTION: Two cases are possible:
777 * Client socket -> the connection is established
778 * Server socket -> a client requests a connection
779 * LOST: The connection is lost
780 *
781 * An event is generated only once and its state is reseted when the
782 * relative IO call is requested.
783 * For example: INPUT -> GSocket_Read()
784 * CONNECTION -> GSocket_Accept()
785 */
786
787 /* GSocket_SetCallback:
788 * Enables the callbacks specified by 'flags'. Note that 'flags'
789 * may be a combination of flags OR'ed toghether, so the same
790 * callback function can be made to accept different events.
791 * The callback function must have the following prototype:
792 *
793 * void function(GSocket *socket, GSocketEvent event, char *cdata)
794 */
795 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
796 GSocketCallback callback, char *cdata)
797 {
798 int count;
799
800 assert (socket != NULL);
801
802 for (count = 0; count < GSOCK_MAX_EVENT; count++)
803 {
804 if ((flags & (1 << count)) != 0)
805 {
806 socket->m_cbacks[count] = callback;
807 socket->m_data[count] = cdata;
808 }
809 }
810 }
811
812 /* GSocket_UnsetCallback:
813 * Disables all callbacks specified by 'flags', which may be a
814 * combination of flags OR'ed toghether.
815 */
816 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
817 {
818 int count = 0;
819
820 assert(socket != NULL);
821
822 for (count = 0; count < GSOCK_MAX_EVENT; count++)
823 {
824 if ((flags & (1 << count)) != 0)
825 {
826 socket->m_cbacks[count] = NULL;
827 socket->m_data[count] = NULL;
828 }
829 }
830 }
831
832
833 /* Internals */
834
835 /* _GSocket_Enable_Events:
836 * We enable all event notifications here (we need to be notified
837 * of all events for internal processing) but we will only notify
838 * users when an appropiate callback function has been installed.
839 */
840 void _GSocket_Enable_Events(GSocket *socket)
841 {
842 assert (socket != NULL);
843
844 if (socket->m_fd != INVALID_SOCKET)
845 {
846 WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber,
847 FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
848 }
849 }
850
851 /* _GSocket_Disable_Events:
852 * Disable event notifications (when shutdowning the socket)
853 */
854 void _GSocket_Disable_Events(GSocket *socket)
855 {
856 assert (socket != NULL);
857
858 if (socket->m_fd != INVALID_SOCKET)
859 {
860 WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
861 }
862 }
863
864
865 LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd,
866 UINT uMsg,
867 WPARAM wParam,
868 LPARAM lParam)
869 {
870 GSocket *socket;
871 GSocketEvent event;
872 GSocketCallback cback;
873 char *data;
874
875 if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1))
876 {
877 EnterCriticalSection(&critical);
878 socket = socketList[(uMsg - WM_USER)];
879 event = -1;
880 cback = NULL;
881 data = NULL;
882
883 /* Check that the socket still exists (it has not been
884 * destroyed) and for safety, check that the m_fd field
885 * is what we expect it to be.
886 */
887 if ((socket != NULL) && (socket->m_fd == wParam))
888 {
889 switch WSAGETSELECTEVENT(lParam)
890 {
891 case FD_READ: event = GSOCK_INPUT; break;
892 case FD_WRITE: event = GSOCK_OUTPUT; break;
893 case FD_ACCEPT: event = GSOCK_CONNECTION; break;
894 case FD_CONNECT:
895 {
896 if (WSAGETSELECTERROR(lParam) != 0)
897 event = GSOCK_LOST;
898 else
899 event = GSOCK_CONNECTION;
900 break;
901 }
902 case FD_CLOSE: event = GSOCK_LOST; break;
903 }
904
905 if (event != -1)
906 {
907 cback = socket->m_cbacks[event];
908 data = socket->m_data[event];
909
910 if (event == GSOCK_LOST)
911 socket->m_detected = GSOCK_LOST_FLAG;
912 else
913 socket->m_detected |= (1 << event);
914 }
915 }
916
917 /* OK, we can now leave the critical section because we have
918 * already obtained the callback address (we make no further
919 * accesses to socket->whatever)
920 */
921 LeaveCriticalSection(&critical);
922
923 if (cback != NULL)
924 (cback)(socket, event, data);
925
926 return (LRESULT) 0;
927 }
928 else
929 return DefWindowProc(hWnd, uMsg, wParam, lParam);
930 }
931
932
933 /* _GSocket_Input_Timeout:
934 * For blocking sockets, wait until data is available or
935 * until timeout ellapses.
936 */
937 GSocketError _GSocket_Input_Timeout(GSocket *socket)
938 {
939 fd_set readfds;
940
941 if (!socket->m_non_blocking)
942 {
943 FD_ZERO(&readfds);
944 FD_SET(socket->m_fd, &readfds);
945 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
946 {
947 socket->m_error = GSOCK_TIMEDOUT;
948 return GSOCK_TIMEDOUT;
949 }
950 }
951 return GSOCK_NOERROR;
952 }
953
954 /* _GSocket_Output_Timeout:
955 * For blocking sockets, wait until data can be sent without
956 * blocking or until timeout ellapses.
957 */
958 GSocketError _GSocket_Output_Timeout(GSocket *socket)
959 {
960 fd_set writefds;
961
962 if (!socket->m_non_blocking)
963 {
964 FD_ZERO(&writefds);
965 FD_SET(socket->m_fd, &writefds);
966 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
967 {
968 socket->m_error = GSOCK_TIMEDOUT;
969 return GSOCK_TIMEDOUT;
970 }
971 }
972 return GSOCK_NOERROR;
973 }
974
975 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
976 {
977 return recv(socket->m_fd, buffer, size, 0);
978 }
979
980 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
981 {
982 struct sockaddr from;
983 SOCKLEN_T fromlen = sizeof(from);
984 int ret;
985 GSocketError err;
986
987 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
988
989 if (ret == SOCKET_ERROR)
990 return SOCKET_ERROR;
991
992 /* Translate a system address into a GSocket address */
993 if (!socket->m_peer)
994 {
995 socket->m_peer = GAddress_new();
996 if (!socket->m_peer)
997 {
998 socket->m_error = GSOCK_MEMERR;
999 return -1;
1000 }
1001 }
1002 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
1003 if (err != GSOCK_NOERROR)
1004 {
1005 GAddress_destroy(socket->m_peer);
1006 socket->m_peer = NULL;
1007 socket->m_error = err;
1008 return -1;
1009 }
1010
1011 return ret;
1012 }
1013
1014 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
1015 {
1016 return send(socket->m_fd, buffer, size, 0);
1017 }
1018
1019 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
1020 {
1021 struct sockaddr *addr;
1022 int len, ret;
1023 GSocketError err;
1024
1025 if (!socket->m_peer)
1026 {
1027 socket->m_error = GSOCK_INVADDR;
1028 return -1;
1029 }
1030
1031 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
1032 if (err != GSOCK_NOERROR)
1033 {
1034 socket->m_error = err;
1035 return -1;
1036 }
1037
1038 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1039
1040 /* Frees memory allocated by _GAddress_translate_to */
1041 free(addr);
1042
1043 return ret;
1044 }
1045
1046
1047 /*
1048 * -------------------------------------------------------------------------
1049 * GAddress
1050 * -------------------------------------------------------------------------
1051 */
1052
1053 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
1054 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
1055 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
1056 */
1057 #define CHECK_ADDRESS(address, family, retval) \
1058 { \
1059 if (address->m_family == GSOCK_NOFAMILY) \
1060 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1061 return address->m_error; \
1062 if (address->m_family != GSOCK_##family) \
1063 { \
1064 address->m_error = GSOCK_INVADDR; \
1065 return retval; \
1066 } \
1067 }
1068
1069 GAddress *GAddress_new()
1070 {
1071 GAddress *address;
1072
1073 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1074 return NULL;
1075
1076 address->m_family = GSOCK_NOFAMILY;
1077 address->m_addr = NULL;
1078 address->m_len = 0;
1079
1080 return address;
1081 }
1082
1083 GAddress *GAddress_copy(GAddress *address)
1084 {
1085 GAddress *addr2;
1086
1087 assert(address != NULL);
1088
1089 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1090 return NULL;
1091
1092 memcpy(addr2, address, sizeof(GAddress));
1093
1094 if (address->m_addr)
1095 {
1096 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1097 if (addr2->m_addr == NULL)
1098 {
1099 free(addr2);
1100 return NULL;
1101 }
1102 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1103 }
1104
1105 return addr2;
1106 }
1107
1108 void GAddress_destroy(GAddress *address)
1109 {
1110 assert(address != NULL);
1111
1112 free(address);
1113 }
1114
1115 void GAddress_SetFamily(GAddress *address, GAddressType type)
1116 {
1117 assert(address != NULL);
1118
1119 address->m_family = type;
1120 }
1121
1122 GAddressType GAddress_GetFamily(GAddress *address)
1123 {
1124 assert(address != NULL);
1125
1126 return address->m_family;
1127 }
1128
1129 GSocketError _GAddress_translate_from(GAddress *address,
1130 struct sockaddr *addr, int len)
1131 {
1132 address->m_realfamily = addr->sa_family;
1133 switch (addr->sa_family)
1134 {
1135 case AF_INET:
1136 address->m_family = GSOCK_INET;
1137 break;
1138 case AF_UNIX:
1139 address->m_family = GSOCK_UNIX;
1140 break;
1141 #ifdef AF_INET6
1142 case AF_INET6:
1143 address->m_family = GSOCK_INET6;
1144 break;
1145 #endif
1146 default:
1147 {
1148 address->m_error = GSOCK_INVOP;
1149 return GSOCK_INVOP;
1150 }
1151 }
1152
1153 if (address->m_addr)
1154 free(address->m_addr);
1155
1156 address->m_len = len;
1157 address->m_addr = (struct sockaddr *) malloc(len);
1158
1159 if (address->m_addr == NULL)
1160 {
1161 address->m_error = GSOCK_MEMERR;
1162 return GSOCK_MEMERR;
1163 }
1164 memcpy(address->m_addr, addr, len);
1165
1166 return GSOCK_NOERROR;
1167 }
1168
1169 GSocketError _GAddress_translate_to(GAddress *address,
1170 struct sockaddr **addr, int *len)
1171 {
1172 if (!address->m_addr)
1173 {
1174 address->m_error = GSOCK_INVADDR;
1175 return GSOCK_INVADDR;
1176 }
1177
1178 *len = address->m_len;
1179 *addr = (struct sockaddr *) malloc(address->m_len);
1180 if (*addr == NULL)
1181 {
1182 address->m_error = GSOCK_MEMERR;
1183 return GSOCK_MEMERR;
1184 }
1185
1186 memcpy(*addr, address->m_addr, address->m_len);
1187 return GSOCK_NOERROR;
1188 }
1189
1190 /*
1191 * -------------------------------------------------------------------------
1192 * Internet address family
1193 * -------------------------------------------------------------------------
1194 */
1195
1196 GSocketError _GAddress_Init_INET(GAddress *address)
1197 {
1198 address->m_len = sizeof(struct sockaddr_in);
1199 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1200 if (address->m_addr == NULL)
1201 {
1202 address->m_error = GSOCK_MEMERR;
1203 return GSOCK_MEMERR;
1204 }
1205
1206 address->m_family = GSOCK_INET;
1207 address->m_realfamily = PF_INET;
1208 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1209 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_NONE;
1210
1211 return GSOCK_NOERROR;
1212 }
1213
1214 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1215 {
1216 struct hostent *he;
1217 struct in_addr *addr;
1218
1219 assert(address != NULL);
1220
1221 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1222
1223 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1224
1225 addr->s_addr = inet_addr(hostname);
1226
1227 /* If it is a numeric host name, convert it now */
1228 if (addr->s_addr == INADDR_NONE)
1229 {
1230 struct in_addr *array_addr;
1231
1232 /* It is a real name, we solve it */
1233 if ((he = gethostbyname(hostname)) == NULL)
1234 {
1235 address->m_error = GSOCK_NOHOST;
1236 return GSOCK_NOHOST;
1237 }
1238 array_addr = (struct in_addr *) *(he->h_addr_list);
1239 addr->s_addr = array_addr[0].s_addr;
1240 }
1241 return GSOCK_NOERROR;
1242 }
1243
1244 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1245 unsigned long hostaddr)
1246 {
1247 struct in_addr *addr;
1248
1249 assert(address != NULL);
1250
1251 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1252
1253 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1254 addr->s_addr = hostaddr;
1255
1256 return GSOCK_NOERROR;
1257 }
1258
1259 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1260 const char *protocol)
1261 {
1262 struct servent *se;
1263 struct sockaddr_in *addr;
1264
1265 assert(address != NULL);
1266 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1267
1268 if (!port)
1269 {
1270 address->m_error = GSOCK_INVPORT;
1271 return GSOCK_INVOP;
1272 }
1273
1274 se = getservbyname(port, protocol);
1275 if (!se)
1276 {
1277 if (isdigit(port[0]))
1278 {
1279 int port_int;
1280
1281 port_int = atoi(port);
1282 addr = (struct sockaddr_in *)address->m_addr;
1283 addr->sin_port = htons((u_short) port_int);
1284 return GSOCK_NOERROR;
1285 }
1286
1287 address->m_error = GSOCK_INVPORT;
1288 return GSOCK_INVPORT;
1289 }
1290
1291 addr = (struct sockaddr_in *)address->m_addr;
1292 addr->sin_port = se->s_port;
1293
1294 return GSOCK_NOERROR;
1295 }
1296
1297 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1298 {
1299 struct sockaddr_in *addr;
1300
1301 assert(address != NULL);
1302 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1303
1304 addr = (struct sockaddr_in *)address->m_addr;
1305 addr->sin_port = htons(port);
1306
1307 return GSOCK_NOERROR;
1308 }
1309
1310 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1311 {
1312 struct hostent *he;
1313 char *addr_buf;
1314 struct sockaddr_in *addr;
1315
1316 assert(address != NULL);
1317 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1318
1319 addr = (struct sockaddr_in *)address->m_addr;
1320 addr_buf = (char *)&(addr->sin_addr);
1321
1322 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1323 if (he == NULL)
1324 {
1325 address->m_error = GSOCK_NOHOST;
1326 return GSOCK_NOHOST;
1327 }
1328
1329 strncpy(hostname, he->h_name, sbuf);
1330
1331 return GSOCK_NOERROR;
1332 }
1333
1334 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1335 {
1336 struct sockaddr_in *addr;
1337
1338 assert(address != NULL);
1339 CHECK_ADDRESS(address, INET, 0);
1340
1341 addr = (struct sockaddr_in *)address->m_addr;
1342
1343 return addr->sin_addr.s_addr;
1344 }
1345
1346 unsigned short GAddress_INET_GetPort(GAddress *address)
1347 {
1348 struct sockaddr_in *addr;
1349
1350 assert(address != NULL);
1351 CHECK_ADDRESS(address, INET, 0);
1352
1353 addr = (struct sockaddr_in *)address->m_addr;
1354 return ntohs(addr->sin_port);
1355 }
1356
1357 /*
1358 * -------------------------------------------------------------------------
1359 * Unix address family
1360 * -------------------------------------------------------------------------
1361 */
1362
1363 GSocketError _GAddress_Init_UNIX(GAddress *address)
1364 {
1365 assert (address != NULL);
1366 address->m_error = GSOCK_INVADDR;
1367 return GSOCK_INVADDR;
1368 }
1369
1370 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1371 {
1372 assert (address != NULL);
1373 address->m_error = GSOCK_INVADDR;
1374 return GSOCK_INVADDR;
1375 }
1376
1377 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1378 {
1379 assert (address != NULL);
1380 address->m_error = GSOCK_INVADDR;
1381 return GSOCK_INVADDR;
1382 }
1383
1384 #else /* !wxUSE_SOCKETS */
1385
1386 /*
1387 * translation unit shouldn't be empty, so include this typedef to make the
1388 * compiler (VC++ 6.0, for example) happy
1389 */
1390 typedef (*wxDummy)();
1391
1392 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
1393
1394 /* Diferencias con la version Unix:
1395 * - El descriptor es SOCKET y no int
1396 * - Constantes -1 pasan a INVALID_SOCKET
1397 * - Errores en muchas funciones pasan de -1 o <0 a SOCKET_ERROR
1398 * - ioctl y close pasan a ioctlsocket y closesocket
1399 * - inet_addr en lugar de inet_aton
1400 * - Codigo de inicializacion y terminacion para inicializar y
1401 * terminar WinSocket y para la ventana interna.
1402 * - SetTimeout, SetNonBlocking y la implementacion de los
1403 * timeouts eran bastante diferentes, pero ahora se han
1404 * hecho en la version Unix igual que en esta.
1405 */