]> git.saurik.com Git - wxWidgets.git/blame - src/msw/gsocket.c
added wxCheckListBox::HitTest() (modified patch 594524)
[wxWidgets.git] / src / msw / gsocket.c
CommitLineData
9bbd7ba3 1/* -------------------------------------------------------------------------
9bf10d6b 2 * Project: GSocket (Generic Socket)
9bbd7ba3 3 * Name: gsocket.c
9bf10d6b 4 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
9bbd7ba3
GRG
5 * Purpose: GSocket main MSW file
6 * CVSID: $Id$
7 * -------------------------------------------------------------------------
8 */
9
9bf10d6b
GRG
10/*
11 * PLEASE don't put C++ comments here - this is a C source file.
12 */
13
8a9c2246 14#ifdef _MSC_VER
29c25a8e
GRG
15 /* RPCNOTIFICATION_ROUTINE in rasasync.h (included from winsock.h),
16 * warning: conditional expression is constant.
17 */
18# pragma warning(disable:4115)
19 /* FD_SET,
20 * warning: named type definition in parentheses.
21 */
22# pragma warning(disable:4127)
23 /* GAddress_UNIX_GetPath,
24 * warning: unreferenced formal parameter.
25 */
26# pragma warning(disable:4100)
27#endif /* _MSC_VER */
28
8a9c2246 29
2f7c2af5 30#ifndef __GSOCKET_STANDALONE__
33ac7e6f 31# include "wx/defs.h"
29c25a8e 32# include "wx/setup.h"
0ce742cf
GRG
33#endif
34
35#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
36
0ce742cf 37#ifndef __GSOCKET_STANDALONE__
ed2eb9af
GRG
38# include "wx/msw/gsockmsw.h"
39# include "wx/gsocket.h"
9bbd7ba3 40#else
ed2eb9af
GRG
41# include "gsockmsw.h"
42# include "gsocket.h"
43#endif /* __GSOCKET_STANDALONE__ */
9bbd7ba3 44
29c25a8e 45/* Redefine some GUI-only functions to do nothing in console mode */
ed2eb9af 46#if defined(wxUSE_GUI) && !wxUSE_GUI
29c25a8e 47# define _GSocket_GUI_Init(socket) (1)
ed2eb9af
GRG
48# define _GSocket_GUI_Destroy(socket)
49# define _GSocket_Enable_Events(socket)
50# define _GSocket_Disable_Events(socket)
51#endif /* wxUSE_GUI */
9bbd7ba3 52
9bbd7ba3 53
9bbd7ba3
GRG
54#include <assert.h>
55#include <string.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <stddef.h>
59#include <ctype.h>
8a9c2246 60
9bbd7ba3
GRG
61#include <winsock.h>
62
c42404a5
VZ
63/* if we use configure for MSW SOCKLEN_T will be already defined */
64#ifndef SOCKLEN_T
ed2eb9af 65# define SOCKLEN_T int
c42404a5
VZ
66#endif
67
9bbd7ba3 68
9bf10d6b 69/* Constructors / Destructors for GSocket */
9bbd7ba3 70
da051b23 71GSocket *GSocket_new(void)
9bbd7ba3 72{
ed2eb9af 73 int i, success;
9bbd7ba3
GRG
74 GSocket *socket;
75
76 if ((socket = (GSocket *) malloc(sizeof(GSocket))) == NULL)
77 return NULL;
78
79 socket->m_fd = INVALID_SOCKET;
80 for (i = 0; i < GSOCK_MAX_EVENT; i++)
81 {
82 socket->m_cbacks[i] = NULL;
83 }
ed2eb9af 84 socket->m_detected = 0;
33ac7e6f
KB
85 socket->m_local = NULL;
86 socket->m_peer = NULL;
9bbd7ba3 87 socket->m_error = GSOCK_NOERROR;
33ac7e6f 88 socket->m_server = FALSE;
9bbd7ba3
GRG
89 socket->m_stream = TRUE;
90 socket->m_non_blocking = FALSE;
91 socket->m_timeout.tv_sec = 10 * 60; /* 10 minutes */
b661e675 92 socket->m_timeout.tv_usec = 0;
ed2eb9af 93 socket->m_establishing = FALSE;
9bbd7ba3 94
70988afb 95 /* Per-socket GUI-specific initialization */
ed2eb9af
GRG
96 success = _GSocket_GUI_Init(socket);
97 if (!success)
9bbd7ba3 98 {
70988afb 99 free(socket);
3ca6a5f0 100 socket = NULL;
9bbd7ba3 101 }
9bbd7ba3
GRG
102
103 return socket;
104}
105
007c77ab
RL
106void GSocket_close(GSocket *socket)
107{
108 _GSocket_Disable_Events(socket);
109 closesocket(socket->m_fd);
110 socket->m_fd = INVALID_SOCKET;
111}
112
9bbd7ba3
GRG
113void GSocket_destroy(GSocket *socket)
114{
115 assert(socket != NULL);
116
70988afb
GRG
117 /* Per-socket GUI-specific cleanup */
118 _GSocket_GUI_Destroy(socket);
9bbd7ba3 119
75d684d9 120 /* Check that the socket is really shutdowned */
9bbd7ba3
GRG
121 if (socket->m_fd != INVALID_SOCKET)
122 GSocket_Shutdown(socket);
123
75d684d9 124 /* Destroy private addresses */
9bbd7ba3
GRG
125 if (socket->m_local)
126 GAddress_destroy(socket->m_local);
127
128 if (socket->m_peer)
129 GAddress_destroy(socket->m_peer);
130
9bf10d6b 131 /* Destroy the socket itself */
9bbd7ba3
GRG
132 free(socket);
133}
134
9bf10d6b
GRG
135/* GSocket_Shutdown:
136 * Disallow further read/write operations on this socket, close
137 * the fd and disable all callbacks.
138 */
9bbd7ba3
GRG
139void GSocket_Shutdown(GSocket *socket)
140{
141 int evt;
142
143 assert(socket != NULL);
144
75d684d9 145 /* If socket has been created, shutdown it */
9bbd7ba3
GRG
146 if (socket->m_fd != INVALID_SOCKET)
147 {
9bbd7ba3 148 shutdown(socket->m_fd, 2);
007c77ab 149 GSocket_close(socket);
9bbd7ba3
GRG
150 }
151
75d684d9 152 /* Disable GUI callbacks */
9bbd7ba3 153 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
9bbd7ba3 154 socket->m_cbacks[evt] = NULL;
9bbd7ba3 155
557e7011 156 socket->m_detected = GSOCK_LOST_FLAG;
9bbd7ba3
GRG
157}
158
159/* Address handling */
160
9bf10d6b
GRG
161/* GSocket_SetLocal:
162 * GSocket_GetLocal:
163 * GSocket_SetPeer:
164 * GSocket_GetPeer:
165 * Set or get the local or peer address for this socket. The 'set'
166 * functions return GSOCK_NOERROR on success, an error code otherwise.
167 * The 'get' functions return a pointer to a GAddress object on success,
168 * or NULL otherwise, in which case they set the error code of the
169 * corresponding GSocket.
170 *
171 * Error codes:
172 * GSOCK_INVSOCK - the socket is not valid.
173 * GSOCK_INVADDR - the address is not valid.
174 */
9bbd7ba3
GRG
175GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
176{
177 assert(socket != NULL);
178
9bf10d6b 179 /* the socket must be initialized, or it must be a server */
9bbd7ba3
GRG
180 if (socket->m_fd != INVALID_SOCKET && !socket->m_server)
181 {
182 socket->m_error = GSOCK_INVSOCK;
183 return GSOCK_INVSOCK;
184 }
185
9bf10d6b 186 /* check address */
9bbd7ba3
GRG
187 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
188 {
189 socket->m_error = GSOCK_INVADDR;
190 return GSOCK_INVADDR;
191 }
192
193 if (socket->m_local)
194 GAddress_destroy(socket->m_local);
195
196 socket->m_local = GAddress_copy(address);
197
198 return GSOCK_NOERROR;
199}
200
201GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
202{
203 assert(socket != NULL);
204
9bf10d6b 205 /* check address */
9bbd7ba3
GRG
206 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
207 {
208 socket->m_error = GSOCK_INVADDR;
209 return GSOCK_INVADDR;
210 }
211
212 if (socket->m_peer)
213 GAddress_destroy(socket->m_peer);
214
215 socket->m_peer = GAddress_copy(address);
216
217 return GSOCK_NOERROR;
218}
219
220GAddress *GSocket_GetLocal(GSocket *socket)
221{
222 GAddress *address;
223 struct sockaddr addr;
85806dc2
GRG
224 SOCKLEN_T size = sizeof(addr);
225 GSocketError err;
9bbd7ba3
GRG
226
227 assert(socket != NULL);
228
9bf10d6b 229 /* try to get it from the m_local var first */
9bbd7ba3
GRG
230 if (socket->m_local)
231 return GAddress_copy(socket->m_local);
232
9bf10d6b 233 /* else, if the socket is initialized, try getsockname */
9bbd7ba3
GRG
234 if (socket->m_fd == INVALID_SOCKET)
235 {
236 socket->m_error = GSOCK_INVSOCK;
237 return NULL;
238 }
239
9bbd7ba3
GRG
240 if (getsockname(socket->m_fd, &addr, &size) == SOCKET_ERROR)
241 {
242 socket->m_error = GSOCK_IOERR;
243 return NULL;
244 }
245
9bf10d6b
GRG
246 /* got a valid address from getsockname, create a GAddress object */
247 if ((address = GAddress_new()) == NULL)
9bbd7ba3
GRG
248 {
249 socket->m_error = GSOCK_MEMERR;
250 return NULL;
251 }
9bf10d6b
GRG
252
253 if ((err = _GAddress_translate_from(address, &addr, size)) != GSOCK_NOERROR)
9bbd7ba3 254 {
9bbd7ba3 255 GAddress_destroy(address);
85806dc2 256 socket->m_error = err;
9bbd7ba3
GRG
257 return NULL;
258 }
259
260 return address;
261}
262
263GAddress *GSocket_GetPeer(GSocket *socket)
264{
265 assert(socket != NULL);
266
9bf10d6b 267 /* try to get it from the m_peer var */
9bbd7ba3
GRG
268 if (socket->m_peer)
269 return GAddress_copy(socket->m_peer);
270
271 return NULL;
272}
273
274/* Server specific parts */
275
276/* GSocket_SetServer:
9bf10d6b
GRG
277 * Sets up this socket as a server. The local address must have been
278 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
279 * Returns GSOCK_NOERROR on success, one of the following otherwise:
33ac7e6f 280 *
9bf10d6b
GRG
281 * Error codes:
282 * GSOCK_INVSOCK - the socket is in use.
283 * GSOCK_INVADDR - the local address has not been set.
33ac7e6f 284 * GSOCK_IOERR - low-level error.
9bbd7ba3
GRG
285 */
286GSocketError GSocket_SetServer(GSocket *sck)
287{
288 u_long arg = 1;
289
290 assert(sck != NULL);
291
9bf10d6b 292 /* must not be in use */
9bbd7ba3
GRG
293 if (sck->m_fd != INVALID_SOCKET)
294 {
295 sck->m_error = GSOCK_INVSOCK;
296 return GSOCK_INVSOCK;
297 }
298
9bf10d6b 299 /* the local addr must have been set */
9bbd7ba3
GRG
300 if (!sck->m_local)
301 {
302 sck->m_error = GSOCK_INVADDR;
303 return GSOCK_INVADDR;
304 }
305
306 /* Initialize all fields */
307 sck->m_server = TRUE;
308 sck->m_stream = TRUE;
309 sck->m_oriented = TRUE;
310
311 /* Create the socket */
312 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
9bbd7ba3
GRG
313
314 if (sck->m_fd == INVALID_SOCKET)
315 {
316 sck->m_error = GSOCK_IOERR;
317 return GSOCK_IOERR;
318 }
319
483c6690 320 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 321 _GSocket_Enable_Events(sck);
483c6690 322
9bf10d6b
GRG
323 /* Bind to the local address,
324 * retrieve the actual address bound,
325 * and listen up to 5 connections.
326 */
327 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
328 (getsockname(sck->m_fd,
329 sck->m_local->m_addr,
378d2bd3 330 (SOCKLEN_T *)&sck->m_local->m_len) != 0) ||
9bf10d6b 331 (listen(sck->m_fd, 5) != 0))
9bbd7ba3 332 {
007c77ab 333 GSocket_close(sck);
9bbd7ba3
GRG
334 sck->m_error = GSOCK_IOERR;
335 return GSOCK_IOERR;
336 }
337
338 return GSOCK_NOERROR;
b661e675 339}
9bbd7ba3
GRG
340
341/* GSocket_WaitConnection:
9bf10d6b
GRG
342 * Waits for an incoming client connection. Returns a pointer to
343 * a GSocket object, or NULL if there was an error, in which case
344 * the last error field will be updated for the calling GSocket.
345 *
346 * Error codes (set in the calling GSocket)
347 * GSOCK_INVSOCK - the socket is not valid or not a server.
348 * GSOCK_TIMEDOUT - timeout, no incoming connections.
349 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
350 * GSOCK_MEMERR - couldn't allocate memory.
33ac7e6f 351 * GSOCK_IOERR - low-level error.
9bbd7ba3
GRG
352 */
353GSocket *GSocket_WaitConnection(GSocket *sck)
354{
355 GSocket *connection;
85806dc2
GRG
356 struct sockaddr from;
357 SOCKLEN_T fromlen = sizeof(from);
358 GSocketError err;
9bbd7ba3
GRG
359 u_long arg = 1;
360
361 assert(sck != NULL);
362
9bf10d6b 363 /* Reenable CONNECTION events */
75d684d9
GRG
364 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
365
9bf10d6b 366 /* If the socket has already been created, we exit immediately */
9bbd7ba3
GRG
367 if (sck->m_fd == INVALID_SOCKET || !sck->m_server)
368 {
369 sck->m_error = GSOCK_INVSOCK;
370 return NULL;
371 }
372
373 /* Create a GSocket object for the new connection */
374 connection = GSocket_new();
375
376 if (!connection)
377 {
378 sck->m_error = GSOCK_MEMERR;
379 return NULL;
380 }
381
382 /* Wait for a connection (with timeout) */
383 if (_GSocket_Input_Timeout(sck) == GSOCK_TIMEDOUT)
384 {
385 GSocket_destroy(connection);
386 /* sck->m_error set by _GSocket_Input_Timeout */
387 return NULL;
388 }
389
85806dc2 390 connection->m_fd = accept(sck->m_fd, &from, &fromlen);
9bbd7ba3
GRG
391
392 if (connection->m_fd == INVALID_SOCKET)
393 {
aa3981f2
GRG
394 if (WSAGetLastError() == WSAEWOULDBLOCK)
395 sck->m_error = GSOCK_WOULDBLOCK;
396 else
397 sck->m_error = GSOCK_IOERR;
398
9bbd7ba3 399 GSocket_destroy(connection);
9bbd7ba3
GRG
400 return NULL;
401 }
402
403 /* Initialize all fields */
404 connection->m_server = FALSE;
405 connection->m_stream = TRUE;
406 connection->m_oriented = TRUE;
407
85806dc2
GRG
408 /* Setup the peer address field */
409 connection->m_peer = GAddress_new();
410 if (!connection->m_peer)
411 {
412 GSocket_destroy(connection);
413 sck->m_error = GSOCK_MEMERR;
414 return NULL;
415 }
416 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
417 if (err != GSOCK_NOERROR)
418 {
419 GAddress_destroy(connection->m_peer);
420 GSocket_destroy(connection);
421 sck->m_error = err;
422 return NULL;
423 }
424
cb421e53 425 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 426 _GSocket_Enable_Events(connection);
cb421e53 427
9bbd7ba3
GRG
428 return connection;
429}
430
9bbd7ba3
GRG
431/* Client specific parts */
432
433/* GSocket_Connect:
9bf10d6b
GRG
434 * For stream (connection oriented) sockets, GSocket_Connect() tries
435 * to establish a client connection to a server using the peer address
436 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
437 * connection has been succesfully established, or one of the error
438 * codes listed below. Note that for nonblocking sockets, a return
439 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
440 * request can be completed later; you should use GSocket_Select()
441 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
442 * corresponding asynchronous events.
443 *
444 * For datagram (non connection oriented) sockets, GSocket_Connect()
445 * just sets the peer address established with GSocket_SetPeer() as
446 * default destination.
447 *
448 * Error codes:
449 * GSOCK_INVSOCK - the socket is in use or not valid.
450 * GSOCK_INVADDR - the peer address has not been established.
451 * GSOCK_TIMEDOUT - timeout, the connection failed.
452 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
453 * GSOCK_MEMERR - couldn't allocate memory.
33ac7e6f 454 * GSOCK_IOERR - low-level error.
9bbd7ba3
GRG
455 */
456GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
457{
9bf10d6b 458 int ret, err;
9bbd7ba3 459 u_long arg = 1;
9bbd7ba3
GRG
460
461 assert(sck != NULL);
462
9bf10d6b 463 /* Enable CONNECTION events (needed for nonblocking connections) */
75d684d9
GRG
464 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
465
9bbd7ba3
GRG
466 if (sck->m_fd != INVALID_SOCKET)
467 {
468 sck->m_error = GSOCK_INVSOCK;
469 return GSOCK_INVSOCK;
470 }
471
472 if (!sck->m_peer)
473 {
474 sck->m_error = GSOCK_INVADDR;
475 return GSOCK_INVADDR;
476 }
477
9bf10d6b 478 /* Streamed or dgram socket? */
9bbd7ba3
GRG
479 sck->m_stream = (stream == GSOCK_STREAMED);
480 sck->m_oriented = TRUE;
481 sck->m_server = FALSE;
ed2eb9af 482 sck->m_establishing = FALSE;
9bbd7ba3 483
9bbd7ba3 484 /* Create the socket */
9bf10d6b
GRG
485 sck->m_fd = socket(sck->m_peer->m_realfamily,
486 sck->m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
9bbd7ba3
GRG
487
488 if (sck->m_fd == INVALID_SOCKET)
489 {
490 sck->m_error = GSOCK_IOERR;
491 return GSOCK_IOERR;
492 }
493
483c6690 494 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
75d684d9 495 _GSocket_Enable_Events(sck);
483c6690 496
9bf10d6b 497 /* Connect it to the peer address, with a timeout (see below) */
9bbd7ba3
GRG
498 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
499
500 if (ret == SOCKET_ERROR)
501 {
aa3981f2
GRG
502 err = WSAGetLastError();
503
504 /* If connect failed with EWOULDBLOCK and the GSocket object
505 * is in blocking mode, we select() for the specified timeout
506 * checking for writability to see if the connection request
507 * completes.
9bbd7ba3 508 */
cb421e53 509 if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking))
9bbd7ba3 510 {
9bf10d6b
GRG
511 err = _GSocket_Connect_Timeout(sck);
512
513 if (err != GSOCK_NOERROR)
9bbd7ba3 514 {
007c77ab 515 GSocket_close(sck);
9bf10d6b 516 /* sck->m_error is set in _GSocket_Connect_Timeout */
9bbd7ba3 517 }
9bf10d6b 518
ba14d986 519 return (GSocketError) err;
9bbd7ba3 520 }
aa3981f2
GRG
521
522 /* If connect failed with EWOULDBLOCK and the GSocket object
523 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
524 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
525 * this way if the connection completes, a GSOCK_CONNECTION
526 * event will be generated, if enabled.
527 */
cb421e53 528 if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking))
9bbd7ba3 529 {
ed2eb9af 530 sck->m_establishing = TRUE;
aa3981f2
GRG
531 sck->m_error = GSOCK_WOULDBLOCK;
532 return GSOCK_WOULDBLOCK;
9bbd7ba3 533 }
aa3981f2
GRG
534
535 /* If connect failed with an error other than EWOULDBLOCK,
9bf10d6b 536 * then the call to GSocket_Connect() has failed.
aa3981f2 537 */
007c77ab 538 GSocket_close(sck);
aa3981f2
GRG
539 sck->m_error = GSOCK_IOERR;
540 return GSOCK_IOERR;
9bbd7ba3
GRG
541 }
542
543 return GSOCK_NOERROR;
544}
545
9bf10d6b
GRG
546/* Datagram sockets */
547
548/* GSocket_SetNonOriented:
549 * Sets up this socket as a non-connection oriented (datagram) socket.
550 * Before using this function, the local address must have been set
551 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
552 * on success, or one of the following otherwise.
553 *
554 * Error codes:
555 * GSOCK_INVSOCK - the socket is in use.
556 * GSOCK_INVADDR - the local address has not been set.
33ac7e6f 557 * GSOCK_IOERR - low-level error.
9bf10d6b
GRG
558 */
559GSocketError GSocket_SetNonOriented(GSocket *sck)
560{
561 u_long arg = 1;
562
563 assert(sck != NULL);
564
565 if (sck->m_fd != INVALID_SOCKET)
566 {
567 sck->m_error = GSOCK_INVSOCK;
568 return GSOCK_INVSOCK;
569 }
570
571 if (!sck->m_local)
572 {
573 sck->m_error = GSOCK_INVADDR;
574 return GSOCK_INVADDR;
575 }
576
577 /* Initialize all fields */
578 sck->m_stream = FALSE;
579 sck->m_server = FALSE;
580 sck->m_oriented = FALSE;
581
582 /* Create the socket */
583 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
584
585 if (sck->m_fd == INVALID_SOCKET)
586 {
587 sck->m_error = GSOCK_IOERR;
588 return GSOCK_IOERR;
589 }
590
591 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
592 _GSocket_Enable_Events(sck);
593
594 /* Bind to the local address,
595 * and retrieve the actual address bound.
596 */
597 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
598 (getsockname(sck->m_fd,
599 sck->m_local->m_addr,
378d2bd3 600 (SOCKLEN_T *)&sck->m_local->m_len) != 0))
9bf10d6b 601 {
007c77ab 602 GSocket_close(sck);
9bf10d6b
GRG
603 sck->m_error = GSOCK_IOERR;
604 return GSOCK_IOERR;
605 }
606
607 return GSOCK_NOERROR;
608}
609
9bbd7ba3
GRG
610/* Generic IO */
611
612/* Like recv(), send(), ... */
613int GSocket_Read(GSocket *socket, char *buffer, int size)
614{
75d684d9
GRG
615 int ret;
616
9bbd7ba3
GRG
617 assert(socket != NULL);
618
9bf10d6b 619 /* Reenable INPUT events */
75d684d9
GRG
620 socket->m_detected &= ~GSOCK_INPUT_FLAG;
621
9bbd7ba3
GRG
622 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
623 {
624 socket->m_error = GSOCK_INVSOCK;
625 return -1;
626 }
627
75d684d9 628 /* If the socket is blocking, wait for data (with a timeout) */
9bbd7ba3
GRG
629 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
630 return -1;
631
75d684d9 632 /* Read the data */
9bbd7ba3 633 if (socket->m_stream)
75d684d9 634 ret = _GSocket_Recv_Stream(socket, buffer, size);
9bbd7ba3 635 else
75d684d9
GRG
636 ret = _GSocket_Recv_Dgram(socket, buffer, size);
637
638 if (ret == SOCKET_ERROR)
639 {
75d684d9 640 if (WSAGetLastError() != WSAEWOULDBLOCK)
75d684d9 641 socket->m_error = GSOCK_IOERR;
75d684d9 642 else
75d684d9 643 socket->m_error = GSOCK_WOULDBLOCK;
9bf10d6b 644 return -1;
75d684d9
GRG
645 }
646
647 return ret;
9bbd7ba3
GRG
648}
649
650int GSocket_Write(GSocket *socket, const char *buffer, int size)
651{
75d684d9
GRG
652 int ret;
653
9bbd7ba3
GRG
654 assert(socket != NULL);
655
656 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
657 {
658 socket->m_error = GSOCK_INVSOCK;
659 return -1;
660 }
661
75d684d9 662 /* If the socket is blocking, wait for writability (with a timeout) */
9bbd7ba3
GRG
663 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
664 return -1;
665
9bf10d6b 666 /* Write the data */
9bbd7ba3 667 if (socket->m_stream)
75d684d9 668 ret = _GSocket_Send_Stream(socket, buffer, size);
9bbd7ba3 669 else
75d684d9
GRG
670 ret = _GSocket_Send_Dgram(socket, buffer, size);
671
672 if (ret == SOCKET_ERROR)
673 {
674 if (WSAGetLastError() != WSAEWOULDBLOCK)
675 socket->m_error = GSOCK_IOERR;
676 else
677 socket->m_error = GSOCK_WOULDBLOCK;
678
9bf10d6b
GRG
679 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
680 * does). Once the first OUTPUT event is received, users can assume
681 * that the socket is writable until a read operation fails. Only then
682 * will further OUTPUT events be posted.
683 */
75d684d9
GRG
684 socket->m_detected &= ~GSOCK_OUTPUT_FLAG;
685 return -1;
686 }
687
688 return ret;
9bbd7ba3
GRG
689}
690
483c6690
GRG
691/* GSocket_Select:
692 * Polls the socket to determine its status. This function will
693 * check for the events specified in the 'flags' parameter, and
694 * it will return a mask indicating which operations can be
695 * performed. This function won't block, regardless of the
9bf10d6b 696 * mode (blocking | nonblocking) of the socket.
483c6690
GRG
697 */
698GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
9bbd7ba3 699{
ed2eb9af
GRG
700#if defined(wxUSE_GUI) && !wxUSE_GUI
701
702 GSocketEventFlags result = 0;
703 fd_set readfds;
704 fd_set writefds;
705 fd_set exceptfds;
706 static const struct timeval tv = { 0, 0 };
707
9bbd7ba3
GRG
708 assert(socket != NULL);
709
ed2eb9af
GRG
710 FD_ZERO(&readfds);
711 FD_ZERO(&writefds);
712 FD_ZERO(&exceptfds);
713 FD_SET(socket->m_fd, &readfds);
714 FD_SET(socket->m_fd, &writefds);
715 FD_SET(socket->m_fd, &exceptfds);
716
717 /* Check known state first */
718 result |= (GSOCK_CONNECTION_FLAG & socket->m_detected & flags);
719 result |= (GSOCK_LOST_FLAG & socket->m_detected & flags);
720
721 /* Try select now */
722 if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
723 return result;
724
725 /* Check for readability */
726 if (FD_ISSET(socket->m_fd, &readfds))
727 {
728 /* Assume that closure of the socket is always reported via exceptfds */
729 if (socket->m_server && socket->m_stream)
730 result |= (GSOCK_CONNECTION_FLAG & flags);
731 else
732 result |= (GSOCK_INPUT_FLAG & flags);
733 }
734
735 /* Check for writability */
736 if (FD_ISSET(socket->m_fd, &writefds))
737 {
738 if (socket->m_establishing && !socket->m_server)
739 {
740 result |= (GSOCK_CONNECTION_FLAG & flags);
741 socket->m_establishing = FALSE;
742 socket->m_detected |= GSOCK_CONNECTION_FLAG;
743 }
744 else
745 result |= (GSOCK_OUTPUT_FLAG & flags);
746 }
747
748 /* Check for exceptions and errors */
749 if (FD_ISSET(socket->m_fd, &exceptfds))
750 {
751 result |= (GSOCK_LOST_FLAG & flags);
752 socket->m_establishing = FALSE;
753 socket->m_detected = GSOCK_LOST_FLAG;
754 }
755
756 return result;
757
33ac7e6f 758#else
ed2eb9af
GRG
759
760 assert(socket != NULL);
ef57d866 761 return flags & socket->m_detected;
ed2eb9af
GRG
762
763#endif /* !wxUSE_GUI */
9bbd7ba3
GRG
764}
765
9bf10d6b 766/* Attributes */
9bbd7ba3
GRG
767
768/* GSocket_SetNonBlocking:
9bf10d6b
GRG
769 * Sets the socket to non-blocking mode. All IO calls will return
770 * immediately.
9bbd7ba3 771 */
5c9eff30 772void GSocket_SetNonBlocking(GSocket *socket, int non_block)
9bbd7ba3
GRG
773{
774 assert(socket != NULL);
775
776 socket->m_non_blocking = non_block;
777}
778
779/* GSocket_SetTimeout:
9bf10d6b
GRG
780 * Sets the timeout for blocking calls. Time is expressed in
781 * milliseconds.
9bbd7ba3 782 */
75d684d9 783void GSocket_SetTimeout(GSocket *socket, unsigned long millis)
9bbd7ba3
GRG
784{
785 assert(socket != NULL);
786
75d684d9
GRG
787 socket->m_timeout.tv_sec = (millis / 1000);
788 socket->m_timeout.tv_usec = (millis % 1000) * 1000;
9bbd7ba3
GRG
789}
790
791/* GSocket_GetError:
9bf10d6b
GRG
792 * Returns the last error occured for this socket. Note that successful
793 * operations do not clear this back to GSOCK_NOERROR, so use it only
794 * after an error.
9bbd7ba3 795 */
82805fe2 796GSocketError GSocket_GetError(GSocket *socket)
9bbd7ba3
GRG
797{
798 assert(socket != NULL);
799
800 return socket->m_error;
801}
802
803/* Callbacks */
804
9bf10d6b
GRG
805/* GSOCK_INPUT:
806 * There is data to be read in the input buffer. If, after a read
807 * operation, there is still data available, the callback function will
808 * be called again.
809 * GSOCK_OUTPUT:
33ac7e6f 810 * The socket is available for writing. That is, the next write call
9bf10d6b
GRG
811 * won't block. This event is generated only once, when the connection is
812 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
813 * when the output buffer empties again. This means that the app should
814 * assume that it can write since the first OUTPUT event, and no more
815 * OUTPUT events will be generated unless an error occurs.
816 * GSOCK_CONNECTION:
817 * Connection succesfully established, for client sockets, or incoming
818 * client connection, for server sockets. Wait for this event (also watch
819 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
820 * GSOCK_LOST:
821 * The connection is lost (or a connection request failed); this could
822 * be due to a failure, or due to the peer closing it gracefully.
9bbd7ba3
GRG
823 */
824
825/* GSocket_SetCallback:
483c6690 826 * Enables the callbacks specified by 'flags'. Note that 'flags'
9bbd7ba3
GRG
827 * may be a combination of flags OR'ed toghether, so the same
828 * callback function can be made to accept different events.
829 * The callback function must have the following prototype:
830 *
831 * void function(GSocket *socket, GSocketEvent event, char *cdata)
832 */
483c6690 833void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
9bbd7ba3
GRG
834 GSocketCallback callback, char *cdata)
835{
836 int count;
837
9bf10d6b 838 assert(socket != NULL);
9bbd7ba3
GRG
839
840 for (count = 0; count < GSOCK_MAX_EVENT; count++)
841 {
483c6690 842 if ((flags & (1 << count)) != 0)
9bbd7ba3
GRG
843 {
844 socket->m_cbacks[count] = callback;
845 socket->m_data[count] = cdata;
846 }
847 }
9bbd7ba3
GRG
848}
849
850/* GSocket_UnsetCallback:
483c6690 851 * Disables all callbacks specified by 'flags', which may be a
9bbd7ba3
GRG
852 * combination of flags OR'ed toghether.
853 */
483c6690 854void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
9bbd7ba3 855{
9bf10d6b 856 int count;
9bbd7ba3
GRG
857
858 assert(socket != NULL);
859
860 for (count = 0; count < GSOCK_MAX_EVENT; count++)
861 {
483c6690 862 if ((flags & (1 << count)) != 0)
9bbd7ba3
GRG
863 {
864 socket->m_cbacks[count] = NULL;
75d684d9 865 socket->m_data[count] = NULL;
9bbd7ba3
GRG
866 }
867 }
9bbd7ba3
GRG
868}
869
70988afb 870/* Internals (IO) */
9bbd7ba3
GRG
871
872/* _GSocket_Input_Timeout:
873 * For blocking sockets, wait until data is available or
874 * until timeout ellapses.
875 */
876GSocketError _GSocket_Input_Timeout(GSocket *socket)
877{
878 fd_set readfds;
879
cb421e53 880 if (!socket->m_non_blocking)
9bbd7ba3
GRG
881 {
882 FD_ZERO(&readfds);
883 FD_SET(socket->m_fd, &readfds);
884 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
885 {
886 socket->m_error = GSOCK_TIMEDOUT;
887 return GSOCK_TIMEDOUT;
888 }
889 }
890 return GSOCK_NOERROR;
891}
892
893/* _GSocket_Output_Timeout:
894 * For blocking sockets, wait until data can be sent without
895 * blocking or until timeout ellapses.
896 */
897GSocketError _GSocket_Output_Timeout(GSocket *socket)
898{
899 fd_set writefds;
900
cb421e53 901 if (!socket->m_non_blocking)
9bbd7ba3
GRG
902 {
903 FD_ZERO(&writefds);
904 FD_SET(socket->m_fd, &writefds);
905 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
906 {
907 socket->m_error = GSOCK_TIMEDOUT;
908 return GSOCK_TIMEDOUT;
909 }
910 }
911 return GSOCK_NOERROR;
912}
913
9bf10d6b
GRG
914/* _GSocket_Connect_Timeout:
915 * For blocking sockets, wait until the connection is
916 * established or fails, or until timeout ellapses.
917 */
918GSocketError _GSocket_Connect_Timeout(GSocket *socket)
919{
920 fd_set writefds;
921 fd_set exceptfds;
922
5330a869
GRG
923 FD_ZERO(&writefds);
924 FD_ZERO(&exceptfds);
925 FD_SET(socket->m_fd, &writefds);
926 FD_SET(socket->m_fd, &exceptfds);
927 if (select(0, NULL, &writefds, &exceptfds, &socket->m_timeout) == 0)
9bf10d6b 928 {
5330a869
GRG
929 socket->m_error = GSOCK_TIMEDOUT;
930 return GSOCK_TIMEDOUT;
9bf10d6b
GRG
931 }
932 if (!FD_ISSET(socket->m_fd, &writefds))
933 {
934 socket->m_error = GSOCK_IOERR;
935 return GSOCK_IOERR;
936 }
937
938 return GSOCK_NOERROR;
939}
940
9bbd7ba3
GRG
941int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
942{
75d684d9 943 return recv(socket->m_fd, buffer, size, 0);
9bbd7ba3
GRG
944}
945
946int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
947{
948 struct sockaddr from;
75d684d9 949 SOCKLEN_T fromlen = sizeof(from);
9bbd7ba3 950 int ret;
85806dc2 951 GSocketError err;
9bbd7ba3 952
9bbd7ba3
GRG
953 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
954
955 if (ret == SOCKET_ERROR)
75d684d9 956 return SOCKET_ERROR;
9bbd7ba3
GRG
957
958 /* Translate a system address into a GSocket address */
959 if (!socket->m_peer)
960 {
961 socket->m_peer = GAddress_new();
962 if (!socket->m_peer)
963 {
964 socket->m_error = GSOCK_MEMERR;
965 return -1;
966 }
967 }
85806dc2
GRG
968 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
969 if (err != GSOCK_NOERROR)
9bbd7ba3 970 {
cb421e53 971 GAddress_destroy(socket->m_peer);
85806dc2
GRG
972 socket->m_peer = NULL;
973 socket->m_error = err;
9bbd7ba3
GRG
974 return -1;
975 }
976
977 return ret;
978}
979
980int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
981{
75d684d9 982 return send(socket->m_fd, buffer, size, 0);
9bbd7ba3
GRG
983}
984
985int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
986{
987 struct sockaddr *addr;
988 int len, ret;
85806dc2 989 GSocketError err;
9bbd7ba3
GRG
990
991 if (!socket->m_peer)
992 {
993 socket->m_error = GSOCK_INVADDR;
994 return -1;
995 }
996
85806dc2
GRG
997 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
998 if (err != GSOCK_NOERROR)
9bbd7ba3 999 {
85806dc2 1000 socket->m_error = err;
9bbd7ba3
GRG
1001 return -1;
1002 }
1003
1004 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1005
1006 /* Frees memory allocated by _GAddress_translate_to */
1007 free(addr);
1008
9bbd7ba3
GRG
1009 return ret;
1010}
1011
1012
1013/*
1014 * -------------------------------------------------------------------------
1015 * GAddress
1016 * -------------------------------------------------------------------------
1017 */
1018
032d5581
GRG
1019/* CHECK_ADDRESS verifies that the current address family is either
1020 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1021 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1022 * an appropiate error code.
1023 *
1024 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
9bbd7ba3 1025 */
032d5581 1026#define CHECK_ADDRESS(address, family) \
9bbd7ba3
GRG
1027{ \
1028 if (address->m_family == GSOCK_NOFAMILY) \
1029 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1030 return address->m_error; \
1031 if (address->m_family != GSOCK_##family) \
032d5581
GRG
1032 { \
1033 address->m_error = GSOCK_INVADDR; \
1034 return GSOCK_INVADDR; \
1035 } \
1036}
1037
1038#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1039{ \
1040 if (address->m_family == GSOCK_NOFAMILY) \
1041 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1042 return retval; \
1043 if (address->m_family != GSOCK_##family) \
9bbd7ba3
GRG
1044 { \
1045 address->m_error = GSOCK_INVADDR; \
1046 return retval; \
1047 } \
1048}
1049
032d5581 1050
da051b23 1051GAddress *GAddress_new(void)
9bbd7ba3
GRG
1052{
1053 GAddress *address;
1054
1055 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1056 return NULL;
1057
1058 address->m_family = GSOCK_NOFAMILY;
1059 address->m_addr = NULL;
1060 address->m_len = 0;
1061
1062 return address;
1063}
1064
1065GAddress *GAddress_copy(GAddress *address)
1066{
1067 GAddress *addr2;
1068
1069 assert(address != NULL);
1070
1071 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1072 return NULL;
1073
1074 memcpy(addr2, address, sizeof(GAddress));
1075
1076 if (address->m_addr)
1077 {
1078 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1079 if (addr2->m_addr == NULL)
1080 {
1081 free(addr2);
1082 return NULL;
1083 }
1084 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1085 }
1086
1087 return addr2;
1088}
1089
1090void GAddress_destroy(GAddress *address)
1091{
1092 assert(address != NULL);
1093
29c25a8e
GRG
1094 if (address->m_addr)
1095 free(address->m_addr);
1096
9bbd7ba3
GRG
1097 free(address);
1098}
1099
1100void GAddress_SetFamily(GAddress *address, GAddressType type)
1101{
1102 assert(address != NULL);
1103
1104 address->m_family = type;
1105}
1106
1107GAddressType GAddress_GetFamily(GAddress *address)
1108{
1109 assert(address != NULL);
1110
1111 return address->m_family;
1112}
1113
1114GSocketError _GAddress_translate_from(GAddress *address,
1115 struct sockaddr *addr, int len)
1116{
1117 address->m_realfamily = addr->sa_family;
1118 switch (addr->sa_family)
1119 {
1120 case AF_INET:
1121 address->m_family = GSOCK_INET;
1122 break;
1123 case AF_UNIX:
1124 address->m_family = GSOCK_UNIX;
1125 break;
1126#ifdef AF_INET6
1127 case AF_INET6:
1128 address->m_family = GSOCK_INET6;
1129 break;
1130#endif
1131 default:
1132 {
1133 address->m_error = GSOCK_INVOP;
1134 return GSOCK_INVOP;
1135 }
1136 }
1137
1138 if (address->m_addr)
1139 free(address->m_addr);
1140
1141 address->m_len = len;
1142 address->m_addr = (struct sockaddr *) malloc(len);
1143
1144 if (address->m_addr == NULL)
1145 {
1146 address->m_error = GSOCK_MEMERR;
1147 return GSOCK_MEMERR;
1148 }
1149 memcpy(address->m_addr, addr, len);
1150
1151 return GSOCK_NOERROR;
1152}
1153
1154GSocketError _GAddress_translate_to(GAddress *address,
1155 struct sockaddr **addr, int *len)
1156{
1157 if (!address->m_addr)
1158 {
1159 address->m_error = GSOCK_INVADDR;
1160 return GSOCK_INVADDR;
1161 }
1162
1163 *len = address->m_len;
1164 *addr = (struct sockaddr *) malloc(address->m_len);
1165 if (*addr == NULL)
1166 {
1167 address->m_error = GSOCK_MEMERR;
1168 return GSOCK_MEMERR;
1169 }
1170
1171 memcpy(*addr, address->m_addr, address->m_len);
1172 return GSOCK_NOERROR;
1173}
1174
1175/*
1176 * -------------------------------------------------------------------------
1177 * Internet address family
1178 * -------------------------------------------------------------------------
1179 */
1180
1181GSocketError _GAddress_Init_INET(GAddress *address)
1182{
9bf10d6b 1183 address->m_len = sizeof(struct sockaddr_in);
9bbd7ba3
GRG
1184 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1185 if (address->m_addr == NULL)
1186 {
1187 address->m_error = GSOCK_MEMERR;
1188 return GSOCK_MEMERR;
1189 }
1190
9bbd7ba3
GRG
1191 address->m_family = GSOCK_INET;
1192 address->m_realfamily = PF_INET;
1193 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
9bf10d6b 1194 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
9bbd7ba3
GRG
1195
1196 return GSOCK_NOERROR;
1197}
1198
1199GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1200{
1201 struct hostent *he;
1202 struct in_addr *addr;
1203
1204 assert(address != NULL);
1205
032d5581 1206 CHECK_ADDRESS(address, INET);
9bbd7ba3
GRG
1207
1208 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1209
1210 addr->s_addr = inet_addr(hostname);
b661e675 1211
9bbd7ba3
GRG
1212 /* If it is a numeric host name, convert it now */
1213 if (addr->s_addr == INADDR_NONE)
1214 {
1215 struct in_addr *array_addr;
1216
1217 /* It is a real name, we solve it */
1218 if ((he = gethostbyname(hostname)) == NULL)
1219 {
9bf10d6b 1220 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
9bbd7ba3
GRG
1221 address->m_error = GSOCK_NOHOST;
1222 return GSOCK_NOHOST;
1223 }
1224 array_addr = (struct in_addr *) *(he->h_addr_list);
1225 addr->s_addr = array_addr[0].s_addr;
1226 }
1227 return GSOCK_NOERROR;
1228}
1229
9bf10d6b
GRG
1230GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1231{
1232 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1233}
1234
9bbd7ba3
GRG
1235GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1236 unsigned long hostaddr)
1237{
1238 struct in_addr *addr;
1239
1240 assert(address != NULL);
1241
032d5581 1242 CHECK_ADDRESS(address, INET);
9bbd7ba3
GRG
1243
1244 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1245 addr->s_addr = hostaddr;
1246
1247 return GSOCK_NOERROR;
1248}
1249
1250GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1251 const char *protocol)
1252{
1253 struct servent *se;
1254 struct sockaddr_in *addr;
1255
1256 assert(address != NULL);
032d5581 1257 CHECK_ADDRESS(address, INET);
9bbd7ba3
GRG
1258
1259 if (!port)
1260 {
1261 address->m_error = GSOCK_INVPORT;
9bf10d6b 1262 return GSOCK_INVPORT;
9bbd7ba3 1263 }
b661e675 1264
9bbd7ba3
GRG
1265 se = getservbyname(port, protocol);
1266 if (!se)
1267 {
1268 if (isdigit(port[0]))
1269 {
1270 int port_int;
1271
1272 port_int = atoi(port);
1273 addr = (struct sockaddr_in *)address->m_addr;
aa3981f2 1274 addr->sin_port = htons((u_short) port_int);
9bbd7ba3
GRG
1275 return GSOCK_NOERROR;
1276 }
1277
1278 address->m_error = GSOCK_INVPORT;
1279 return GSOCK_INVPORT;
1280 }
1281
1282 addr = (struct sockaddr_in *)address->m_addr;
1283 addr->sin_port = se->s_port;
1284
1285 return GSOCK_NOERROR;
1286}
1287
1288GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1289{
1290 struct sockaddr_in *addr;
1291
1292 assert(address != NULL);
032d5581 1293 CHECK_ADDRESS(address, INET);
b661e675 1294
9bbd7ba3
GRG
1295 addr = (struct sockaddr_in *)address->m_addr;
1296 addr->sin_port = htons(port);
1297
1298 return GSOCK_NOERROR;
1299}
1300
1301GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1302{
1303 struct hostent *he;
1304 char *addr_buf;
1305 struct sockaddr_in *addr;
1306
b661e675 1307 assert(address != NULL);
032d5581 1308 CHECK_ADDRESS(address, INET);
9bbd7ba3
GRG
1309
1310 addr = (struct sockaddr_in *)address->m_addr;
1311 addr_buf = (char *)&(addr->sin_addr);
1312
1313 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1314 if (he == NULL)
1315 {
1316 address->m_error = GSOCK_NOHOST;
1317 return GSOCK_NOHOST;
1318 }
1319
1320 strncpy(hostname, he->h_name, sbuf);
1321
1322 return GSOCK_NOERROR;
1323}
1324
1325unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1326{
1327 struct sockaddr_in *addr;
1328
b661e675 1329 assert(address != NULL);
032d5581 1330 CHECK_ADDRESS_RETVAL(address, INET, 0);
9bbd7ba3
GRG
1331
1332 addr = (struct sockaddr_in *)address->m_addr;
1333
1334 return addr->sin_addr.s_addr;
1335}
1336
1337unsigned short GAddress_INET_GetPort(GAddress *address)
1338{
1339 struct sockaddr_in *addr;
1340
b661e675 1341 assert(address != NULL);
032d5581 1342 CHECK_ADDRESS_RETVAL(address, INET, 0);
9bbd7ba3
GRG
1343
1344 addr = (struct sockaddr_in *)address->m_addr;
1345 return ntohs(addr->sin_port);
1346}
1347
1348/*
1349 * -------------------------------------------------------------------------
1350 * Unix address family
1351 * -------------------------------------------------------------------------
1352 */
1353
1354GSocketError _GAddress_Init_UNIX(GAddress *address)
1355{
1356 assert (address != NULL);
1357 address->m_error = GSOCK_INVADDR;
1358 return GSOCK_INVADDR;
1359}
1360
1361GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1362{
1363 assert (address != NULL);
1364 address->m_error = GSOCK_INVADDR;
1365 return GSOCK_INVADDR;
1366}
1367
1368GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1369{
1370 assert (address != NULL);
1371 address->m_error = GSOCK_INVADDR;
1372 return GSOCK_INVADDR;
1373}
1374
a497618a 1375#else /* !wxUSE_SOCKETS */
9bbd7ba3 1376
33ac7e6f 1377/*
9bf10d6b 1378 * Translation unit shouldn't be empty, so include this typedef to make the
a497618a
VZ
1379 * compiler (VC++ 6.0, for example) happy
1380 */
3a922bb4 1381typedef void (*wxDummy)();
9bbd7ba3 1382
a497618a 1383#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
007c77ab
RL
1384
1385// vi:sts=4:sw=4:et