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