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