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