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