]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
fixed wxBase and GUI separation for sockets code
[wxWidgets.git] / src / unix / gsocket.c
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>
29 struct 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
123 static 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
145 static struct GSocketBaseFunctionsTable gs_base_functions =
146 {
147 _GSocket_Detected_Read,
148 _GSocket_Detected_Write
149 };
150
151 /* Global initialisers */
152
153 void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc)
154 {
155 gs_gui_functions = guifunc;
156 }
157
158 int 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
168 void 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
178 GSocket *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
218 void GSocket_close(GSocket *socket)
219 {
220 _GSocket_Disable_Events(socket);
221 close(socket->m_fd);
222 socket->m_fd = INVALID_SOCKET;
223 }
224
225 void 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 */
251 void 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 */
287 GSocketError 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
313 GSocketError 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
332 GAddress *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
377 GAddress *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 */
400 GSocketError 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 */
467 GSocket *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 */
570 GSocketError 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 */
680 GSocketError 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(), ... */
734 int 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
770 int 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 */
834 GSocketEventFlags 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 */
964 void 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 */
977 void 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 */
989 GSocketError 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 */
1026 void 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 */
1047 void 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
1071 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
1072 {
1073 socket->m_detected &= ~(1 << event);
1074 _GSocket_Install_Callback(socket, event);
1075 }
1076
1077 void _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 */
1087 GSocketError _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 */
1126 GSocketError _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
1174 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
1175 {
1176 return recv(socket->m_fd, buffer, size, 0);
1177 }
1178
1179 int _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
1215 int _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
1226 int _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
1255 void _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
1289 void _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
1371 GAddress *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
1385 GAddress *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
1410 void 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
1420 void GAddress_SetFamily(GAddress *address, GAddressType type)
1421 {
1422 assert(address != NULL);
1423
1424 address->m_family = type;
1425 }
1426
1427 GAddressType GAddress_GetFamily(GAddress *address)
1428 {
1429 assert(address != NULL);
1430
1431 return address->m_family;
1432 }
1433
1434 GSocketError _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
1474 GSocketError _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
1501 GSocketError _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
1519 GSocketError 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
1558 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1559 {
1560 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1561 }
1562
1563 GSocketError 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
1578 GSocketError 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
1618 GSocketError 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
1631 GSocketError 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
1655 unsigned 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
1667 unsigned 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
1684 GSocketError _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
1704 GSocketError 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
1719 GSocketError 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