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