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