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