]> git.saurik.com Git - wxWidgets.git/blame - src/msw/gsocket.c
wxDateTime progress: DST compuation, weekday computation, day-in-year and week
[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
2f7c2af5 9#ifndef __GSOCKET_STANDALONE__
9bbd7ba3 10#include "wx/setup.h"
0ce742cf
GRG
11#endif
12
13#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
14
15
16#ifndef __GSOCKET_STANDALONE__
17
9bbd7ba3
GRG
18#include "wx/msw/gsockmsw.h"
19#include "wx/gsocket.h"
20
eb254be6 21#define INSTANCE wxGetInstance()
9bbd7ba3
GRG
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 */
b661e675 32#define INSTANCE hInst
9bbd7ba3 33
2f7c2af5 34#endif /* __GSOCKET_STANDALONE__ */
9bbd7ba3
GRG
35
36
9bbd7ba3
GRG
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
62extern HINSTANCE INSTANCE;
63static HWND hWin;
64static CRITICAL_SECTION critical;
65static GSocket* socketList[MAXSOCKETS];
66static int firstAvailable;
67
68/* Global initializers */
69
70bool 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
9bbd7ba3
GRG
105 /* Initialize WinSocket */
106 return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
107}
108
109void GSocket_Cleanup()
110{
111 /* Destroy internal window */
aa3981f2 112 DestroyWindow(hWin);
9bbd7ba3
GRG
113 UnregisterClass(CLASSNAME, INSTANCE);
114
115 /* Delete critical section */
116 DeleteCriticalSection(&critical);
117
118 /* Cleanup WinSocket */
119 WSACleanup();
120}
121
122/* Constructors / Destructors */
123
124GSocket *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 */
b661e675 144 socket->m_timeout.tv_usec = 0;
75d684d9 145 socket->m_detected = 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
75d684d9 175 /* Remove the socket from the list */
9bbd7ba3
GRG
176 EnterCriticalSection(&critical);
177 socketList[(socket->m_msgnumber - WM_USER)] = NULL;
178 LeaveCriticalSection(&critical);
179
75d684d9 180 /* Check that the socket is really shutdowned */
9bbd7ba3
GRG
181 if (socket->m_fd != INVALID_SOCKET)
182 GSocket_Shutdown(socket);
183
75d684d9 184 /* Destroy private addresses */
9bbd7ba3
GRG
185 if (socket->m_local)
186 GAddress_destroy(socket->m_local);
187
188 if (socket->m_peer)
189 GAddress_destroy(socket->m_peer);
190
75d684d9 191 /* Destroy socket itself */
9bbd7ba3
GRG
192 free(socket);
193}
194
195void GSocket_Shutdown(GSocket *socket)
196{
197 int evt;
198
199 assert(socket != NULL);
200
75d684d9 201 /* If socket has been created, shutdown it */
9bbd7ba3
GRG
202 if (socket->m_fd != INVALID_SOCKET)
203 {
9bbd7ba3
GRG
204 shutdown(socket->m_fd, 2);
205 closesocket(socket->m_fd);
206 socket->m_fd = INVALID_SOCKET;
207 }
208
75d684d9 209 /* Disable GUI callbacks */
9bbd7ba3 210 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
9bbd7ba3 211 socket->m_cbacks[evt] = NULL;
9bbd7ba3 212
75d684d9
GRG
213 socket->m_detected = 0;
214 _GSocket_Disable_Events(socket);
9bbd7ba3
GRG
215}
216
217/* Address handling */
218
219GSocketError 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
243GSocketError 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
261GAddress *GSocket_GetLocal(GSocket *socket)
262{
263 GAddress *address;
264 struct sockaddr addr;
85806dc2
GRG
265 SOCKLEN_T size = sizeof(addr);
266 GSocketError err;
9bbd7ba3
GRG
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 }
85806dc2
GRG
293 err = _GAddress_translate_from(address, &addr, size);
294 if (err != GSOCK_NOERROR)
9bbd7ba3 295 {
9bbd7ba3 296 GAddress_destroy(address);
85806dc2 297 socket->m_error = err;
9bbd7ba3
GRG
298 return NULL;
299 }
300
301 return address;
302}
303
304GAddress *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 */
323GSocketError 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);
9bbd7ba3
GRG
348
349 if (sck->m_fd == INVALID_SOCKET)
350 {
351 sck->m_error = GSOCK_IOERR;
352 return GSOCK_IOERR;
353 }
354
483c6690 355 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 356 _GSocket_Enable_Events(sck);
483c6690 357
9bbd7ba3
GRG
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;
b661e675 377}
9bbd7ba3
GRG
378
379/* GSocket_WaitConnection:
380 * Waits for an incoming client connection.
381 */
382GSocket *GSocket_WaitConnection(GSocket *sck)
383{
384 GSocket *connection;
85806dc2
GRG
385 struct sockaddr from;
386 SOCKLEN_T fromlen = sizeof(from);
387 GSocketError err;
9bbd7ba3
GRG
388 u_long arg = 1;
389
390 assert(sck != NULL);
391
75d684d9
GRG
392 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
393
9bbd7ba3
GRG
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
85806dc2 417 connection->m_fd = accept(sck->m_fd, &from, &fromlen);
9bbd7ba3
GRG
418
419 if (connection->m_fd == INVALID_SOCKET)
420 {
aa3981f2
GRG
421 if (WSAGetLastError() == WSAEWOULDBLOCK)
422 sck->m_error = GSOCK_WOULDBLOCK;
423 else
424 sck->m_error = GSOCK_IOERR;
425
9bbd7ba3 426 GSocket_destroy(connection);
9bbd7ba3
GRG
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
85806dc2
GRG
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
cb421e53 452 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 453 _GSocket_Enable_Events(connection);
cb421e53 454
9bbd7ba3
GRG
455 return connection;
456}
457
458/* Non oriented connections */
459
460GSocketError 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);
9bbd7ba3
GRG
485
486 if (sck->m_fd == INVALID_SOCKET)
487 {
488 sck->m_error = GSOCK_IOERR;
489 return GSOCK_IOERR;
490 }
491
483c6690 492 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 493 _GSocket_Enable_Events(sck);
483c6690 494
9bbd7ba3
GRG
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
507GSocketError GSocket_SetBroadcast(GSocket *sck)
508{
75d684d9 509 BOOL b = TRUE;
9bbd7ba3
GRG
510
511 assert(sck != NULL);
512
513 if (GSocket_SetNonOriented(sck) != GSOCK_NOERROR)
514 return sck->m_error;
515
75d684d9
GRG
516 setsockopt(sck->m_fd, SOL_SOCKET, SO_BROADCAST,
517 (const char FAR *) &b, sizeof(b));
9bbd7ba3
GRG
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
cb421e53
GRG
527 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
528 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
483c6690
GRG
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.
9bbd7ba3
GRG
532 */
533GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
534{
535 u_long arg = 1;
aa3981f2 536 int type, ret, err;
9bbd7ba3
GRG
537
538 assert(sck != NULL);
539
75d684d9
GRG
540 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
541
9bbd7ba3
GRG
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);
9bbd7ba3
GRG
566
567 if (sck->m_fd == INVALID_SOCKET)
568 {
569 sck->m_error = GSOCK_IOERR;
570 return GSOCK_IOERR;
571 }
572
483c6690 573 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 574 _GSocket_Enable_Events(sck);
483c6690 575
aa3981f2 576 /* Connect it to the PEER address, with a timeout (see below) */
9bbd7ba3
GRG
577 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
578
579 if (ret == SOCKET_ERROR)
580 {
aa3981f2
GRG
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.
9bbd7ba3 587 */
cb421e53 588 if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking))
9bbd7ba3
GRG
589 {
590 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
591 {
592 closesocket(sck->m_fd);
593 sck->m_fd = INVALID_SOCKET;
cb421e53 594 /* sck->m_error is set in _GSocket_Output_Timeout */
9bbd7ba3
GRG
595 return GSOCK_TIMEDOUT;
596 }
aa3981f2
GRG
597 else
598 return GSOCK_NOERROR;
9bbd7ba3 599 }
aa3981f2
GRG
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 */
cb421e53 607 if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking))
9bbd7ba3 608 {
aa3981f2
GRG
609 sck->m_error = GSOCK_WOULDBLOCK;
610 return GSOCK_WOULDBLOCK;
9bbd7ba3 611 }
aa3981f2
GRG
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;
9bbd7ba3
GRG
620 }
621
622 return GSOCK_NOERROR;
623}
624
625/* Generic IO */
626
627/* Like recv(), send(), ... */
628int GSocket_Read(GSocket *socket, char *buffer, int size)
629{
75d684d9
GRG
630 int ret;
631
9bbd7ba3
GRG
632 assert(socket != NULL);
633
75d684d9
GRG
634 socket->m_detected &= ~GSOCK_INPUT_FLAG;
635
9bbd7ba3
GRG
636 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
637 {
638 socket->m_error = GSOCK_INVSOCK;
639 return -1;
640 }
641
75d684d9 642 /* If the socket is blocking, wait for data (with a timeout) */
9bbd7ba3
GRG
643 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
644 return -1;
645
75d684d9 646 /* Read the data */
9bbd7ba3 647 if (socket->m_stream)
75d684d9 648 ret = _GSocket_Recv_Stream(socket, buffer, size);
9bbd7ba3 649 else
75d684d9
GRG
650 ret = _GSocket_Recv_Dgram(socket, buffer, size);
651
652 if (ret == SOCKET_ERROR)
653 {
654 /* NOTE: Window sockets exhibit a very strange property;
655 * if the socket is in non-blocking mode (which is always
656 * the case here, no matter the setting of GSocket itself)
657 * a call to send() can fail with EWOULDBLOCK even when
658 * select() says that the socket is readable.
659 *
660 * This can break several things because, usually, if
661 * select() says that the socket is writable, it is
662 * assumed that send() won't fail. To avoid this, we
663 * return 0 instead of -1 for this special case.
664 */
665 if (WSAGetLastError() != WSAEWOULDBLOCK)
666 {
667 socket->m_error = GSOCK_IOERR;
668 return -1;
669 }
670 else
671 {
672 socket->m_error = GSOCK_WOULDBLOCK;
673 return 0;
674 }
675 }
676
677 return ret;
9bbd7ba3
GRG
678}
679
680int GSocket_Write(GSocket *socket, const char *buffer, int size)
681{
75d684d9
GRG
682 int ret;
683
9bbd7ba3
GRG
684 assert(socket != NULL);
685
686 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
687 {
688 socket->m_error = GSOCK_INVSOCK;
689 return -1;
690 }
691
75d684d9 692 /* If the socket is blocking, wait for writability (with a timeout) */
9bbd7ba3
GRG
693 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
694 return -1;
695
75d684d9 696 /* Read the data */
9bbd7ba3 697 if (socket->m_stream)
75d684d9 698 ret = _GSocket_Send_Stream(socket, buffer, size);
9bbd7ba3 699 else
75d684d9
GRG
700 ret = _GSocket_Send_Dgram(socket, buffer, size);
701
702 if (ret == SOCKET_ERROR)
703 {
704 if (WSAGetLastError() != WSAEWOULDBLOCK)
705 socket->m_error = GSOCK_IOERR;
706 else
707 socket->m_error = GSOCK_WOULDBLOCK;
708
709 socket->m_detected &= ~GSOCK_OUTPUT_FLAG;
710 return -1;
711 }
712
713 return ret;
9bbd7ba3
GRG
714}
715
483c6690
GRG
716/* GSocket_Select:
717 * Polls the socket to determine its status. This function will
718 * check for the events specified in the 'flags' parameter, and
719 * it will return a mask indicating which operations can be
720 * performed. This function won't block, regardless of the
721 * mode (blocking|nonblocking) of the socket.
722 */
723GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
9bbd7ba3 724{
9bbd7ba3
GRG
725 assert(socket != NULL);
726
75d684d9 727 return (flags & socket->m_detected);
9bbd7ba3
GRG
728}
729
730/* Flags */
731
732/* GSocket_SetNonBlocking:
483c6690 733 * Sets the socket to non-blocking mode. This is useful if
9bbd7ba3
GRG
734 * we don't want to wait.
735 */
736void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
737{
738 assert(socket != NULL);
739
740 socket->m_non_blocking = non_block;
741}
742
743/* GSocket_SetTimeout:
483c6690
GRG
744 * Sets the timeout for blocking calls. Time is
745 * expressed in milliseconds.
9bbd7ba3 746 */
75d684d9 747void GSocket_SetTimeout(GSocket *socket, unsigned long millis)
9bbd7ba3
GRG
748{
749 assert(socket != NULL);
750
75d684d9
GRG
751 socket->m_timeout.tv_sec = (millis / 1000);
752 socket->m_timeout.tv_usec = (millis % 1000) * 1000;
9bbd7ba3
GRG
753}
754
755/* GSocket_GetError:
756 * Returns the last error occured for this socket.
757 */
758GSocketError GSocket_GetError(GSocket *socket)
759{
760 assert(socket != NULL);
761
762 return socket->m_error;
763}
764
765/* Callbacks */
766
767/* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
768 * and LOST). The callbacks are called in the following situations:
769 *
770 * INPUT: There is at least one byte in the input buffer
771 * OUTPUT: The system is sure that the next write call will not block
772 * CONNECTION: Two cases are possible:
773 * Client socket -> the connection is established
774 * Server socket -> a client requests a connection
775 * LOST: The connection is lost
776 *
777 * An event is generated only once and its state is reseted when the
778 * relative IO call is requested.
779 * For example: INPUT -> GSocket_Read()
780 * CONNECTION -> GSocket_Accept()
781 */
782
783/* GSocket_SetCallback:
483c6690 784 * Enables the callbacks specified by 'flags'. Note that 'flags'
9bbd7ba3
GRG
785 * may be a combination of flags OR'ed toghether, so the same
786 * callback function can be made to accept different events.
787 * The callback function must have the following prototype:
788 *
789 * void function(GSocket *socket, GSocketEvent event, char *cdata)
790 */
483c6690 791void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
9bbd7ba3
GRG
792 GSocketCallback callback, char *cdata)
793{
794 int count;
795
796 assert (socket != NULL);
797
798 for (count = 0; count < GSOCK_MAX_EVENT; count++)
799 {
483c6690 800 if ((flags & (1 << count)) != 0)
9bbd7ba3
GRG
801 {
802 socket->m_cbacks[count] = callback;
803 socket->m_data[count] = cdata;
804 }
805 }
9bbd7ba3
GRG
806}
807
808/* GSocket_UnsetCallback:
483c6690 809 * Disables all callbacks specified by 'flags', which may be a
9bbd7ba3
GRG
810 * combination of flags OR'ed toghether.
811 */
483c6690 812void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
9bbd7ba3
GRG
813{
814 int count = 0;
815
816 assert(socket != NULL);
817
818 for (count = 0; count < GSOCK_MAX_EVENT; count++)
819 {
483c6690 820 if ((flags & (1 << count)) != 0)
9bbd7ba3
GRG
821 {
822 socket->m_cbacks[count] = NULL;
75d684d9 823 socket->m_data[count] = NULL;
9bbd7ba3
GRG
824 }
825 }
9bbd7ba3
GRG
826}
827
828
829/* Internals */
830
75d684d9
GRG
831/* _GSocket_Enable_Events:
832 * We enable all event notifications here (we need to be notified
833 * of all events for internal processing) but we will only notify
834 * users when an appropiate callback function has been installed.
835 */
836void _GSocket_Enable_Events(GSocket *socket)
9bbd7ba3 837{
75d684d9 838 assert (socket != NULL);
483c6690 839
75d684d9 840 if (socket->m_fd != INVALID_SOCKET)
9bbd7ba3 841 {
75d684d9
GRG
842 WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber,
843 FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
9bbd7ba3 844 }
75d684d9
GRG
845}
846
847/* _GSocket_Disable_Events:
848 * Disable event notifications (when shutdowning the socket)
849 */
850void _GSocket_Disable_Events(GSocket *socket)
851{
852 assert (socket != NULL);
9bbd7ba3 853
75d684d9
GRG
854 if (socket->m_fd != INVALID_SOCKET)
855 {
856 WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
857 }
9bbd7ba3
GRG
858}
859
75d684d9 860
9bbd7ba3
GRG
861LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd,
862 UINT uMsg,
863 WPARAM wParam,
864 LPARAM lParam)
865{
866 GSocket *socket;
867 GSocketEvent event;
868 GSocketCallback cback;
75d684d9 869 char *data;
9bbd7ba3
GRG
870
871 if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1))
872 {
873 EnterCriticalSection(&critical);
874 socket = socketList[(uMsg - WM_USER)];
875 event = -1;
876 cback = NULL;
75d684d9 877 data = NULL;
9bbd7ba3
GRG
878
879 /* Check that the socket still exists (it has not been
880 * destroyed) and for safety, check that the m_fd field
881 * is what we expect it to be.
882 */
883 if ((socket != NULL) && (socket->m_fd == wParam))
884 {
885 switch WSAGETSELECTEVENT(lParam)
886 {
887 case FD_READ: event = GSOCK_INPUT; break;
888 case FD_WRITE: event = GSOCK_OUTPUT; break;
889 case FD_ACCEPT: event = GSOCK_CONNECTION; break;
cb421e53
GRG
890 case FD_CONNECT:
891 {
892 if (WSAGETSELECTERROR(lParam) != 0)
893 event = GSOCK_LOST;
894 else
895 event = GSOCK_CONNECTION;
896 break;
897 }
9bbd7ba3
GRG
898 case FD_CLOSE: event = GSOCK_LOST; break;
899 }
900
901 if (event != -1)
75d684d9 902 {
9bbd7ba3 903 cback = socket->m_cbacks[event];
75d684d9
GRG
904 data = socket->m_data[event];
905
906 if (event == GSOCK_LOST)
907 socket->m_detected = GSOCK_LOST_FLAG;
908 else
909 socket->m_detected |= (1 << event);
910 }
9bbd7ba3
GRG
911 }
912
913 /* OK, we can now leave the critical section because we have
914 * already obtained the callback address (we make no further
915 * accesses to socket->whatever)
916 */
917 LeaveCriticalSection(&critical);
918
919 if (cback != NULL)
75d684d9 920 (cback)(socket, event, data);
9bbd7ba3
GRG
921
922 return (LRESULT) 0;
923 }
924 else
925 return DefWindowProc(hWnd, uMsg, wParam, lParam);
926}
927
928
929/* _GSocket_Input_Timeout:
930 * For blocking sockets, wait until data is available or
931 * until timeout ellapses.
932 */
933GSocketError _GSocket_Input_Timeout(GSocket *socket)
934{
935 fd_set readfds;
936
cb421e53 937 if (!socket->m_non_blocking)
9bbd7ba3
GRG
938 {
939 FD_ZERO(&readfds);
940 FD_SET(socket->m_fd, &readfds);
941 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
942 {
943 socket->m_error = GSOCK_TIMEDOUT;
944 return GSOCK_TIMEDOUT;
945 }
946 }
947 return GSOCK_NOERROR;
948}
949
950/* _GSocket_Output_Timeout:
951 * For blocking sockets, wait until data can be sent without
952 * blocking or until timeout ellapses.
953 */
954GSocketError _GSocket_Output_Timeout(GSocket *socket)
955{
956 fd_set writefds;
957
cb421e53 958 if (!socket->m_non_blocking)
9bbd7ba3
GRG
959 {
960 FD_ZERO(&writefds);
961 FD_SET(socket->m_fd, &writefds);
962 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
963 {
964 socket->m_error = GSOCK_TIMEDOUT;
965 return GSOCK_TIMEDOUT;
966 }
967 }
968 return GSOCK_NOERROR;
969}
970
971int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
972{
75d684d9 973 return recv(socket->m_fd, buffer, size, 0);
9bbd7ba3
GRG
974}
975
976int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
977{
978 struct sockaddr from;
75d684d9 979 SOCKLEN_T fromlen = sizeof(from);
9bbd7ba3 980 int ret;
85806dc2 981 GSocketError err;
9bbd7ba3 982
9bbd7ba3
GRG
983 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
984
985 if (ret == SOCKET_ERROR)
75d684d9 986 return SOCKET_ERROR;
9bbd7ba3
GRG
987
988 /* Translate a system address into a GSocket address */
989 if (!socket->m_peer)
990 {
991 socket->m_peer = GAddress_new();
992 if (!socket->m_peer)
993 {
994 socket->m_error = GSOCK_MEMERR;
995 return -1;
996 }
997 }
85806dc2
GRG
998 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
999 if (err != GSOCK_NOERROR)
9bbd7ba3 1000 {
cb421e53 1001 GAddress_destroy(socket->m_peer);
85806dc2
GRG
1002 socket->m_peer = NULL;
1003 socket->m_error = err;
9bbd7ba3
GRG
1004 return -1;
1005 }
1006
1007 return ret;
1008}
1009
1010int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
1011{
75d684d9 1012 return send(socket->m_fd, buffer, size, 0);
9bbd7ba3
GRG
1013}
1014
1015int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
1016{
1017 struct sockaddr *addr;
1018 int len, ret;
85806dc2 1019 GSocketError err;
9bbd7ba3
GRG
1020
1021 if (!socket->m_peer)
1022 {
1023 socket->m_error = GSOCK_INVADDR;
1024 return -1;
1025 }
1026
85806dc2
GRG
1027 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
1028 if (err != GSOCK_NOERROR)
9bbd7ba3 1029 {
85806dc2 1030 socket->m_error = err;
9bbd7ba3
GRG
1031 return -1;
1032 }
1033
1034 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1035
1036 /* Frees memory allocated by _GAddress_translate_to */
1037 free(addr);
1038
9bbd7ba3
GRG
1039 return ret;
1040}
1041
1042
1043/*
1044 * -------------------------------------------------------------------------
1045 * GAddress
1046 * -------------------------------------------------------------------------
1047 */
1048
1049/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
1050 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
1051 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
1052 */
1053#define CHECK_ADDRESS(address, family, retval) \
1054{ \
1055 if (address->m_family == GSOCK_NOFAMILY) \
1056 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1057 return address->m_error; \
1058 if (address->m_family != GSOCK_##family) \
1059 { \
1060 address->m_error = GSOCK_INVADDR; \
1061 return retval; \
1062 } \
1063}
1064
1065GAddress *GAddress_new()
1066{
1067 GAddress *address;
1068
1069 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1070 return NULL;
1071
1072 address->m_family = GSOCK_NOFAMILY;
1073 address->m_addr = NULL;
1074 address->m_len = 0;
1075
1076 return address;
1077}
1078
1079GAddress *GAddress_copy(GAddress *address)
1080{
1081 GAddress *addr2;
1082
1083 assert(address != NULL);
1084
1085 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1086 return NULL;
1087
1088 memcpy(addr2, address, sizeof(GAddress));
1089
1090 if (address->m_addr)
1091 {
1092 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1093 if (addr2->m_addr == NULL)
1094 {
1095 free(addr2);
1096 return NULL;
1097 }
1098 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1099 }
1100
1101 return addr2;
1102}
1103
1104void GAddress_destroy(GAddress *address)
1105{
1106 assert(address != NULL);
1107
1108 free(address);
1109}
1110
1111void GAddress_SetFamily(GAddress *address, GAddressType type)
1112{
1113 assert(address != NULL);
1114
1115 address->m_family = type;
1116}
1117
1118GAddressType GAddress_GetFamily(GAddress *address)
1119{
1120 assert(address != NULL);
1121
1122 return address->m_family;
1123}
1124
1125GSocketError _GAddress_translate_from(GAddress *address,
1126 struct sockaddr *addr, int len)
1127{
1128 address->m_realfamily = addr->sa_family;
1129 switch (addr->sa_family)
1130 {
1131 case AF_INET:
1132 address->m_family = GSOCK_INET;
1133 break;
1134 case AF_UNIX:
1135 address->m_family = GSOCK_UNIX;
1136 break;
1137#ifdef AF_INET6
1138 case AF_INET6:
1139 address->m_family = GSOCK_INET6;
1140 break;
1141#endif
1142 default:
1143 {
1144 address->m_error = GSOCK_INVOP;
1145 return GSOCK_INVOP;
1146 }
1147 }
1148
1149 if (address->m_addr)
1150 free(address->m_addr);
1151
1152 address->m_len = len;
1153 address->m_addr = (struct sockaddr *) malloc(len);
1154
1155 if (address->m_addr == NULL)
1156 {
1157 address->m_error = GSOCK_MEMERR;
1158 return GSOCK_MEMERR;
1159 }
1160 memcpy(address->m_addr, addr, len);
1161
1162 return GSOCK_NOERROR;
1163}
1164
1165GSocketError _GAddress_translate_to(GAddress *address,
1166 struct sockaddr **addr, int *len)
1167{
1168 if (!address->m_addr)
1169 {
1170 address->m_error = GSOCK_INVADDR;
1171 return GSOCK_INVADDR;
1172 }
1173
1174 *len = address->m_len;
1175 *addr = (struct sockaddr *) malloc(address->m_len);
1176 if (*addr == NULL)
1177 {
1178 address->m_error = GSOCK_MEMERR;
1179 return GSOCK_MEMERR;
1180 }
1181
1182 memcpy(*addr, address->m_addr, address->m_len);
1183 return GSOCK_NOERROR;
1184}
1185
1186/*
1187 * -------------------------------------------------------------------------
1188 * Internet address family
1189 * -------------------------------------------------------------------------
1190 */
1191
1192GSocketError _GAddress_Init_INET(GAddress *address)
1193{
e22da5d6 1194 address->m_len = sizeof(struct sockaddr_in);
9bbd7ba3
GRG
1195 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1196 if (address->m_addr == NULL)
1197 {
1198 address->m_error = GSOCK_MEMERR;
1199 return GSOCK_MEMERR;
1200 }
1201
9bbd7ba3
GRG
1202 address->m_family = GSOCK_INET;
1203 address->m_realfamily = PF_INET;
1204 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
06a0865f 1205 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_NONE;
9bbd7ba3
GRG
1206
1207 return GSOCK_NOERROR;
1208}
1209
1210GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1211{
1212 struct hostent *he;
1213 struct in_addr *addr;
1214
1215 assert(address != NULL);
1216
1217 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1218
1219 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1220
1221 addr->s_addr = inet_addr(hostname);
b661e675 1222
9bbd7ba3
GRG
1223 /* If it is a numeric host name, convert it now */
1224 if (addr->s_addr == INADDR_NONE)
1225 {
1226 struct in_addr *array_addr;
1227
1228 /* It is a real name, we solve it */
1229 if ((he = gethostbyname(hostname)) == NULL)
1230 {
1231 address->m_error = GSOCK_NOHOST;
1232 return GSOCK_NOHOST;
1233 }
1234 array_addr = (struct in_addr *) *(he->h_addr_list);
1235 addr->s_addr = array_addr[0].s_addr;
1236 }
1237 return GSOCK_NOERROR;
1238}
1239
1240GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1241 unsigned long hostaddr)
1242{
1243 struct in_addr *addr;
1244
1245 assert(address != NULL);
1246
1247 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1248
1249 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1250 addr->s_addr = hostaddr;
1251
1252 return GSOCK_NOERROR;
1253}
1254
1255GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1256 const char *protocol)
1257{
1258 struct servent *se;
1259 struct sockaddr_in *addr;
1260
1261 assert(address != NULL);
1262 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1263
1264 if (!port)
1265 {
1266 address->m_error = GSOCK_INVPORT;
1267 return GSOCK_INVOP;
1268 }
b661e675 1269
9bbd7ba3
GRG
1270 se = getservbyname(port, protocol);
1271 if (!se)
1272 {
1273 if (isdigit(port[0]))
1274 {
1275 int port_int;
1276
1277 port_int = atoi(port);
1278 addr = (struct sockaddr_in *)address->m_addr;
aa3981f2 1279 addr->sin_port = htons((u_short) port_int);
9bbd7ba3
GRG
1280 return GSOCK_NOERROR;
1281 }
1282
1283 address->m_error = GSOCK_INVPORT;
1284 return GSOCK_INVPORT;
1285 }
1286
1287 addr = (struct sockaddr_in *)address->m_addr;
1288 addr->sin_port = se->s_port;
1289
1290 return GSOCK_NOERROR;
1291}
1292
1293GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1294{
1295 struct sockaddr_in *addr;
1296
1297 assert(address != NULL);
1298 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
b661e675 1299
9bbd7ba3
GRG
1300 addr = (struct sockaddr_in *)address->m_addr;
1301 addr->sin_port = htons(port);
1302
1303 return GSOCK_NOERROR;
1304}
1305
1306GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1307{
1308 struct hostent *he;
1309 char *addr_buf;
1310 struct sockaddr_in *addr;
1311
b661e675 1312 assert(address != NULL);
9bbd7ba3
GRG
1313 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1314
1315 addr = (struct sockaddr_in *)address->m_addr;
1316 addr_buf = (char *)&(addr->sin_addr);
1317
1318 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1319 if (he == NULL)
1320 {
1321 address->m_error = GSOCK_NOHOST;
1322 return GSOCK_NOHOST;
1323 }
1324
1325 strncpy(hostname, he->h_name, sbuf);
1326
1327 return GSOCK_NOERROR;
1328}
1329
1330unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1331{
1332 struct sockaddr_in *addr;
1333
b661e675
RD
1334 assert(address != NULL);
1335 CHECK_ADDRESS(address, INET, 0);
9bbd7ba3
GRG
1336
1337 addr = (struct sockaddr_in *)address->m_addr;
1338
1339 return addr->sin_addr.s_addr;
1340}
1341
1342unsigned short GAddress_INET_GetPort(GAddress *address)
1343{
1344 struct sockaddr_in *addr;
1345
b661e675
RD
1346 assert(address != NULL);
1347 CHECK_ADDRESS(address, INET, 0);
9bbd7ba3
GRG
1348
1349 addr = (struct sockaddr_in *)address->m_addr;
1350 return ntohs(addr->sin_port);
1351}
1352
1353/*
1354 * -------------------------------------------------------------------------
1355 * Unix address family
1356 * -------------------------------------------------------------------------
1357 */
1358
1359GSocketError _GAddress_Init_UNIX(GAddress *address)
1360{
1361 assert (address != NULL);
1362 address->m_error = GSOCK_INVADDR;
1363 return GSOCK_INVADDR;
1364}
1365
1366GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1367{
1368 assert (address != NULL);
1369 address->m_error = GSOCK_INVADDR;
1370 return GSOCK_INVADDR;
1371}
1372
1373GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1374{
1375 assert (address != NULL);
1376 address->m_error = GSOCK_INVADDR;
1377 return GSOCK_INVADDR;
1378}
1379
a497618a 1380#else /* !wxUSE_SOCKETS */
9bbd7ba3 1381
a497618a
VZ
1382/*
1383 * translation unit shouldn't be empty, so include this typedef to make the
1384 * compiler (VC++ 6.0, for example) happy
1385 */
1386typedef (*wxDummy)();
9bbd7ba3 1387
a497618a 1388#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
9bbd7ba3
GRG
1389
1390/* Diferencias con la version Unix:
1391 * - El descriptor es SOCKET y no int
1392 * - Constantes -1 pasan a INVALID_SOCKET
1393 * - Errores en muchas funciones pasan de -1 o <0 a SOCKET_ERROR
1394 * - ioctl y close pasan a ioctlsocket y closesocket
1395 * - inet_addr en lugar de inet_aton
1396 * - Codigo de inicializacion y terminacion para inicializar y
1397 * terminar WinSocket y para la ventana interna.
75d684d9
GRG
1398 * - SetTimeout, SetNonBlocking y la implementacion de los
1399 * timeouts eran bastante diferentes, pero ahora se han
1400 * hecho en la version Unix igual que en esta.
9bbd7ba3 1401 */