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