]> git.saurik.com Git - wxWidgets.git/blame - src/os2/gsocket.c
Visualage fixes for Stefan's socket implementations and true to TRUE in db.cpp
[wxWidgets.git] / src / os2 / gsocket.c
CommitLineData
fb9010ed
DW
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
3958ae62
SN
4 * Authors: Guilhem Lavaux,
5 * Guillermo Rodriguez Garcia <guille@iies.es> (maintainer)
fb9010ed
DW
6 * Purpose: GSocket main Unix-style file
7 * CVSID: $Id$
8 * -------------------------------------------------------------------------
9 */
10
3958ae62
SN
11/*
12 * PLEASE don't put C++ comments here - this is a C source file.
13 */
14
15#ifndef __GSOCKET_STANDALONE__
fb9010ed 16#include "wx/setup.h"
3958ae62
SN
17#endif
18
bfdc8d18
SN
19#ifndef __EMX__
20/* I don't see, why this include is needed, but it seems to be necessary
21 sometimes. For EMX, including C++ headers into plain C source breaks
22 compilation, so don't do it there. */
1cd04aa2 23#include "wx/defs.h"
bfdc8d18 24#endif
fb9010ed 25
3958ae62 26#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
fb9010ed 27
9dea36ef 28#define BSD_SELECT /* use Berkley Sockets select */
fb9010ed
DW
29
30#include <assert.h>
fb9010ed 31#include <sys\types.h>
610c9851
SN
32#ifdef __EMX__
33#include <sys/time.h>
34#include <netinet/in.h>
35#include <arpa/inet.h>
36#include <netdb.h>
37#include <errno.h>
3958ae62
SN
38#include <unistd.h>
39#include <sys/un.h>
610c9851
SN
40#define HAVE_INET_ADDR
41#else
fb9010ed
DW
42#include <utils.h>
43#include <sys\time.h>
5fd2b2c6 44#include <types.h>
fb9010ed
DW
45#include <in.h>
46#include <netdb.h>
47#include <nerrno.h>
610c9851 48#endif
9ac6ff7b 49#if defined(__VISAGECPP__) && __IBMCPP__ < 400
5fd2b2c6 50#include <machine\endian.h>
9ac6ff7b
DW
51#include <socket.h>
52#include <ioctl.h>
53#include <select.h>
5fd2b2c6 54#include <unistd.h>
9ac6ff7b
DW
55#else
56#include <sys\socket.h>
57#include <sys\ioctl.h>
476607a7 58#include <sys\select.h>
521ccc1b
SN
59#ifdef __EMX__
60#define soclose(a) close(a)
61#else
9dea36ef
DW
62#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
63int _System bsdselect(int,
64 struct fd_set *,
65 struct fd_set *,
66 struct fd_set *,
67 struct timeval *);
68int _System soclose(int);
9ac6ff7b 69#endif
610c9851 70#endif
fb9010ed
DW
71
72#include <string.h>
73#include <stdio.h>
3958ae62 74#if (defined(__VISAGECPP__) && __IBMCPP__ < 400) || defined(__EMX__)
e15bbde0
DW
75# ifdef min
76# undef min
77# endif
78# include <stdlib.h>
79#endif
fb9010ed
DW
80#include <stddef.h>
81#include <ctype.h>
82
83#include <signal.h>
84
fb9010ed
DW
85#ifndef SOCKLEN_T
86
87#ifdef __GLIBC__
88# if __GLIBC__ == 2
89# define SOCKLEN_T socklen_t
90# endif
91#else
92# define SOCKLEN_T int
93#endif
94
95#endif
96
3958ae62
SN
97/*
98 * MSW defines this, Unices don't.
99 */
100#ifndef INVALID_SOCKET
101#define INVALID_SOCKET -1
102#endif
103
104/*
105 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
106 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
107 */
108#ifndef INADDR_NONE
109#define INADDR_NONE INADDR_BROADCAST
110#endif
111
112#define MASK_SIGNAL() \
113{ \
114 void (*old_handler)(int); \
115 \
116 old_handler = signal(SIGPIPE, SIG_IGN);
117
118#define UNMASK_SIGNAL() \
119 signal(SIGPIPE, old_handler); \
120}
121
122#ifndef __GSOCKET_STANDALONE__
123# include "wx/unix/gsockunx.h"
124# include "wx/gsocket.h"
125#else
126# include "gsockunx.h"
127# include "gsocket.h"
128#endif /* __GSOCKET_STANDALONE__ */
129
130/* redefine some GUI-only functions to do nothing in console mode */
131#if defined(wxUSE_GUI) && !wxUSE_GUI
132# define _GSocket_GUI_Init(socket) (1)
133# define _GSocket_GUI_Destroy(socket)
134# define _GSocket_Enable_Events(socket)
135# define _GSocket_Disable_Events(socket)
136# define _GSocket_Install_Callback(socket, event)
137# define _GSocket_Uninstall_Callback(socket, event)
138#endif /* wxUSE_GUI */
139
140/* debugging helpers */
141#define __GSOCKET_DEBUG__
142#ifdef __GSOCKET_DEBUG__
143# define GSocket_Debug(args) printf args
144#else
145# define GSocket_Debug(args)
146#endif /* __GSOCKET_DEBUG__ */
147
fb9010ed
DW
148/* Global initialisers */
149
3958ae62 150int GSocket_Init(void)
fb9010ed 151{
27f37ae5 152 return 1;
fb9010ed
DW
153}
154
3958ae62 155void GSocket_Cleanup(void)
fb9010ed
DW
156{
157}
158
3958ae62 159/* Constructors / Destructors for GSocket */
fb9010ed 160
3958ae62 161GSocket *GSocket_new(void)
fb9010ed 162{
3958ae62 163 int i, success;
fb9010ed
DW
164 GSocket *socket;
165
166 socket = (GSocket *)malloc(sizeof(GSocket));
167
168 if (socket == NULL)
169 return NULL;
170
3958ae62 171 socket->m_fd = INVALID_SOCKET;
fb9010ed
DW
172 for (i=0;i<GSOCK_MAX_EVENT;i++)
173 {
174 socket->m_cbacks[i] = NULL;
175 }
176 socket->m_detected = 0;
177 socket->m_local = NULL;
178 socket->m_peer = NULL;
179 socket->m_error = GSOCK_NOERROR;
3958ae62
SN
180 socket->m_server = FALSE;
181 socket->m_stream = TRUE;
fb9010ed 182 socket->m_gui_dependent = NULL;
3958ae62 183 socket->m_non_blocking = FALSE;
fb9010ed
DW
184 socket->m_timeout = 10*60*1000;
185 /* 10 minutes * 60 sec * 1000 millisec */
3958ae62
SN
186 socket->m_establishing = FALSE;
187
188 /* Per-socket GUI-specific initialization */
189 success = _GSocket_GUI_Init(socket);
190 if (!success)
191 {
192 free(socket);
193 return NULL;
194 }
fb9010ed 195
fb9010ed
DW
196 return socket;
197}
198
199void GSocket_destroy(GSocket *socket)
200{
201 assert(socket != NULL);
202
3958ae62
SN
203 /* Check that the socket is really shutdowned */
204 if (socket->m_fd != INVALID_SOCKET)
fb9010ed
DW
205 GSocket_Shutdown(socket);
206
3958ae62
SN
207 /* Per-socket GUI-specific cleanup */
208 _GSocket_GUI_Destroy(socket);
209
210 /* Destroy private addresses */
fb9010ed
DW
211 if (socket->m_local)
212 GAddress_destroy(socket->m_local);
213
214 if (socket->m_peer)
215 GAddress_destroy(socket->m_peer);
216
3958ae62 217 /* Destroy the socket itself */
fb9010ed
DW
218 free(socket);
219}
220
3958ae62
SN
221/* GSocket_Shutdown:
222 * Disallow further read/write operations on this socket, close
223 * the fd and disable all callbacks.
224 */
fb9010ed
DW
225void GSocket_Shutdown(GSocket *socket)
226{
227 int evt;
228
229 assert(socket != NULL);
230
3958ae62
SN
231 /* If socket has been created, shutdown it */
232 if (socket->m_fd != INVALID_SOCKET)
fb9010ed
DW
233 {
234 shutdown(socket->m_fd, 2);
235 soclose(socket->m_fd);
3958ae62 236 socket->m_fd = INVALID_SOCKET;
fb9010ed
DW
237 }
238
3958ae62 239 /* Disable GUI callbacks */
fb9010ed
DW
240 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
241 socket->m_cbacks[evt] = NULL;
242
3958ae62
SN
243 socket->m_detected = GSOCK_LOST_FLAG;
244 _GSocket_Disable_Events(socket);
fb9010ed
DW
245}
246
247/* Address handling */
248
3958ae62
SN
249/* GSocket_SetLocal:
250 * GSocket_GetLocal:
251 * GSocket_SetPeer:
252 * GSocket_GetPeer:
253 * Set or get the local or peer address for this socket. The 'set'
254 * functions return GSOCK_NOERROR on success, an error code otherwise.
255 * The 'get' functions return a pointer to a GAddress object on success,
256 * or NULL otherwise, in which case they set the error code of the
257 * corresponding GSocket.
258 *
259 * Error codes:
260 * GSOCK_INVSOCK - the socket is not valid.
261 * GSOCK_INVADDR - the address is not valid.
262 */
fb9010ed
DW
263GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
264{
265 assert(socket != NULL);
266
3958ae62
SN
267 /* the socket must be initialized, or it must be a server */
268 if ((socket->m_fd != INVALID_SOCKET && !socket->m_server))
269 {
fb9010ed
DW
270 socket->m_error = GSOCK_INVSOCK;
271 return GSOCK_INVSOCK;
272 }
273
3958ae62
SN
274 /* check address */
275 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
276 {
fb9010ed
DW
277 socket->m_error = GSOCK_INVADDR;
278 return GSOCK_INVADDR;
279 }
280
281 if (socket->m_local)
282 GAddress_destroy(socket->m_local);
283
284 socket->m_local = GAddress_copy(address);
285
286 return GSOCK_NOERROR;
287}
288
289GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
290{
291 assert(socket != NULL);
292
3958ae62
SN
293 /* check address */
294 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
295 {
fb9010ed
DW
296 socket->m_error = GSOCK_INVADDR;
297 return GSOCK_INVADDR;
298 }
299
300 if (socket->m_peer)
301 GAddress_destroy(socket->m_peer);
302
303 socket->m_peer = GAddress_copy(address);
304
305 return GSOCK_NOERROR;
306}
307
308GAddress *GSocket_GetLocal(GSocket *socket)
309{
310 GAddress *address;
311 struct sockaddr addr;
3958ae62 312 SOCKLEN_T size = sizeof(addr);
fb9010ed
DW
313 GSocketError err;
314
315 assert(socket != NULL);
316
3958ae62 317 /* try to get it from the m_local var first */
fb9010ed
DW
318 if (socket->m_local)
319 return GAddress_copy(socket->m_local);
320
3958ae62
SN
321 /* else, if the socket is initialized, try getsockname */
322 if (socket->m_fd == INVALID_SOCKET)
323 {
fb9010ed
DW
324 socket->m_error = GSOCK_INVSOCK;
325 return NULL;
326 }
327
3958ae62
SN
328 if (getsockname(socket->m_fd, &addr, (SOCKLEN_T *) &size) < 0)
329 {
fb9010ed
DW
330 socket->m_error = GSOCK_IOERR;
331 return NULL;
332 }
333
3958ae62 334 /* got a valid address from getsockname, create a GAddress object */
fb9010ed 335 address = GAddress_new();
3958ae62
SN
336 if (address == NULL)
337 {
fb9010ed
DW
338 socket->m_error = GSOCK_MEMERR;
339 return NULL;
340 }
3958ae62
SN
341
342 err = _GAddress_translate_from(address, &addr, size);
343 if (err != GSOCK_NOERROR)
344 {
fb9010ed 345 GAddress_destroy(address);
3958ae62 346 socket->m_error = err;
fb9010ed
DW
347 return NULL;
348 }
349
350 return address;
351}
352
353GAddress *GSocket_GetPeer(GSocket *socket)
354{
355 assert(socket != NULL);
356
3958ae62 357 /* try to get it from the m_peer var */
fb9010ed
DW
358 if (socket->m_peer)
359 return GAddress_copy(socket->m_peer);
360
361 return NULL;
362}
363
364/* Server specific parts */
365
366/* GSocket_SetServer:
3958ae62
SN
367 * Sets up this socket as a server. The local address must have been
368 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
369 * Returns GSOCK_NOERROR on success, one of the following otherwise:
370 *
371 * Error codes:
372 * GSOCK_INVSOCK - the socket is in use.
373 * GSOCK_INVADDR - the local address has not been set.
374 * GSOCK_IOERR - low-level error.
fb9010ed
DW
375 */
376GSocketError GSocket_SetServer(GSocket *sck)
377{
fb9010ed
DW
378 int arg = 1;
379
380 assert(sck != NULL);
381
3958ae62
SN
382 /* must not be in use */
383 if (sck->m_fd != INVALID_SOCKET)
384 {
fb9010ed
DW
385 sck->m_error = GSOCK_INVSOCK;
386 return GSOCK_INVSOCK;
387 }
388
3958ae62
SN
389 /* the local addr must have been set */
390 if (!sck->m_local)
391 {
fb9010ed
DW
392 sck->m_error = GSOCK_INVADDR;
393 return GSOCK_INVADDR;
394 }
395
3958ae62
SN
396 /* Initialize all fields */
397 sck->m_stream = TRUE;
398 sck->m_server = TRUE;
399 sck->m_oriented = TRUE;
fb9010ed
DW
400
401 /* Create the socket */
402 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
403
3958ae62
SN
404 if (sck->m_fd == INVALID_SOCKET)
405 {
fb9010ed
DW
406 sck->m_error = GSOCK_IOERR;
407 return GSOCK_IOERR;
408 }
409
3958ae62
SN
410 ioctl(sck->m_fd, FIONBIO, &arg);
411 _GSocket_Enable_Events(sck);
412
413 /* Bind to the local address,
414 * retrieve the actual address bound,
415 * and listen up to 5 connections.
416 */
417 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
418 (getsockname(sck->m_fd,
419 sck->m_local->m_addr,
420 (SOCKLEN_T *) &sck->m_local->m_len) != 0) ||
421 (listen(sck->m_fd, 5) != 0))
422 {
fb9010ed 423 soclose(sck->m_fd);
3958ae62 424 sck->m_fd = INVALID_SOCKET;
fb9010ed
DW
425 sck->m_error = GSOCK_IOERR;
426 return GSOCK_IOERR;
427 }
428
429 return GSOCK_NOERROR;
430}
431
432/* GSocket_WaitConnection:
3958ae62
SN
433 * Waits for an incoming client connection. Returns a pointer to
434 * a GSocket object, or NULL if there was an error, in which case
435 * the last error field will be updated for the calling GSocket.
436 *
437 * Error codes (set in the calling GSocket)
438 * GSOCK_INVSOCK - the socket is not valid or not a server.
439 * GSOCK_TIMEDOUT - timeout, no incoming connections.
440 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
441 * GSOCK_MEMERR - couldn't allocate memory.
442 * GSOCK_IOERR - low-level error.
fb9010ed
DW
443 */
444GSocket *GSocket_WaitConnection(GSocket *socket)
445{
3958ae62
SN
446 struct sockaddr from;
447 SOCKLEN_T fromlen = sizeof(from);
fb9010ed 448 GSocket *connection;
3958ae62 449 GSocketError err;
fb9010ed
DW
450 int arg = 1;
451
452 assert(socket != NULL);
453
454 /* Reenable CONNECTION events */
455 _GSocket_Enable(socket, GSOCK_CONNECTION);
456
457 /* If the socket has already been created, we exit immediately */
3958ae62 458 if (socket->m_fd == INVALID_SOCKET || !socket->m_server)
fb9010ed
DW
459 {
460 socket->m_error = GSOCK_INVSOCK;
461 return NULL;
462 }
463
464 /* Create a GSocket object for the new connection */
465 connection = GSocket_new();
3958ae62 466
fb9010ed
DW
467 if (!connection)
468 {
3958ae62 469 socket->m_error = GSOCK_MEMERR;
fb9010ed
DW
470 return NULL;
471 }
472
3958ae62 473 /* Wait for a connection (with timeout) */
fb9010ed
DW
474 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
475 {
476 GSocket_destroy(connection);
477 /* socket->m_error set by _GSocket_Input_Timeout */
478 return NULL;
479 }
480
3958ae62 481 connection->m_fd = accept(socket->m_fd, &from, (SOCKLEN_T *) &fromlen);
fb9010ed 482
3958ae62 483 if (connection->m_fd == INVALID_SOCKET)
fb9010ed
DW
484 {
485 if (errno == EWOULDBLOCK)
486 socket->m_error = GSOCK_WOULDBLOCK;
487 else
488 socket->m_error = GSOCK_IOERR;
489
490 GSocket_destroy(connection);
491 return NULL;
492 }
493
494 /* Initialize all fields */
3958ae62
SN
495 connection->m_server = FALSE;
496 connection->m_stream = TRUE;
497 connection->m_oriented = TRUE;
fb9010ed 498
3958ae62
SN
499 /* Setup the peer address field */
500 connection->m_peer = GAddress_new();
501 if (!connection->m_peer)
502 {
503 GSocket_destroy(connection);
504 socket->m_error = GSOCK_MEMERR;
505 return NULL;
fb9010ed 506 }
3958ae62
SN
507 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
508 if (err != GSOCK_NOERROR)
509 {
510 GAddress_destroy(connection->m_peer);
511 GSocket_destroy(connection);
512 socket->m_error = err;
513 return NULL;
fb9010ed
DW
514 }
515
3958ae62
SN
516 ioctl(connection->m_fd, FIONBIO, &arg);
517 _GSocket_Enable_Events(connection);
fb9010ed 518
3958ae62 519 return connection;
fb9010ed
DW
520}
521
522/* Client specific parts */
523
524/* GSocket_Connect:
3958ae62
SN
525 * For stream (connection oriented) sockets, GSocket_Connect() tries
526 * to establish a client connection to a server using the peer address
527 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
528 * connection has been succesfully established, or one of the error
529 * codes listed below. Note that for nonblocking sockets, a return
530 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
531 * request can be completed later; you should use GSocket_Select()
532 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
533 * corresponding asynchronous events.
534 *
535 * For datagram (non connection oriented) sockets, GSocket_Connect()
536 * just sets the peer address established with GSocket_SetPeer() as
537 * default destination.
538 *
539 * Error codes:
540 * GSOCK_INVSOCK - the socket is in use or not valid.
541 * GSOCK_INVADDR - the peer address has not been established.
542 * GSOCK_TIMEDOUT - timeout, the connection failed.
543 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
544 * GSOCK_MEMERR - couldn't allocate memory.
545 * GSOCK_IOERR - low-level error.
fb9010ed
DW
546 */
547GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
548{
3958ae62 549 int err, ret;
fb9010ed
DW
550 int arg = 1;
551
552 assert(sck != NULL);
553
554 /* Enable CONNECTION events (needed for nonblocking connections) */
555 _GSocket_Enable(sck, GSOCK_CONNECTION);
556
3958ae62 557 if (sck->m_fd != INVALID_SOCKET)
fb9010ed
DW
558 {
559 sck->m_error = GSOCK_INVSOCK;
560 return GSOCK_INVSOCK;
561 }
562
563 if (!sck->m_peer)
564 {
565 sck->m_error = GSOCK_INVADDR;
566 return GSOCK_INVADDR;
567 }
568
3958ae62 569 /* Streamed or dgram socket? */
fb9010ed 570 sck->m_stream = (stream == GSOCK_STREAMED);
3958ae62
SN
571 sck->m_oriented = TRUE;
572 sck->m_server = FALSE;
573 sck->m_establishing = FALSE;
fb9010ed
DW
574
575 /* Create the socket */
3958ae62
SN
576 sck->m_fd = socket(sck->m_peer->m_realfamily,
577 sck->m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
fb9010ed 578
3958ae62
SN
579 if (sck->m_fd == INVALID_SOCKET)
580 {
fb9010ed
DW
581 sck->m_error = GSOCK_IOERR;
582 return GSOCK_IOERR;
583 }
584
3958ae62
SN
585 ioctl(sck->m_fd, FIONBIO, &arg);
586 _GSocket_Enable_Events(sck);
fb9010ed 587
3958ae62 588 /* Connect it to the peer address, with a timeout (see below) */
fb9010ed
DW
589 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
590
3958ae62
SN
591 printf("connect on %d to %X (%d) returned %d, errno = %d\n",
592 sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len, ret, errno);
fb9010ed
DW
593 if (ret == -1)
594 {
595 err = errno;
596
597 /* If connect failed with EINPROGRESS and the GSocket object
598 * is in blocking mode, we select() for the specified timeout
599 * checking for writability to see if the connection request
600 * completes.
601 */
602 if ((err == EINPROGRESS) && (!sck->m_non_blocking))
603 {
604 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
605 {
606 soclose(sck->m_fd);
3958ae62 607 sck->m_fd = INVALID_SOCKET;
fb9010ed 608 /* sck->m_error is set in _GSocket_Output_Timeout */
fb9010ed
DW
609 return GSOCK_TIMEDOUT;
610 }
611 else
612 {
3958ae62
SN
613 int error;
614 SOCKLEN_T len = sizeof(error);
615
616 getsockopt(sck->m_fd, SOL_SOCKET, SO_ERROR, (void*) &error, &len);
617
618 if (!error)
619 return GSOCK_NOERROR;
fb9010ed
DW
620 }
621 }
622
623 /* If connect failed with EINPROGRESS and the GSocket object
624 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
625 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
626 * this way if the connection completes, a GSOCK_CONNECTION
627 * event will be generated, if enabled.
628 */
629 if ((err == EINPROGRESS) && (sck->m_non_blocking))
630 {
3958ae62 631 sck->m_establishing = TRUE;
fb9010ed 632 sck->m_error = GSOCK_WOULDBLOCK;
fb9010ed
DW
633 return GSOCK_WOULDBLOCK;
634 }
635
636 /* If connect failed with an error other than EINPROGRESS,
637 * then the call to GSocket_Connect has failed.
638 */
639 soclose(sck->m_fd);
3958ae62 640 sck->m_fd = INVALID_SOCKET;
fb9010ed 641 sck->m_error = GSOCK_IOERR;
3958ae62
SN
642 return GSOCK_IOERR;
643 }
fb9010ed 644
3958ae62
SN
645 return GSOCK_NOERROR;
646}
647
648/* Datagram sockets */
649
650/* GSocket_SetNonOriented:
651 * Sets up this socket as a non-connection oriented (datagram) socket.
652 * Before using this function, the local address must have been set
653 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
654 * on success, or one of the following otherwise.
655 *
656 * Error codes:
657 * GSOCK_INVSOCK - the socket is in use.
658 * GSOCK_INVADDR - the local address has not been set.
659 * GSOCK_IOERR - low-level error.
660 */
661GSocketError GSocket_SetNonOriented(GSocket *sck)
662{
663 int arg = 1;
664
665 assert(sck != NULL);
666
667 if (sck->m_fd != INVALID_SOCKET)
668 {
669 sck->m_error = GSOCK_INVSOCK;
670 return GSOCK_INVSOCK;
671 }
672
673 if (!sck->m_local)
674 {
675 sck->m_error = GSOCK_INVADDR;
676 return GSOCK_INVADDR;
677 }
678
679 /* Initialize all fields */
680 sck->m_stream = FALSE;
681 sck->m_server = FALSE;
682 sck->m_oriented = FALSE;
683
684 /* Create the socket */
685 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
686
687 if (sck->m_fd == INVALID_SOCKET)
688 {
689 sck->m_error = GSOCK_IOERR;
690 return GSOCK_IOERR;
691 }
692
693 ioctl(sck->m_fd, FIONBIO, &arg);
694 _GSocket_Enable_Events(sck);
695
696 /* Bind to the local address,
697 * and retrieve the actual address bound.
698 */
699 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
700 (getsockname(sck->m_fd,
701 sck->m_local->m_addr,
702 (SOCKLEN_T *) &sck->m_local->m_len) != 0))
703 {
704 soclose(sck->m_fd);
705 sck->m_fd = INVALID_SOCKET;
706 sck->m_error = GSOCK_IOERR;
fb9010ed
DW
707 return GSOCK_IOERR;
708 }
709
fb9010ed
DW
710 return GSOCK_NOERROR;
711}
712
713/* Generic IO */
714
715/* Like recv(), send(), ... */
716int GSocket_Read(GSocket *socket, char *buffer, int size)
717{
718 int ret;
719
720 assert(socket != NULL);
721
722 /* Reenable INPUT events */
723 _GSocket_Enable(socket, GSOCK_INPUT);
724
3958ae62 725 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
fb9010ed
DW
726 {
727 socket->m_error = GSOCK_INVSOCK;
728 return -1;
729 }
730
3958ae62 731 /* If the socket is blocking, wait for data (with a timeout) */
fb9010ed
DW
732 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
733 return -1;
734
3958ae62 735 /* Read the data */
fb9010ed
DW
736 if (socket->m_stream)
737 ret = _GSocket_Recv_Stream(socket, buffer, size);
738 else
739 ret = _GSocket_Recv_Dgram(socket, buffer, size);
3958ae62 740
fb9010ed
DW
741 if (ret == -1)
742 {
743 if (errno == EWOULDBLOCK)
744 socket->m_error = GSOCK_WOULDBLOCK;
745 else
746 socket->m_error = GSOCK_IOERR;
747 }
3958ae62 748
fb9010ed
DW
749 return ret;
750}
751
3958ae62
SN
752int GSocket_Write(GSocket *socket, const char *buffer, int size)
753{
fb9010ed
DW
754 int ret;
755
756 assert(socket != NULL);
3958ae62
SN
757
758 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
fb9010ed 759
3958ae62 760 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
fb9010ed
DW
761 {
762 socket->m_error = GSOCK_INVSOCK;
763 return -1;
764 }
765
3958ae62
SN
766 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
767
768 /* If the socket is blocking, wait for writability (with a timeout) */
fb9010ed
DW
769 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
770 return -1;
771
3958ae62
SN
772 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
773
774 /* Write the data */
fb9010ed
DW
775 if (socket->m_stream)
776 ret = _GSocket_Send_Stream(socket, buffer, size);
777 else
778 ret = _GSocket_Send_Dgram(socket, buffer, size);
3958ae62
SN
779
780 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
fb9010ed
DW
781
782 if (ret == -1)
783 {
784 if (errno == EWOULDBLOCK)
3958ae62 785 {
fb9010ed 786 socket->m_error = GSOCK_WOULDBLOCK;
3958ae62
SN
787 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
788 }
fb9010ed 789 else
3958ae62 790 {
fb9010ed 791 socket->m_error = GSOCK_IOERR;
3958ae62
SN
792 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
793 }
fb9010ed
DW
794
795 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
796 * in MSW). Once the first OUTPUT event is received, users can assume
797 * that the socket is writable until a read operation fails. Only then
798 * will further OUTPUT events be posted.
799 */
800 _GSocket_Enable(socket, GSOCK_OUTPUT);
3958ae62 801 return -1;
fb9010ed 802 }
3958ae62
SN
803
804 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
fb9010ed
DW
805
806 return ret;
807}
808
809/* GSocket_Select:
810 * Polls the socket to determine its status. This function will
811 * check for the events specified in the 'flags' parameter, and
812 * it will return a mask indicating which operations can be
813 * performed. This function won't block, regardless of the
3958ae62 814 * mode (blocking | nonblocking) of the socket.
fb9010ed
DW
815 */
816GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
817{
3958ae62
SN
818#if defined(wxUSE_GUI) && !wxUSE_GUI
819
820 GSocketEventFlags result = 0;
821 fd_set readfds;
822 fd_set writefds;
823 fd_set exceptfds;
824 struct timeval tv;
825
826 /* Do not use a static struct, Linux can garble it */
827 tv.tv_sec = 0;
828 tv.tv_usec = 0;
829
fb9010ed
DW
830 assert(socket != NULL);
831
3958ae62
SN
832 FD_ZERO(&readfds);
833 FD_ZERO(&writefds);
834 FD_ZERO(&exceptfds);
835 FD_SET(socket->m_fd, &readfds);
836 FD_SET(socket->m_fd, &writefds);
837 FD_SET(socket->m_fd, &exceptfds);
838
839 /* Check known state first */
840 result |= (GSOCK_CONNECTION_FLAG & socket->m_detected & flags);
841 result |= (GSOCK_LOST_FLAG & socket->m_detected & flags);
842
843 /* Try select now */
844 if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
845 return result;
846
847 /* Check for readability */
848 if (FD_ISSET(socket->m_fd, &readfds))
849 {
850 char c;
851
852 if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
853 {
854 result |= (GSOCK_INPUT_FLAG & flags);
855 }
856 else
857 {
858 if (socket->m_server && socket->m_stream)
859 {
860 result |= (GSOCK_CONNECTION_FLAG & flags);
861 socket->m_detected |= GSOCK_CONNECTION_FLAG;
862 }
863 else
864 {
865 result |= (GSOCK_LOST_FLAG & flags);
866 socket->m_detected = GSOCK_LOST_FLAG;
867 }
868 }
869 }
870
871 /* Check for writability */
872 if (FD_ISSET(socket->m_fd, &writefds))
873 {
874 if (socket->m_establishing && !socket->m_server)
875 {
876 int error;
877 SOCKLEN_T len = sizeof(error);
878
879 socket->m_establishing = FALSE;
880
881 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
882
883 if (error)
884 {
885 result |= (GSOCK_LOST_FLAG & flags);
886 socket->m_detected = GSOCK_LOST_FLAG;
887 }
888 else
889 {
890 result |= (GSOCK_CONNECTION_FLAG & flags);
891 socket->m_detected |= GSOCK_CONNECTION_FLAG;
892 }
893 }
894 else
895 {
896 result |= (GSOCK_OUTPUT_FLAG & flags);
897 }
898 }
899
900 /* Check for exceptions and errors (is this useful in Unices?) */
901 if (FD_ISSET(socket->m_fd, &exceptfds))
902 {
903 result |= (GSOCK_LOST_FLAG & flags);
904 socket->m_establishing = FALSE;
905 socket->m_detected = GSOCK_LOST_FLAG;
906 }
907
908 return result;
909
910#else
911
912 assert(socket != NULL);
913 return flags & socket->m_detected;
914
915#endif /* !wxUSE_GUI */
fb9010ed
DW
916}
917
918/* Flags */
919
920/* GSocket_SetNonBlocking:
3958ae62
SN
921 * Sets the socket to non-blocking mode. All IO calls will return
922 * immediately.
fb9010ed 923 */
27f37ae5 924void GSocket_SetNonBlocking(GSocket *socket, int non_block)
fb9010ed
DW
925{
926 assert(socket != NULL);
927
3958ae62
SN
928 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
929
fb9010ed
DW
930 socket->m_non_blocking = non_block;
931}
932
933/* GSocket_SetTimeout:
3958ae62
SN
934 * Sets the timeout for blocking calls. Time is expressed in
935 * milliseconds.
fb9010ed
DW
936 */
937void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
938{
939 assert(socket != NULL);
940
941 socket->m_timeout = millisec;
942}
943
944/* GSocket_GetError:
3958ae62
SN
945 * Returns the last error occured for this socket. Note that successful
946 * operations do not clear this back to GSOCK_NOERROR, so use it only
947 * after an error.
fb9010ed
DW
948 */
949GSocketError GSocket_GetError(GSocket *socket)
950{
951 assert(socket != NULL);
952
953 return socket->m_error;
954}
955
956/* Callbacks */
957
3958ae62
SN
958/* GSOCK_INPUT:
959 * There is data to be read in the input buffer. If, after a read
960 * operation, there is still data available, the callback function will
961 * be called again.
962 * GSOCK_OUTPUT:
963 * The socket is available for writing. That is, the next write call
964 * won't block. This event is generated only once, when the connection is
965 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
966 * when the output buffer empties again. This means that the app should
967 * assume that it can write since the first OUTPUT event, and no more
968 * OUTPUT events will be generated unless an error occurs.
969 * GSOCK_CONNECTION:
970 * Connection succesfully established, for client sockets, or incoming
971 * client connection, for server sockets. Wait for this event (also watch
972 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
973 * GSOCK_LOST:
974 * The connection is lost (or a connection request failed); this could
975 * be due to a failure, or due to the peer closing it gracefully.
fb9010ed
DW
976 */
977
978/* GSocket_SetCallback:
979 * Enables the callbacks specified by 'flags'. Note that 'flags'
980 * may be a combination of flags OR'ed toghether, so the same
981 * callback function can be made to accept different events.
982 * The callback function must have the following prototype:
983 *
984 * void function(GSocket *socket, GSocketEvent event, char *cdata)
985 */
986void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
3958ae62 987 GSocketCallback callback, char *cdata)
fb9010ed
DW
988{
989 int count;
990
991 assert(socket != NULL);
992
993 for (count = 0; count < GSOCK_MAX_EVENT; count++)
994 {
995 if ((flags & (1 << count)) != 0)
996 {
3958ae62
SN
997 printf("Setting callback no %d for socket at %X to address %X,data %X\n",
998 count, socket, callback, cdata);
fb9010ed
DW
999 socket->m_cbacks[count] = callback;
1000 socket->m_data[count] = cdata;
1001 }
1002 }
1003}
1004
1005/* GSocket_UnsetCallback:
1006 * Disables all callbacks specified by 'flags', which may be a
1007 * combination of flags OR'ed toghether.
1008 */
1009void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
1010{
1011 int count;
1012
1013 assert(socket != NULL);
1014
1015 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1016 {
1017 if ((flags & (1 << count)) != 0)
1018 {
3958ae62
SN
1019 printf("Removing callback no %d for socket at %X",
1020 count, socket);
fb9010ed
DW
1021 socket->m_cbacks[count] = NULL;
1022 socket->m_data[count] = NULL;
1023 }
1024 }
1025}
1026
3958ae62 1027
fb9010ed
DW
1028#define CALL_CALLBACK(socket, event) { \
1029 _GSocket_Disable(socket, event); \
3958ae62
SN
1030 if (socket->m_cbacks[event]){ \
1031 printf("Call callback for event %d, socket %X: %X, %X\n", event, \
1032 socket, socket->m_cbacks[event], socket->m_data[event]); \
fb9010ed 1033 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
3958ae62 1034 } \
fb9010ed
DW
1035}
1036
1037
1038void _GSocket_Enable(GSocket *socket, GSocketEvent event)
1039{
1040 socket->m_detected &= ~(1 << event);
3958ae62 1041 _GSocket_Install_Callback(socket, event);
fb9010ed
DW
1042}
1043
1044void _GSocket_Disable(GSocket *socket, GSocketEvent event)
1045{
1046 socket->m_detected |= (1 << event);
3958ae62 1047 _GSocket_Uninstall_Callback(socket, event);
fb9010ed
DW
1048}
1049
1050/* _GSocket_Input_Timeout:
1051 * For blocking sockets, wait until data is available or
1052 * until timeout ellapses.
1053 */
1054GSocketError _GSocket_Input_Timeout(GSocket *socket)
1055{
1056 struct timeval tv;
1057 fd_set readfds;
3958ae62 1058 int ret;
fb9010ed 1059
3958ae62 1060 /* Linux select() will overwrite the struct on return */
fb9010ed
DW
1061 tv.tv_sec = (socket->m_timeout / 1000);
1062 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
1063
1064 if (!socket->m_non_blocking)
1065 {
1066 FD_ZERO(&readfds);
1067 FD_SET(socket->m_fd, &readfds);
3958ae62
SN
1068 ret = select(socket->m_fd + 1, &readfds, NULL, NULL, &tv);
1069 if (ret == 0)
fb9010ed 1070 {
3958ae62
SN
1071 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1072 socket->m_error = GSOCK_TIMEDOUT;
1073 return GSOCK_TIMEDOUT;
1074 }
1075 if (ret == -1)
1076 {
1077 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1078 if (errno == EBADF) GSocket_Debug(( "Invalid file descriptor\n" ));
1079 if (errno == EINTR) GSocket_Debug(( "A non blocked signal was caught\n" ));
1080 if (errno == EINVAL) GSocket_Debug(( "The highest number descriptor is negative\n" ));
1081 if (errno == ENOMEM) GSocket_Debug(( "Not enough memory\n" ));
fb9010ed
DW
1082 socket->m_error = GSOCK_TIMEDOUT;
1083 return GSOCK_TIMEDOUT;
1084 }
1085 }
1086 return GSOCK_NOERROR;
1087}
1088
1089/* _GSocket_Output_Timeout:
1090 * For blocking sockets, wait until data can be sent without
1091 * blocking or until timeout ellapses.
1092 */
1093GSocketError _GSocket_Output_Timeout(GSocket *socket)
1094{
1095 struct timeval tv;
1096 fd_set writefds;
3958ae62 1097 int ret;
fb9010ed 1098
3958ae62 1099 /* Linux select() will overwrite the struct on return */
fb9010ed
DW
1100 tv.tv_sec = (socket->m_timeout / 1000);
1101 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
1102
3958ae62
SN
1103 GSocket_Debug( ("m_non_blocking has: %d\n", (int)socket->m_non_blocking) );
1104
fb9010ed
DW
1105 if (!socket->m_non_blocking)
1106 {
1107 FD_ZERO(&writefds);
1108 FD_SET(socket->m_fd, &writefds);
3958ae62
SN
1109 ret = select(socket->m_fd + 1, NULL, &writefds, NULL, &tv);
1110 if (ret == 0)
fb9010ed 1111 {
3958ae62 1112 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
fb9010ed
DW
1113 socket->m_error = GSOCK_TIMEDOUT;
1114 return GSOCK_TIMEDOUT;
1115 }
3958ae62
SN
1116 if (ret == -1)
1117 {
1118 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1119 if (errno == EBADF) GSocket_Debug(( "Invalid file descriptor\n" ));
1120 if (errno == EINTR) GSocket_Debug(( "A non blocked signal was caught\n" ));
1121 if (errno == EINVAL) GSocket_Debug(( "The highest number descriptor is negative\n" ));
1122 if (errno == ENOMEM) GSocket_Debug(( "Not enough memory\n" ));
1123 socket->m_error = GSOCK_TIMEDOUT;
1124 return GSOCK_TIMEDOUT;
1125 }
1126 if ( ! FD_ISSET(socket->m_fd, &writefds) )
1127 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1128 else
1129 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1130 }
1131 else
1132 {
1133 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
fb9010ed 1134 }
3958ae62 1135
fb9010ed
DW
1136 return GSOCK_NOERROR;
1137}
1138
1139int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
1140{
3958ae62 1141 return recv(socket->m_fd, buffer, size, 0);
fb9010ed
DW
1142}
1143
1144int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
1145{
1146 struct sockaddr from;
3958ae62 1147 SOCKLEN_T fromlen = sizeof(from);
fb9010ed
DW
1148 int ret;
1149 GSocketError err;
1150
1151 fromlen = sizeof(from);
1152
3958ae62 1153 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, (SOCKLEN_T *) &fromlen);
fb9010ed
DW
1154
1155 if (ret == -1)
1156 return -1;
1157
1158 /* Translate a system address into a GSocket address */
1159 if (!socket->m_peer)
1160 {
1161 socket->m_peer = GAddress_new();
1162 if (!socket->m_peer)
1163 {
1164 socket->m_error = GSOCK_MEMERR;
1165 return -1;
1166 }
1167 }
1168 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
1169 if (err != GSOCK_NOERROR)
1170 {
1171 GAddress_destroy(socket->m_peer);
1172 socket->m_peer = NULL;
1173 socket->m_error = err;
1174 return -1;
1175 }
1176
1177 return ret;
1178}
1179
1180int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
1181{
1182 int ret;
fb9010ed 1183
3958ae62
SN
1184 MASK_SIGNAL();
1185 ret = send(socket->m_fd, buffer, size, 0);
1186 UNMASK_SIGNAL();
fb9010ed
DW
1187
1188 return ret;
1189}
1190
1191int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
1192{
1193 struct sockaddr *addr;
1194 int len, ret;
1195 GSocketError err;
1196
3958ae62
SN
1197 if (!socket->m_peer)
1198 {
fb9010ed
DW
1199 socket->m_error = GSOCK_INVADDR;
1200 return -1;
1201 }
1202
1203 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
3958ae62
SN
1204 if (err != GSOCK_NOERROR)
1205 {
fb9010ed
DW
1206 socket->m_error = err;
1207 return -1;
1208 }
1209
3958ae62
SN
1210 MASK_SIGNAL();
1211 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1212 UNMASK_SIGNAL();
fb9010ed
DW
1213
1214 /* Frees memory allocated from _GAddress_translate_to */
1215 free(addr);
1216
1217 return ret;
1218}
1219
1220void _GSocket_Detected_Read(GSocket *socket)
1221{
1222 char c;
fb9010ed 1223
3958ae62 1224 if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
fb9010ed 1225 {
3958ae62
SN
1226 CALL_CALLBACK(socket, GSOCK_INPUT);
1227 }
1228 else
1229 {
1230 if (socket->m_server && socket->m_stream)
fb9010ed
DW
1231 {
1232 CALL_CALLBACK(socket, GSOCK_CONNECTION);
fb9010ed
DW
1233 }
1234 else
1235 {
1236 CALL_CALLBACK(socket, GSOCK_LOST);
1237 }
1238 }
1239}
1240
1241void _GSocket_Detected_Write(GSocket *socket)
1242{
1243 if (socket->m_establishing && !socket->m_server)
1244 {
3958ae62
SN
1245 int error;
1246 SOCKLEN_T len = sizeof(error);
fb9010ed 1247
3958ae62 1248 socket->m_establishing = FALSE;
fb9010ed 1249
3958ae62 1250 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
fb9010ed
DW
1251
1252 if (error)
1253 {
1254 CALL_CALLBACK(socket, GSOCK_LOST);
1255 }
1256 else
1257 {
1258 CALL_CALLBACK(socket, GSOCK_CONNECTION);
1259 /* We have to fire this event by hand because CONNECTION (for clients)
1260 * and OUTPUT are internally the same and we just disabled CONNECTION
1261 * events with the above macro.
1262 */
1263 CALL_CALLBACK(socket, GSOCK_OUTPUT);
1264 }
1265 }
1266 else
1267 {
1268 CALL_CALLBACK(socket, GSOCK_OUTPUT);
1269 }
1270}
1271
1272/*
1273 * -------------------------------------------------------------------------
1274 * GAddress
1275 * -------------------------------------------------------------------------
1276 */
1277
3958ae62
SN
1278/* CHECK_ADDRESS verifies that the current address family is either
1279 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1280 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1281 * an appropiate error code.
1282 *
1283 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
fb9010ed 1284 */
3958ae62
SN
1285#define CHECK_ADDRESS(address, family) \
1286{ \
1287 if (address->m_family == GSOCK_NOFAMILY) \
1288 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1289 return address->m_error; \
1290 if (address->m_family != GSOCK_##family) \
1291 { \
1292 address->m_error = GSOCK_INVADDR; \
1293 return GSOCK_INVADDR; \
1294 } \
1295}
1296
1297#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1298{ \
1299 if (address->m_family == GSOCK_NOFAMILY) \
1300 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1301 return retval; \
1302 if (address->m_family != GSOCK_##family) \
1303 { \
1304 address->m_error = GSOCK_INVADDR; \
1305 return retval; \
1306 } \
fb9010ed
DW
1307}
1308
3958ae62
SN
1309
1310GAddress *GAddress_new(void)
fb9010ed
DW
1311{
1312 GAddress *address;
1313
3958ae62 1314 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
fb9010ed
DW
1315 return NULL;
1316
1317 address->m_family = GSOCK_NOFAMILY;
1318 address->m_addr = NULL;
1319 address->m_len = 0;
1320
1321 return address;
1322}
1323
1324GAddress *GAddress_copy(GAddress *address)
1325{
1326 GAddress *addr2;
1327
1328 assert(address != NULL);
1329
3958ae62 1330 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
fb9010ed
DW
1331 return NULL;
1332
1333 memcpy(addr2, address, sizeof(GAddress));
1334
3958ae62
SN
1335 if (address->m_addr)
1336 {
fb9010ed 1337 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
3958ae62
SN
1338 if (addr2->m_addr == NULL)
1339 {
fb9010ed
DW
1340 free(addr2);
1341 return NULL;
1342 }
1343 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1344 }
1345
1346 return addr2;
1347}
1348
1349void GAddress_destroy(GAddress *address)
1350{
1351 assert(address != NULL);
1352
3958ae62
SN
1353 if (address->m_addr)
1354 free(address->m_addr);
1355
1356/* free(address); */
fb9010ed
DW
1357}
1358
1359void GAddress_SetFamily(GAddress *address, GAddressType type)
1360{
1361 assert(address != NULL);
1362
1363 address->m_family = type;
1364}
1365
1366GAddressType GAddress_GetFamily(GAddress *address)
1367{
1368 assert(address != NULL);
1369
1370 return address->m_family;
1371}
1372
3958ae62
SN
1373GSocketError _GAddress_translate_from(GAddress *address,
1374 struct sockaddr *addr, int len)
1375{
fb9010ed 1376 address->m_realfamily = addr->sa_family;
3958ae62
SN
1377 switch (addr->sa_family)
1378 {
1379 case AF_INET:
1380 address->m_family = GSOCK_INET;
1381 break;
1382 case AF_UNIX:
1383 address->m_family = GSOCK_UNIX;
1384 break;
fb9010ed 1385#ifdef AF_INET6
3958ae62
SN
1386 case AF_INET6:
1387 address->m_family = GSOCK_INET6;
1388 break;
fb9010ed 1389#endif
3958ae62 1390 default:
fb9010ed 1391 {
3958ae62
SN
1392 address->m_error = GSOCK_INVOP;
1393 return GSOCK_INVOP;
fb9010ed
DW
1394 }
1395 }
1396
1397 if (address->m_addr)
1398 free(address->m_addr);
1399
1400 address->m_len = len;
1401 address->m_addr = (struct sockaddr *)malloc(len);
3958ae62
SN
1402
1403 if (address->m_addr == NULL)
1404 {
fb9010ed
DW
1405 address->m_error = GSOCK_MEMERR;
1406 return GSOCK_MEMERR;
1407 }
1408 memcpy(address->m_addr, addr, len);
1409
1410 return GSOCK_NOERROR;
1411}
1412
1413GSocketError _GAddress_translate_to(GAddress *address,
1414 struct sockaddr **addr, int *len)
1415{
3958ae62
SN
1416 if (!address->m_addr)
1417 {
fb9010ed
DW
1418 address->m_error = GSOCK_INVADDR;
1419 return GSOCK_INVADDR;
1420 }
1421
1422 *len = address->m_len;
1423 *addr = (struct sockaddr *)malloc(address->m_len);
3958ae62
SN
1424 if (*addr == NULL)
1425 {
fb9010ed
DW
1426 address->m_error = GSOCK_MEMERR;
1427 return GSOCK_MEMERR;
1428 }
1429
1430 memcpy(*addr, address->m_addr, address->m_len);
1431 return GSOCK_NOERROR;
1432}
1433
1434/*
1435 * -------------------------------------------------------------------------
1436 * Internet address family
1437 * -------------------------------------------------------------------------
1438 */
1439
1440GSocketError _GAddress_Init_INET(GAddress *address)
1441{
3958ae62
SN
1442 address->m_len = sizeof(struct sockaddr_in);
1443 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1444 if (address->m_addr == NULL)
1445 {
fb9010ed
DW
1446 address->m_error = GSOCK_MEMERR;
1447 return GSOCK_MEMERR;
1448 }
1449
fb9010ed
DW
1450 address->m_family = GSOCK_INET;
1451 address->m_realfamily = PF_INET;
1452 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
3958ae62 1453 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
fb9010ed
DW
1454
1455 return GSOCK_NOERROR;
1456}
1457
1458GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1459{
1460 struct hostent *he;
1461 struct in_addr *addr;
1462
1463 assert(address != NULL);
1464
3958ae62 1465 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1466
1467 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1468
1469 /* If it is a numeric host name, convert it now */
1470#if defined(HAVE_INET_ATON)
3958ae62
SN
1471 if (inet_aton(hostname, addr) == 0)
1472 {
fb9010ed 1473#elif defined(HAVE_INET_ADDR)
3958ae62
SN
1474 if ( (addr->s_addr = inet_addr(hostname)) == -1 )
1475 {
1476#else
1477 /* Use gethostbyname by default */
1478 if (1)
1479 {
fb9010ed
DW
1480#endif
1481 struct in_addr *array_addr;
1482
1483 /* It is a real name, we solve it */
3958ae62
SN
1484 if ((he = gethostbyname(hostname)) == NULL)
1485 {
1486 /* Reset to invalid address */
1487 addr->s_addr = INADDR_NONE;
fb9010ed
DW
1488 address->m_error = GSOCK_NOHOST;
1489 return GSOCK_NOHOST;
1490 }
1491 array_addr = (struct in_addr *) *(he->h_addr_list);
1492 addr->s_addr = array_addr[0].s_addr;
fb9010ed 1493 }
fb9010ed
DW
1494 return GSOCK_NOERROR;
1495}
1496
b662c135
SN
1497GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1498{
1499 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1500}
1501
fb9010ed
DW
1502GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1503 unsigned long hostaddr)
1504{
1505 struct in_addr *addr;
1506
1507 assert(address != NULL);
1508
3958ae62 1509 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1510
1511 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1512 addr->s_addr = hostaddr;
1513
1514 return GSOCK_NOERROR;
1515}
1516
1517GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1518 const char *protocol)
1519{
1520 struct servent *se;
1521 struct sockaddr_in *addr;
1522
1523 assert(address != NULL);
3958ae62 1524 CHECK_ADDRESS(address, INET);
fb9010ed 1525
3958ae62
SN
1526 if (!port)
1527 {
fb9010ed
DW
1528 address->m_error = GSOCK_INVPORT;
1529 return GSOCK_INVPORT;
1530 }
3958ae62
SN
1531
1532 se = getservbyname(port, protocol);
1533 if (!se)
1534 {
1535 if (isdigit((int)port[0]))
1536 {
fb9010ed
DW
1537 int port_int;
1538
1539 port_int = atoi(port);
1540 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1541 addr->sin_port = htons(port_int);
fb9010ed
DW
1542 return GSOCK_NOERROR;
1543 }
1544
1545 address->m_error = GSOCK_INVPORT;
1546 return GSOCK_INVPORT;
1547 }
1548
1549 addr = (struct sockaddr_in *)address->m_addr;
1550 addr->sin_port = se->s_port;
1551
1552 return GSOCK_NOERROR;
1553}
1554
1555GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1556{
1557 struct sockaddr_in *addr;
1558
1559 assert(address != NULL);
3958ae62
SN
1560 CHECK_ADDRESS(address, INET);
1561
fb9010ed 1562 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1563 addr->sin_port = htons(port);
fb9010ed
DW
1564
1565 return GSOCK_NOERROR;
1566}
1567
1568GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1569{
1570 struct hostent *he;
1571 char *addr_buf;
1572 struct sockaddr_in *addr;
1573
3958ae62
SN
1574 assert(address != NULL);
1575 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1576
1577 addr = (struct sockaddr_in *)address->m_addr;
1578 addr_buf = (char *)&(addr->sin_addr);
1579
3958ae62
SN
1580 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1581 if (he == NULL)
1582 {
fb9010ed
DW
1583 address->m_error = GSOCK_NOHOST;
1584 return GSOCK_NOHOST;
1585 }
1586
1587 strncpy(hostname, he->h_name, sbuf);
1588
1589 return GSOCK_NOERROR;
1590}
1591
1592unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1593{
1594 struct sockaddr_in *addr;
1595
3958ae62
SN
1596 assert(address != NULL);
1597 CHECK_ADDRESS_RETVAL(address, INET, 0);
fb9010ed
DW
1598
1599 addr = (struct sockaddr_in *)address->m_addr;
1600
1601 return addr->sin_addr.s_addr;
1602}
1603
1604unsigned short GAddress_INET_GetPort(GAddress *address)
1605{
1606 struct sockaddr_in *addr;
1607
3958ae62
SN
1608 assert(address != NULL);
1609 CHECK_ADDRESS_RETVAL(address, INET, 0);
fb9010ed
DW
1610
1611 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1612 return ntohs(addr->sin_port);
fb9010ed
DW
1613}
1614
b662c135
SN
1615/*
1616 * -------------------------------------------------------------------------
1617 * Unix address family
1618 * -------------------------------------------------------------------------
1619 */
1620
3958ae62 1621#ifdef __EMX__
b662c135
SN
1622GSocketError _GAddress_Init_UNIX(GAddress *address)
1623{
3958ae62
SN
1624 address->m_len = sizeof(struct sockaddr_un);
1625 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1626 if (address->m_addr == NULL)
1627 {
1628 address->m_error = GSOCK_MEMERR;
1629 return GSOCK_MEMERR;
1630 }
1631
1632 address->m_family = GSOCK_UNIX;
1633 address->m_realfamily = PF_UNIX;
1634 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1635 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1636
1637 return GSOCK_NOERROR;
b662c135
SN
1638}
1639
1640GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1641{
3958ae62
SN
1642 struct sockaddr_un *addr;
1643
1644 assert(address != NULL);
1645
1646 CHECK_ADDRESS(address, UNIX);
1647
1648 addr = ((struct sockaddr_un *)address->m_addr);
1649 memcpy(addr->sun_path, path, strlen(path));
1650
1651 return GSOCK_NOERROR;
b662c135
SN
1652}
1653
1654GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1655{
3958ae62
SN
1656 struct sockaddr_un *addr;
1657
1658 assert(address != NULL);
1659 CHECK_ADDRESS(address, UNIX);
1660
1661 addr = (struct sockaddr_un *)address->m_addr;
1662
1663 strncpy(path, addr->sun_path, sbuf);
b662c135 1664
3958ae62
SN
1665 return GSOCK_NOERROR;
1666}
fb9010ed 1667#endif
3958ae62
SN
1668 /* __EMX__ */
1669#endif
1670 /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
1671