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