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