]> git.saurik.com Git - wxWidgets.git/blob - src/os2/gsocket.c
Acutally use the m_maxChars parameter value instead of ignoring it
[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 /* 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
163 int GSocket_Init(void)
164 {
165 return 1;
166 }
167
168 void GSocket_Cleanup(void)
169 {
170 }
171
172 /* Constructors / Destructors for GSocket */
173
174 GSocket *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
212 void GSocket_close(GSocket *socket)
213 {
214 _GSocket_Disable_Events(socket);
215 soclose(socket->m_fd);
216 socket->m_fd = INVALID_SOCKET;
217 }
218
219 void 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 */
245 void 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 */
282 GSocketError 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
308 GSocketError 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
327 GAddress *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
372 GAddress *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 */
395 GSocketError 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 */
462 GSocket *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 */
565 GSocketError 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 */
675 GSocketError 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(), ... */
729 int 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
765 int 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 */
829 GSocketEventFlags 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 */
956 void 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 */
969 void 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 */
981 GSocketError 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 */
1018 void 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 */
1039 void 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
1063 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
1064 {
1065 socket->m_detected &= ~(1 << event);
1066 _GSocket_Install_Callback(socket, event);
1067 }
1068
1069 void _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 */
1079 GSocketError _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 */
1118 GSocketError _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
1164 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
1165 {
1166 return recv(socket->m_fd, buffer, size, 0);
1167 }
1168
1169 int _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
1205 int _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
1219 int _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
1252 void _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
1286 void _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
1368 GAddress *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
1382 GAddress *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
1407 void 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
1417 void GAddress_SetFamily(GAddress *address, GAddressType type)
1418 {
1419 assert(address != NULL);
1420
1421 address->m_family = type;
1422 }
1423
1424 GAddressType GAddress_GetFamily(GAddress *address)
1425 {
1426 assert(address != NULL);
1427
1428 return address->m_family;
1429 }
1430
1431 GSocketError _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
1471 GSocketError _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
1498 GSocketError _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
1516 GSocketError 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
1557 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1558 {
1559 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1560 }
1561
1562 GSocketError 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
1577 GSocketError 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
1617 GSocketError 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
1630 GSocketError 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
1654 unsigned 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
1666 unsigned 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__
1684 GSocketError _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
1704 GSocketError 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
1719 GSocketError 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