]> git.saurik.com Git - wxWidgets.git/blame - src/os2/gsocket.c
Compilation fix.
[wxWidgets.git] / src / os2 / gsocket.c
CommitLineData
fb9010ed
DW
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
3958ae62
SN
4 * Authors: Guilhem Lavaux,
5 * Guillermo Rodriguez Garcia <guille@iies.es> (maintainer)
fb9010ed 6 * Purpose: GSocket main Unix-style file
84969af7 7 * Licence: The wxWindows licence
fb9010ed
DW
8 * CVSID: $Id$
9 * -------------------------------------------------------------------------
10 */
11
3958ae62
SN
12/*
13 * PLEASE don't put C++ comments here - this is a C source file.
14 */
15
16#ifndef __GSOCKET_STANDALONE__
fb9010ed 17#include "wx/setup.h"
3958ae62
SN
18#endif
19
bfdc8d18
SN
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. */
1cd04aa2 24#include "wx/defs.h"
bfdc8d18 25#endif
fb9010ed 26
3958ae62 27#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
fb9010ed 28
9dea36ef 29#define BSD_SELECT /* use Berkley Sockets select */
fb9010ed
DW
30
31#include <assert.h>
19193a2c 32#include <sys/types.h>
29d83fc1 33
610c9851
SN
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>
3958ae62
SN
40#include <unistd.h>
41#include <sys/un.h>
610c9851 42#define HAVE_INET_ADDR
29d83fc1 43
610c9851 44#else
29d83fc1 45
19193a2c
KB
46#include <string.h>
47
48#include <sys/time.h>
5fd2b2c6 49#include <types.h>
19193a2c 50#include <netinet/in.h>
fb9010ed
DW
51#include <netdb.h>
52#include <nerrno.h>
29d83fc1 53
610c9851 54#endif
29d83fc1 55
9ac6ff7b 56#if defined(__VISAGECPP__) && __IBMCPP__ < 400
29d83fc1 57
19193a2c 58#include <machine/endian.h>
9ac6ff7b
DW
59#include <socket.h>
60#include <ioctl.h>
61#include <select.h>
5fd2b2c6 62#include <unistd.h>
29d83fc1
DW
63
64#define EBADF SOCEBADF
65
9ac6ff7b 66#else
29d83fc1 67
19193a2c
KB
68#include <sys/socket.h>
69#include <sys/ioctl.h>
70#include <sys/select.h>
29d83fc1 71
521ccc1b
SN
72#ifdef __EMX__
73#define soclose(a) close(a)
74#else
9dea36ef
DW
75#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
76int _System bsdselect(int,
77 struct fd_set *,
78 struct fd_set *,
79 struct fd_set *,
80 struct timeval *);
81int _System soclose(int);
9ac6ff7b 82#endif
610c9851 83#endif
fb9010ed 84
fb9010ed 85#include <stdio.h>
3958ae62 86#if (defined(__VISAGECPP__) && __IBMCPP__ < 400) || defined(__EMX__)
e15bbde0
DW
87# ifdef min
88# undef min
89# endif
90# include <stdlib.h>
91#endif
fb9010ed
DW
92#include <stddef.h>
93#include <ctype.h>
19193a2c 94#include <stdlib.h>
fb9010ed
DW
95
96#include <signal.h>
97
fb9010ed
DW
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
3958ae62
SN
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
e32c4e60 135
3958ae62
SN
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 */
3958ae62
SN
155#ifdef __GSOCKET_DEBUG__
156# define GSocket_Debug(args) printf args
157#else
158# define GSocket_Debug(args)
159#endif /* __GSOCKET_DEBUG__ */
160
fb9010ed
DW
161/* Global initialisers */
162
3958ae62 163int GSocket_Init(void)
fb9010ed 164{
27f37ae5 165 return 1;
fb9010ed
DW
166}
167
3958ae62 168void GSocket_Cleanup(void)
fb9010ed
DW
169{
170}
171
3958ae62 172/* Constructors / Destructors for GSocket */
fb9010ed 173
3958ae62 174GSocket *GSocket_new(void)
fb9010ed 175{
3958ae62 176 int i, success;
fb9010ed
DW
177 GSocket *socket;
178
179 socket = (GSocket *)malloc(sizeof(GSocket));
180
181 if (socket == NULL)
182 return NULL;
183
3958ae62 184 socket->m_fd = INVALID_SOCKET;
fb9010ed
DW
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;
3958ae62
SN
193 socket->m_server = FALSE;
194 socket->m_stream = TRUE;
fb9010ed 195 socket->m_gui_dependent = NULL;
3958ae62 196 socket->m_non_blocking = FALSE;
fb9010ed
DW
197 socket->m_timeout = 10*60*1000;
198 /* 10 minutes * 60 sec * 1000 millisec */
3958ae62
SN
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 }
fb9010ed 208
fb9010ed
DW
209 return socket;
210}
211
e32c4e60
SN
212void GSocket_close(GSocket *socket)
213{
214 _GSocket_Disable_Events(socket);
215 soclose(socket->m_fd);
216 socket->m_fd = INVALID_SOCKET;
217}
218
fb9010ed
DW
219void GSocket_destroy(GSocket *socket)
220{
221 assert(socket != NULL);
222
3958ae62
SN
223 /* Check that the socket is really shutdowned */
224 if (socket->m_fd != INVALID_SOCKET)
fb9010ed
DW
225 GSocket_Shutdown(socket);
226
3958ae62
SN
227 /* Per-socket GUI-specific cleanup */
228 _GSocket_GUI_Destroy(socket);
229
230 /* Destroy private addresses */
fb9010ed
DW
231 if (socket->m_local)
232 GAddress_destroy(socket->m_local);
233
234 if (socket->m_peer)
235 GAddress_destroy(socket->m_peer);
236
3958ae62 237 /* Destroy the socket itself */
fb9010ed
DW
238 free(socket);
239}
240
3958ae62
SN
241/* GSocket_Shutdown:
242 * Disallow further read/write operations on this socket, close
243 * the fd and disable all callbacks.
244 */
fb9010ed
DW
245void GSocket_Shutdown(GSocket *socket)
246{
247 int evt;
248
249 assert(socket != NULL);
250
3958ae62
SN
251 /* If socket has been created, shutdown it */
252 if (socket->m_fd != INVALID_SOCKET)
fb9010ed
DW
253 {
254 shutdown(socket->m_fd, 2);
e32c4e60 255 GSocket_close(socket);
fb9010ed
DW
256 }
257
3958ae62 258 /* Disable GUI callbacks */
fb9010ed
DW
259 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
260 socket->m_cbacks[evt] = NULL;
261
3958ae62
SN
262 socket->m_detected = GSOCK_LOST_FLAG;
263 _GSocket_Disable_Events(socket);
fb9010ed
DW
264}
265
266/* Address handling */
267
3958ae62
SN
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 */
fb9010ed
DW
282GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
283{
284 assert(socket != NULL);
285
3958ae62
SN
286 /* the socket must be initialized, or it must be a server */
287 if ((socket->m_fd != INVALID_SOCKET && !socket->m_server))
288 {
fb9010ed
DW
289 socket->m_error = GSOCK_INVSOCK;
290 return GSOCK_INVSOCK;
291 }
292
3958ae62
SN
293 /* check address */
294 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
295 {
fb9010ed
DW
296 socket->m_error = GSOCK_INVADDR;
297 return GSOCK_INVADDR;
298 }
299
300 if (socket->m_local)
301 GAddress_destroy(socket->m_local);
302
303 socket->m_local = GAddress_copy(address);
304
305 return GSOCK_NOERROR;
306}
307
308GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
309{
310 assert(socket != NULL);
311
3958ae62
SN
312 /* check address */
313 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
314 {
fb9010ed
DW
315 socket->m_error = GSOCK_INVADDR;
316 return GSOCK_INVADDR;
317 }
318
319 if (socket->m_peer)
320 GAddress_destroy(socket->m_peer);
321
322 socket->m_peer = GAddress_copy(address);
323
324 return GSOCK_NOERROR;
325}
326
327GAddress *GSocket_GetLocal(GSocket *socket)
328{
329 GAddress *address;
330 struct sockaddr addr;
3958ae62 331 SOCKLEN_T size = sizeof(addr);
fb9010ed
DW
332 GSocketError err;
333
334 assert(socket != NULL);
335
3958ae62 336 /* try to get it from the m_local var first */
fb9010ed
DW
337 if (socket->m_local)
338 return GAddress_copy(socket->m_local);
339
3958ae62
SN
340 /* else, if the socket is initialized, try getsockname */
341 if (socket->m_fd == INVALID_SOCKET)
342 {
fb9010ed
DW
343 socket->m_error = GSOCK_INVSOCK;
344 return NULL;
345 }
346
3958ae62
SN
347 if (getsockname(socket->m_fd, &addr, (SOCKLEN_T *) &size) < 0)
348 {
fb9010ed
DW
349 socket->m_error = GSOCK_IOERR;
350 return NULL;
351 }
352
3958ae62 353 /* got a valid address from getsockname, create a GAddress object */
fb9010ed 354 address = GAddress_new();
3958ae62
SN
355 if (address == NULL)
356 {
fb9010ed
DW
357 socket->m_error = GSOCK_MEMERR;
358 return NULL;
359 }
3958ae62
SN
360
361 err = _GAddress_translate_from(address, &addr, size);
362 if (err != GSOCK_NOERROR)
363 {
fb9010ed 364 GAddress_destroy(address);
3958ae62 365 socket->m_error = err;
fb9010ed
DW
366 return NULL;
367 }
368
369 return address;
370}
371
372GAddress *GSocket_GetPeer(GSocket *socket)
373{
374 assert(socket != NULL);
375
3958ae62 376 /* try to get it from the m_peer var */
fb9010ed
DW
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:
3958ae62
SN
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:
e32c4e60 389 *
3958ae62
SN
390 * Error codes:
391 * GSOCK_INVSOCK - the socket is in use.
392 * GSOCK_INVADDR - the local address has not been set.
e32c4e60 393 * GSOCK_IOERR - low-level error.
fb9010ed
DW
394 */
395GSocketError GSocket_SetServer(GSocket *sck)
396{
fb9010ed
DW
397 int arg = 1;
398
399 assert(sck != NULL);
400
3958ae62
SN
401 /* must not be in use */
402 if (sck->m_fd != INVALID_SOCKET)
403 {
fb9010ed
DW
404 sck->m_error = GSOCK_INVSOCK;
405 return GSOCK_INVSOCK;
406 }
407
3958ae62
SN
408 /* the local addr must have been set */
409 if (!sck->m_local)
410 {
fb9010ed
DW
411 sck->m_error = GSOCK_INVADDR;
412 return GSOCK_INVADDR;
413 }
414
3958ae62
SN
415 /* Initialize all fields */
416 sck->m_stream = TRUE;
417 sck->m_server = TRUE;
418 sck->m_oriented = TRUE;
fb9010ed
DW
419
420 /* Create the socket */
421 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
422
3958ae62
SN
423 if (sck->m_fd == INVALID_SOCKET)
424 {
fb9010ed
DW
425 sck->m_error = GSOCK_IOERR;
426 return GSOCK_IOERR;
427 }
428
19193a2c 429 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62
SN
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 {
e32c4e60 442 GSocket_close(sck);
fb9010ed
DW
443 sck->m_error = GSOCK_IOERR;
444 return GSOCK_IOERR;
445 }
446
447 return GSOCK_NOERROR;
448}
449
450/* GSocket_WaitConnection:
3958ae62
SN
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.
e32c4e60 460 * GSOCK_IOERR - low-level error.
fb9010ed
DW
461 */
462GSocket *GSocket_WaitConnection(GSocket *socket)
463{
3958ae62
SN
464 struct sockaddr from;
465 SOCKLEN_T fromlen = sizeof(from);
fb9010ed 466 GSocket *connection;
3958ae62 467 GSocketError err;
fb9010ed
DW
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 */
3958ae62 476 if (socket->m_fd == INVALID_SOCKET || !socket->m_server)
fb9010ed
DW
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();
3958ae62 484
fb9010ed
DW
485 if (!connection)
486 {
3958ae62 487 socket->m_error = GSOCK_MEMERR;
fb9010ed
DW
488 return NULL;
489 }
490
3958ae62 491 /* Wait for a connection (with timeout) */
fb9010ed
DW
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
3958ae62 499 connection->m_fd = accept(socket->m_fd, &from, (SOCKLEN_T *) &fromlen);
fb9010ed 500
3958ae62 501 if (connection->m_fd == INVALID_SOCKET)
fb9010ed
DW
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 */
3958ae62
SN
513 connection->m_server = FALSE;
514 connection->m_stream = TRUE;
515 connection->m_oriented = TRUE;
fb9010ed 516
3958ae62
SN
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;
fb9010ed 524 }
3958ae62
SN
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;
fb9010ed
DW
532 }
533
19193a2c 534 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62 535 _GSocket_Enable_Events(connection);
fb9010ed 536
3958ae62 537 return connection;
fb9010ed
DW
538}
539
540/* Client specific parts */
541
542/* GSocket_Connect:
3958ae62
SN
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.
e32c4e60 563 * GSOCK_IOERR - low-level error.
fb9010ed
DW
564 */
565GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
566{
3958ae62 567 int err, ret;
fb9010ed
DW
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
3958ae62 575 if (sck->m_fd != INVALID_SOCKET)
fb9010ed
DW
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
3958ae62 587 /* Streamed or dgram socket? */
fb9010ed 588 sck->m_stream = (stream == GSOCK_STREAMED);
3958ae62
SN
589 sck->m_oriented = TRUE;
590 sck->m_server = FALSE;
591 sck->m_establishing = FALSE;
fb9010ed
DW
592
593 /* Create the socket */
3958ae62
SN
594 sck->m_fd = socket(sck->m_peer->m_realfamily,
595 sck->m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
fb9010ed 596
3958ae62
SN
597 if (sck->m_fd == INVALID_SOCKET)
598 {
fb9010ed
DW
599 sck->m_error = GSOCK_IOERR;
600 return GSOCK_IOERR;
601 }
602
19193a2c 603 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62 604 _GSocket_Enable_Events(sck);
fb9010ed 605
3958ae62 606 /* Connect it to the peer address, with a timeout (see below) */
fb9010ed
DW
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 {
e32c4e60 622 GSocket_close(sck);
fb9010ed 623 /* sck->m_error is set in _GSocket_Output_Timeout */
fb9010ed
DW
624 return GSOCK_TIMEDOUT;
625 }
626 else
627 {
3958ae62
SN
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;
fb9010ed
DW
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 {
3958ae62 646 sck->m_establishing = TRUE;
fb9010ed 647 sck->m_error = GSOCK_WOULDBLOCK;
fb9010ed
DW
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 */
e32c4e60 654 GSocket_close(sck);
fb9010ed 655 sck->m_error = GSOCK_IOERR;
3958ae62
SN
656 return GSOCK_IOERR;
657 }
fb9010ed 658
3958ae62
SN
659 return GSOCK_NOERROR;
660}
661
662/* Datagram sockets */
663
664/* GSocket_SetNonOriented:
665 * Sets up this socket as a non-connection oriented (datagram) socket.
666 * Before using this function, the local address must have been set
667 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
668 * on success, or one of the following otherwise.
669 *
670 * Error codes:
671 * GSOCK_INVSOCK - the socket is in use.
672 * GSOCK_INVADDR - the local address has not been set.
673 * GSOCK_IOERR - low-level error.
674 */
675GSocketError GSocket_SetNonOriented(GSocket *sck)
676{
677 int arg = 1;
678
679 assert(sck != NULL);
680
681 if (sck->m_fd != INVALID_SOCKET)
682 {
683 sck->m_error = GSOCK_INVSOCK;
684 return GSOCK_INVSOCK;
685 }
686
687 if (!sck->m_local)
688 {
689 sck->m_error = GSOCK_INVADDR;
690 return GSOCK_INVADDR;
691 }
692
693 /* Initialize all fields */
694 sck->m_stream = FALSE;
695 sck->m_server = FALSE;
696 sck->m_oriented = FALSE;
697
698 /* Create the socket */
699 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
700
701 if (sck->m_fd == INVALID_SOCKET)
702 {
703 sck->m_error = GSOCK_IOERR;
704 return GSOCK_IOERR;
705 }
706
19193a2c 707 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62
SN
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 {
e32c4e60 718 GSocket_close(sck);
3958ae62 719 sck->m_error = GSOCK_IOERR;
fb9010ed
DW
720 return GSOCK_IOERR;
721 }
722
fb9010ed
DW
723 return GSOCK_NOERROR;
724}
725
726/* Generic IO */
727
728/* Like recv(), send(), ... */
729int GSocket_Read(GSocket *socket, char *buffer, int size)
730{
731 int ret;
732
733 assert(socket != NULL);
734
735 /* Reenable INPUT events */
736 _GSocket_Enable(socket, GSOCK_INPUT);
737
3958ae62 738 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
fb9010ed
DW
739 {
740 socket->m_error = GSOCK_INVSOCK;
741 return -1;
742 }
743
3958ae62 744 /* If the socket is blocking, wait for data (with a timeout) */
fb9010ed
DW
745 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
746 return -1;
747
3958ae62 748 /* Read the data */
fb9010ed
DW
749 if (socket->m_stream)
750 ret = _GSocket_Recv_Stream(socket, buffer, size);
751 else
752 ret = _GSocket_Recv_Dgram(socket, buffer, size);
e32c4e60 753
fb9010ed
DW
754 if (ret == -1)
755 {
756 if (errno == EWOULDBLOCK)
757 socket->m_error = GSOCK_WOULDBLOCK;
758 else
759 socket->m_error = GSOCK_IOERR;
760 }
e32c4e60 761
fb9010ed
DW
762 return ret;
763}
764
3958ae62 765int GSocket_Write(GSocket *socket, const char *buffer, int size)
e32c4e60 766{
fb9010ed
DW
767 int ret;
768
769 assert(socket != NULL);
e32c4e60 770
3958ae62 771 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
fb9010ed 772
3958ae62 773 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
fb9010ed
DW
774 {
775 socket->m_error = GSOCK_INVSOCK;
776 return -1;
777 }
778
3958ae62
SN
779 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
780
781 /* If the socket is blocking, wait for writability (with a timeout) */
fb9010ed
DW
782 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
783 return -1;
784
3958ae62
SN
785 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
786
787 /* Write the data */
fb9010ed
DW
788 if (socket->m_stream)
789 ret = _GSocket_Send_Stream(socket, buffer, size);
790 else
791 ret = _GSocket_Send_Dgram(socket, buffer, size);
e32c4e60 792
3958ae62 793 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
fb9010ed
DW
794
795 if (ret == -1)
796 {
797 if (errno == EWOULDBLOCK)
3958ae62 798 {
fb9010ed 799 socket->m_error = GSOCK_WOULDBLOCK;
3958ae62
SN
800 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
801 }
fb9010ed 802 else
3958ae62 803 {
fb9010ed 804 socket->m_error = GSOCK_IOERR;
3958ae62
SN
805 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
806 }
fb9010ed
DW
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);
3958ae62 814 return -1;
fb9010ed 815 }
e32c4e60 816
3958ae62 817 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
fb9010ed
DW
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
3958ae62 827 * mode (blocking | nonblocking) of the socket.
fb9010ed
DW
828 */
829GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
830{
3958ae62
SN
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
fb9010ed
DW
843 assert(socket != NULL);
844
3958ae62
SN
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
e32c4e60
SN
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 }
3958ae62
SN
864
865 /* Try select now */
866 if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
e32c4e60
SN
867 {
868 /* What to do here? */
869 return (result & flags);
870 }
3958ae62
SN
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 {
e32c4e60 879 result |= GSOCK_INPUT_FLAG;
3958ae62
SN
880 }
881 else
882 {
883 if (socket->m_server && socket->m_stream)
884 {
e32c4e60 885 result |= GSOCK_CONNECTION_FLAG;
3958ae62
SN
886 socket->m_detected |= GSOCK_CONNECTION_FLAG;
887 }
888 else
889 {
3958ae62 890 socket->m_detected = GSOCK_LOST_FLAG;
e32c4e60
SN
891 socket->m_establishing = FALSE;
892
893 /* LOST event: Abort any further processing */
894 return (GSOCK_LOST_FLAG & flags);
3958ae62
SN
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 {
3958ae62 913 socket->m_detected = GSOCK_LOST_FLAG;
e32c4e60
SN
914
915 /* LOST event: Abort any further processing */
916 return (GSOCK_LOST_FLAG & flags);
3958ae62
SN
917 }
918 else
919 {
e32c4e60 920 result |= GSOCK_CONNECTION_FLAG;
3958ae62
SN
921 socket->m_detected |= GSOCK_CONNECTION_FLAG;
922 }
923 }
924 else
925 {
e32c4e60 926 result |= GSOCK_OUTPUT_FLAG;
3958ae62
SN
927 }
928 }
929
930 /* Check for exceptions and errors (is this useful in Unices?) */
931 if (FD_ISSET(socket->m_fd, &exceptfds))
932 {
3958ae62
SN
933 socket->m_establishing = FALSE;
934 socket->m_detected = GSOCK_LOST_FLAG;
e32c4e60
SN
935
936 /* LOST event: Abort any further processing */
937 return (GSOCK_LOST_FLAG & flags);
3958ae62
SN
938 }
939
e32c4e60 940 return (result & flags);
3958ae62 941
e32c4e60 942#else
3958ae62
SN
943
944 assert(socket != NULL);
945 return flags & socket->m_detected;
946
947#endif /* !wxUSE_GUI */
fb9010ed
DW
948}
949
950/* Flags */
951
952/* GSocket_SetNonBlocking:
3958ae62
SN
953 * Sets the socket to non-blocking mode. All IO calls will return
954 * immediately.
fb9010ed 955 */
27f37ae5 956void GSocket_SetNonBlocking(GSocket *socket, int non_block)
fb9010ed
DW
957{
958 assert(socket != NULL);
959
3958ae62
SN
960 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
961
fb9010ed
DW
962 socket->m_non_blocking = non_block;
963}
964
965/* GSocket_SetTimeout:
3958ae62
SN
966 * Sets the timeout for blocking calls. Time is expressed in
967 * milliseconds.
fb9010ed
DW
968 */
969void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
970{
971 assert(socket != NULL);
972
973 socket->m_timeout = millisec;
974}
975
976/* GSocket_GetError:
3958ae62
SN
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.
fb9010ed
DW
980 */
981GSocketError GSocket_GetError(GSocket *socket)
982{
983 assert(socket != NULL);
984
985 return socket->m_error;
986}
987
988/* Callbacks */
989
3958ae62
SN
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:
e32c4e60 995 * The socket is available for writing. That is, the next write call
3958ae62
SN
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.
fb9010ed
DW
1008 */
1009
1010/* GSocket_SetCallback:
1011 * Enables the callbacks specified by 'flags'. Note that 'flags'
1012 * may be a combination of flags OR'ed toghether, so the same
1013 * callback function can be made to accept different events.
1014 * The callback function must have the following prototype:
1015 *
1016 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1017 */
1018void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
3958ae62 1019 GSocketCallback callback, char *cdata)
fb9010ed
DW
1020{
1021 int count;
1022
1023 assert(socket != NULL);
1024
1025 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1026 {
1027 if ((flags & (1 << count)) != 0)
1028 {
1029 socket->m_cbacks[count] = callback;
1030 socket->m_data[count] = cdata;
1031 }
1032 }
1033}
1034
1035/* GSocket_UnsetCallback:
1036 * Disables all callbacks specified by 'flags', which may be a
1037 * combination of flags OR'ed toghether.
1038 */
1039void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
1040{
1041 int count;
1042
1043 assert(socket != NULL);
1044
1045 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1046 {
1047 if ((flags & (1 << count)) != 0)
1048 {
1049 socket->m_cbacks[count] = NULL;
1050 socket->m_data[count] = NULL;
1051 }
1052 }
1053}
1054
3958ae62 1055
fb9010ed
DW
1056#define CALL_CALLBACK(socket, event) { \
1057 _GSocket_Disable(socket, event); \
e32c4e60 1058 if (socket->m_cbacks[event]) \
fb9010ed
DW
1059 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1060}
1061
1062
1063void _GSocket_Enable(GSocket *socket, GSocketEvent event)
1064{
1065 socket->m_detected &= ~(1 << event);
3958ae62 1066 _GSocket_Install_Callback(socket, event);
fb9010ed
DW
1067}
1068
1069void _GSocket_Disable(GSocket *socket, GSocketEvent event)
1070{
1071 socket->m_detected |= (1 << event);
3958ae62 1072 _GSocket_Uninstall_Callback(socket, event);
fb9010ed
DW
1073}
1074
1075/* _GSocket_Input_Timeout:
1076 * For blocking sockets, wait until data is available or
1077 * until timeout ellapses.
1078 */
1079GSocketError _GSocket_Input_Timeout(GSocket *socket)
1080{
1081 struct timeval tv;
1082 fd_set readfds;
3958ae62 1083 int ret;
fb9010ed 1084
3958ae62 1085 /* Linux select() will overwrite the struct on return */
fb9010ed
DW
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);
3958ae62
SN
1093 ret = select(socket->m_fd + 1, &readfds, NULL, NULL, &tv);
1094 if (ret == 0)
fb9010ed 1095 {
3958ae62
SN
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" ));
fb9010ed
DW
1107 socket->m_error = GSOCK_TIMEDOUT;
1108 return GSOCK_TIMEDOUT;
1109 }
1110 }
1111 return GSOCK_NOERROR;
1112}
1113
1114/* _GSocket_Output_Timeout:
1115 * For blocking sockets, wait until data can be sent without
1116 * blocking or until timeout ellapses.
1117 */
1118GSocketError _GSocket_Output_Timeout(GSocket *socket)
1119{
1120 struct timeval tv;
1121 fd_set writefds;
3958ae62 1122 int ret;
fb9010ed 1123
3958ae62 1124 /* Linux select() will overwrite the struct on return */
fb9010ed
DW
1125 tv.tv_sec = (socket->m_timeout / 1000);
1126 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
1127
3958ae62
SN
1128 GSocket_Debug( ("m_non_blocking has: %d\n", (int)socket->m_non_blocking) );
1129
fb9010ed
DW
1130 if (!socket->m_non_blocking)
1131 {
1132 FD_ZERO(&writefds);
1133 FD_SET(socket->m_fd, &writefds);
3958ae62
SN
1134 ret = select(socket->m_fd + 1, NULL, &writefds, NULL, &tv);
1135 if (ret == 0)
fb9010ed 1136 {
3958ae62 1137 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
fb9010ed
DW
1138 socket->m_error = GSOCK_TIMEDOUT;
1139 return GSOCK_TIMEDOUT;
1140 }
3958ae62
SN
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" ));
fb9010ed 1159 }
3958ae62 1160
fb9010ed
DW
1161 return GSOCK_NOERROR;
1162}
1163
1164int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
1165{
3958ae62 1166 return recv(socket->m_fd, buffer, size, 0);
fb9010ed
DW
1167}
1168
1169int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
1170{
1171 struct sockaddr from;
3958ae62 1172 SOCKLEN_T fromlen = sizeof(from);
fb9010ed
DW
1173 int ret;
1174 GSocketError err;
1175
1176 fromlen = sizeof(from);
1177
3958ae62 1178 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, (SOCKLEN_T *) &fromlen);
fb9010ed
DW
1179
1180 if (ret == -1)
1181 return -1;
1182
1183 /* Translate a system address into a GSocket address */
1184 if (!socket->m_peer)
1185 {
1186 socket->m_peer = GAddress_new();
1187 if (!socket->m_peer)
1188 {
1189 socket->m_error = GSOCK_MEMERR;
1190 return -1;
1191 }
1192 }
1193 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
1194 if (err != GSOCK_NOERROR)
1195 {
1196 GAddress_destroy(socket->m_peer);
1197 socket->m_peer = NULL;
1198 socket->m_error = err;
1199 return -1;
1200 }
1201
1202 return ret;
1203}
1204
1205int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
1206{
1207 int ret;
fb9010ed 1208
29d83fc1 1209#ifdef __EMX__
3958ae62
SN
1210 MASK_SIGNAL();
1211 ret = send(socket->m_fd, buffer, size, 0);
1212 UNMASK_SIGNAL();
29d83fc1 1213#else
19193a2c 1214 ret = send(socket->m_fd, (char *)buffer, size, 0);
29d83fc1 1215#endif
fb9010ed
DW
1216 return ret;
1217}
1218
1219int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
1220{
1221 struct sockaddr *addr;
1222 int len, ret;
1223 GSocketError err;
1224
3958ae62
SN
1225 if (!socket->m_peer)
1226 {
fb9010ed
DW
1227 socket->m_error = GSOCK_INVADDR;
1228 return -1;
1229 }
1230
1231 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
3958ae62
SN
1232 if (err != GSOCK_NOERROR)
1233 {
fb9010ed
DW
1234 socket->m_error = err;
1235 return -1;
1236 }
1237
29d83fc1 1238#ifdef __EMX__
3958ae62
SN
1239 MASK_SIGNAL();
1240 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1241 UNMASK_SIGNAL();
29d83fc1 1242#else
19193a2c 1243 ret = sendto(socket->m_fd, (char *)buffer, size, 0, addr, len);
29d83fc1 1244#endif
fb9010ed
DW
1245
1246 /* Frees memory allocated from _GAddress_translate_to */
1247 free(addr);
1248
1249 return ret;
1250}
1251
1252void _GSocket_Detected_Read(GSocket *socket)
1253{
1254 char c;
fb9010ed 1255
e32c4e60
SN
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
3958ae62 1268 if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
fb9010ed 1269 {
3958ae62
SN
1270 CALL_CALLBACK(socket, GSOCK_INPUT);
1271 }
1272 else
1273 {
1274 if (socket->m_server && socket->m_stream)
fb9010ed
DW
1275 {
1276 CALL_CALLBACK(socket, GSOCK_CONNECTION);
fb9010ed
DW
1277 }
1278 else
1279 {
1280 CALL_CALLBACK(socket, GSOCK_LOST);
e32c4e60 1281 GSocket_Shutdown(socket);
fb9010ed
DW
1282 }
1283 }
1284}
1285
1286void _GSocket_Detected_Write(GSocket *socket)
1287{
e32c4e60
SN
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
fb9010ed
DW
1300 if (socket->m_establishing && !socket->m_server)
1301 {
3958ae62
SN
1302 int error;
1303 SOCKLEN_T len = sizeof(error);
fb9010ed 1304
3958ae62 1305 socket->m_establishing = FALSE;
fb9010ed 1306
3958ae62 1307 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
fb9010ed
DW
1308
1309 if (error)
1310 {
1311 CALL_CALLBACK(socket, GSOCK_LOST);
e32c4e60 1312 GSocket_Shutdown(socket);
fb9010ed
DW
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
3958ae62
SN
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.
fb9010ed 1342 */
3958ae62
SN
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 } \
fb9010ed
DW
1365}
1366
3958ae62
SN
1367
1368GAddress *GAddress_new(void)
fb9010ed
DW
1369{
1370 GAddress *address;
1371
3958ae62 1372 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
fb9010ed
DW
1373 return NULL;
1374
1375 address->m_family = GSOCK_NOFAMILY;
1376 address->m_addr = NULL;
1377 address->m_len = 0;
1378
1379 return address;
1380}
1381
1382GAddress *GAddress_copy(GAddress *address)
1383{
1384 GAddress *addr2;
1385
1386 assert(address != NULL);
1387
3958ae62 1388 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
fb9010ed
DW
1389 return NULL;
1390
1391 memcpy(addr2, address, sizeof(GAddress));
1392
e32c4e60 1393 if (address->m_addr && address->m_len > 0)
3958ae62 1394 {
fb9010ed 1395 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
3958ae62
SN
1396 if (addr2->m_addr == NULL)
1397 {
fb9010ed
DW
1398 free(addr2);
1399 return NULL;
1400 }
1401 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1402 }
1403
1404 return addr2;
1405}
1406
1407void GAddress_destroy(GAddress *address)
1408{
1409 assert(address != NULL);
1410
3958ae62
SN
1411 if (address->m_addr)
1412 free(address->m_addr);
1413
1414/* free(address); */
fb9010ed
DW
1415}
1416
1417void GAddress_SetFamily(GAddress *address, GAddressType type)
1418{
1419 assert(address != NULL);
1420
1421 address->m_family = type;
1422}
1423
1424GAddressType GAddress_GetFamily(GAddress *address)
1425{
1426 assert(address != NULL);
1427
1428 return address->m_family;
1429}
1430
3958ae62
SN
1431GSocketError _GAddress_translate_from(GAddress *address,
1432 struct sockaddr *addr, int len)
1433{
fb9010ed 1434 address->m_realfamily = addr->sa_family;
3958ae62
SN
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;
fb9010ed 1443#ifdef AF_INET6
3958ae62
SN
1444 case AF_INET6:
1445 address->m_family = GSOCK_INET6;
1446 break;
fb9010ed 1447#endif
3958ae62 1448 default:
fb9010ed 1449 {
3958ae62
SN
1450 address->m_error = GSOCK_INVOP;
1451 return GSOCK_INVOP;
fb9010ed
DW
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);
3958ae62
SN
1460
1461 if (address->m_addr == NULL)
1462 {
fb9010ed
DW
1463 address->m_error = GSOCK_MEMERR;
1464 return GSOCK_MEMERR;
1465 }
1466 memcpy(address->m_addr, addr, len);
1467
1468 return GSOCK_NOERROR;
1469}
1470
1471GSocketError _GAddress_translate_to(GAddress *address,
1472 struct sockaddr **addr, int *len)
1473{
3958ae62
SN
1474 if (!address->m_addr)
1475 {
fb9010ed
DW
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);
3958ae62
SN
1482 if (*addr == NULL)
1483 {
fb9010ed
DW
1484 address->m_error = GSOCK_MEMERR;
1485 return GSOCK_MEMERR;
1486 }
1487
1488 memcpy(*addr, address->m_addr, address->m_len);
1489 return GSOCK_NOERROR;
1490}
1491
1492/*
1493 * -------------------------------------------------------------------------
1494 * Internet address family
1495 * -------------------------------------------------------------------------
1496 */
1497
1498GSocketError _GAddress_Init_INET(GAddress *address)
1499{
3958ae62
SN
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 {
fb9010ed
DW
1504 address->m_error = GSOCK_MEMERR;
1505 return GSOCK_MEMERR;
1506 }
1507
fb9010ed
DW
1508 address->m_family = GSOCK_INET;
1509 address->m_realfamily = PF_INET;
1510 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
3958ae62 1511 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
fb9010ed
DW
1512
1513 return GSOCK_NOERROR;
1514}
1515
1516GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1517{
1518 struct hostent *he;
1519 struct in_addr *addr;
1520
1521 assert(address != NULL);
1522
3958ae62 1523 CHECK_ADDRESS(address, INET);
fb9010ed
DW
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)
3958ae62
SN
1529 if (inet_aton(hostname, addr) == 0)
1530 {
fb9010ed 1531#elif defined(HAVE_INET_ADDR)
29d83fc1 1532 addr->s_addr = inet_addr(hostname);
d75262db 1533 if ( addr->s_addr == -1 )
3958ae62
SN
1534 {
1535#else
1536 /* Use gethostbyname by default */
987da0d4
DW
1537 int val = 1; //VA doesn't like constants in conditional expressions at all
1538 if (val)
3958ae62 1539 {
fb9010ed
DW
1540#endif
1541 struct in_addr *array_addr;
1542
1543 /* It is a real name, we solve it */
3958ae62
SN
1544 if ((he = gethostbyname(hostname)) == NULL)
1545 {
1546 /* Reset to invalid address */
1547 addr->s_addr = INADDR_NONE;
fb9010ed
DW
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;
fb9010ed 1553 }
fb9010ed
DW
1554 return GSOCK_NOERROR;
1555}
1556
b662c135
SN
1557GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1558{
1559 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1560}
1561
fb9010ed
DW
1562GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1563 unsigned long hostaddr)
1564{
1565 struct in_addr *addr;
1566
1567 assert(address != NULL);
1568
3958ae62 1569 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1570
1571 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1572 addr->s_addr = hostaddr;
1573
1574 return GSOCK_NOERROR;
1575}
1576
1577GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1578 const char *protocol)
1579{
1580 struct servent *se;
1581 struct sockaddr_in *addr;
1582
1583 assert(address != NULL);
3958ae62 1584 CHECK_ADDRESS(address, INET);
fb9010ed 1585
3958ae62
SN
1586 if (!port)
1587 {
fb9010ed
DW
1588 address->m_error = GSOCK_INVPORT;
1589 return GSOCK_INVPORT;
1590 }
e32c4e60 1591
3958ae62
SN
1592 se = getservbyname(port, protocol);
1593 if (!se)
1594 {
e32c4e60
SN
1595 /* the cast to int suppresses compiler warnings about subscript having the
1596 type char */
3958ae62
SN
1597 if (isdigit((int)port[0]))
1598 {
fb9010ed
DW
1599 int port_int;
1600
1601 port_int = atoi(port);
1602 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1603 addr->sin_port = htons(port_int);
fb9010ed
DW
1604 return GSOCK_NOERROR;
1605 }
1606
1607 address->m_error = GSOCK_INVPORT;
1608 return GSOCK_INVPORT;
1609 }
1610
1611 addr = (struct sockaddr_in *)address->m_addr;
1612 addr->sin_port = se->s_port;
1613
1614 return GSOCK_NOERROR;
1615}
1616
1617GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1618{
1619 struct sockaddr_in *addr;
1620
1621 assert(address != NULL);
3958ae62 1622 CHECK_ADDRESS(address, INET);
e32c4e60 1623
fb9010ed 1624 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1625 addr->sin_port = htons(port);
fb9010ed
DW
1626
1627 return GSOCK_NOERROR;
1628}
1629
1630GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1631{
1632 struct hostent *he;
1633 char *addr_buf;
1634 struct sockaddr_in *addr;
1635
e32c4e60 1636 assert(address != NULL);
3958ae62 1637 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1638
1639 addr = (struct sockaddr_in *)address->m_addr;
1640 addr_buf = (char *)&(addr->sin_addr);
1641
3958ae62
SN
1642 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1643 if (he == NULL)
1644 {
fb9010ed
DW
1645 address->m_error = GSOCK_NOHOST;
1646 return GSOCK_NOHOST;
1647 }
1648
1649 strncpy(hostname, he->h_name, sbuf);
1650
1651 return GSOCK_NOERROR;
1652}
1653
1654unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1655{
1656 struct sockaddr_in *addr;
1657
e32c4e60
SN
1658 assert(address != NULL);
1659 CHECK_ADDRESS_RETVAL(address, INET, 0);
fb9010ed
DW
1660
1661 addr = (struct sockaddr_in *)address->m_addr;
1662
1663 return addr->sin_addr.s_addr;
1664}
1665
1666unsigned short GAddress_INET_GetPort(GAddress *address)
1667{
1668 struct sockaddr_in *addr;
1669
e32c4e60
SN
1670 assert(address != NULL);
1671 CHECK_ADDRESS_RETVAL(address, INET, 0);
fb9010ed
DW
1672
1673 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1674 return ntohs(addr->sin_port);
fb9010ed
DW
1675}
1676
b662c135
SN
1677/*
1678 * -------------------------------------------------------------------------
1679 * Unix address family
1680 * -------------------------------------------------------------------------
1681 */
1682
3958ae62 1683#ifdef __EMX__
b662c135
SN
1684GSocketError _GAddress_Init_UNIX(GAddress *address)
1685{
3958ae62
SN
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;
b662c135
SN
1700}
1701
e32c4e60
SN
1702#define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
1703
b662c135
SN
1704GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1705{
3958ae62
SN
1706 struct sockaddr_un *addr;
1707
e32c4e60 1708 assert(address != NULL);
3958ae62 1709
e32c4e60 1710 CHECK_ADDRESS(address, UNIX);
3958ae62
SN
1711
1712 addr = ((struct sockaddr_un *)address->m_addr);
e32c4e60
SN
1713 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
1714 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
3958ae62
SN
1715
1716 return GSOCK_NOERROR;
b662c135
SN
1717}
1718
1719GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1720{
3958ae62
SN
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);
b662c135 1729
3958ae62
SN
1730 return GSOCK_NOERROR;
1731}
fb9010ed 1732#endif
3958ae62
SN
1733 /* __EMX__ */
1734#endif
1735 /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
1736