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