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