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