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