]> git.saurik.com Git - wxWidgets.git/blame - src/common/socket.cpp
Document wxGridCellAttrProvider.
[wxWidgets.git] / src / common / socket.cpp
CommitLineData
56d8adc0 1/////////////////////////////////////////////////////////////////////////////
7fb0a11d 2// Name: src/common/socket.cpp
f4ada568 3// Purpose: Socket handler classes
56d8adc0 4// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
f4ada568 5// Created: April 1997
d3ea6527 6// Copyright: (C) 1999-1997, Guilhem Lavaux
51fe4b60
VZ
7// (C) 1999-2000, Guillermo Rodriguez Garcia
8// (C) 2008 Vadim Zeitlin
f4ada568 9// RCS_ID: $Id$
7fb0a11d 10// License: wxWindows licence
56d8adc0
GRG
11/////////////////////////////////////////////////////////////////////////////
12
bffc1eaa
GRG
13// ==========================================================================
14// Declarations
15// ==========================================================================
16
fcc6dddd
JS
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
8e3f3880 21 #pragma hdrstop
fcc6dddd
JS
22#endif
23
35a4dab7
GL
24#if wxUSE_SOCKETS
25
df91131c
WS
26#include "wx/socket.h"
27
8e3f3880
WS
28#ifndef WX_PRECOMP
29 #include "wx/object.h"
df91131c 30 #include "wx/string.h"
88a7a4e1 31 #include "wx/intl.h"
e4db172a 32 #include "wx/log.h"
d5da0ce7 33 #include "wx/event.h"
670f9935 34 #include "wx/app.h"
de6185e2 35 #include "wx/utils.h"
c0badb70 36 #include "wx/timer.h"
02761f6c 37 #include "wx/module.h"
8e3f3880
WS
38#endif
39
e2478fde 40#include "wx/apptrait.h"
56d8adc0 41#include "wx/sckaddr.h"
4252569b 42#include "wx/stopwatch.h"
204abcd4 43#include "wx/thread.h"
2804f77d 44#include "wx/evtloop.h"
54e757fc 45#include "wx/link.h"
02564412 46
40e7c0b9 47#include "wx/private/fd.h"
60913641 48#include "wx/private/socket.h"
3b4183d8 49
14372de8
VZ
50#ifdef __UNIX__
51 #include <errno.h>
52#endif
53
54// we use MSG_NOSIGNAL to avoid getting SIGPIPE when sending data to a remote
55// host which closed the connection if it is available, otherwise we rely on
56// SO_NOSIGPIPE existency
57//
58// this should cover all the current Unix systems (Windows never sends any
59// signals anyhow) but if we find one that has neither we should explicitly
60// ignore SIGPIPE for it
66034aba
JJ
61// OpenVMS has neither MSG_NOSIGNAL nor SO_NOSIGPIPE. However the socket sample
62// seems to work. Not sure if problems will show up on OpenVMS using sockets.
14372de8
VZ
63#ifdef MSG_NOSIGNAL
64 #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
65#else // MSG_NOSIGNAL not available (BSD including OS X)
04b2ab1a 66 // next best possibility is to use SO_NOSIGPIPE socket option, this covers
335a0bc3
VZ
67 // BSD systems (including OS X) -- but if we don't have it neither (AIX and
68 // old HP-UX do not), we have to fall back to the old way of simply
69 // disabling SIGPIPE temporarily, so define a class to do it in a safe way
04b2ab1a 70 #if defined(__UNIX__) && !defined(SO_NOSIGPIPE)
a645ea88 71 extern "C" { typedef void (*wxSigHandler_t)(int); }
04b2ab1a
VZ
72 namespace
73 {
74 class IgnoreSignal
75 {
76 public:
77 // ctor disables the given signal
78 IgnoreSignal(int sig)
79 : m_handler(signal(sig, SIG_IGN)),
80 m_sig(sig)
81 {
82 }
83
84 // dtor restores the old handler
85 ~IgnoreSignal()
86 {
87 signal(m_sig, m_handler);
88 }
89
90 private:
a645ea88 91 const wxSigHandler_t m_handler;
04b2ab1a
VZ
92 const int m_sig;
93
94 wxDECLARE_NO_COPY_CLASS(IgnoreSignal);
95 };
96 } // anonymous namespace
335a0bc3
VZ
97
98 #define wxNEEDS_IGNORE_SIGPIPE
99 #endif // Unix without SO_NOSIGPIPE
14372de8
VZ
100
101 #define wxSOCKET_MSG_NOSIGNAL 0
102#endif
103
34fdf762
VS
104// DLL options compatibility check:
105#include "wx/build.h"
106WX_CHECK_BUILD_OPTIONS("wxNet")
107
bffc1eaa
GRG
108// --------------------------------------------------------------------------
109// macros and constants
110// --------------------------------------------------------------------------
ef57d866 111
3c778901
VZ
112// event
113wxDEFINE_EVENT(wxEVT_SOCKET, wxSocketEvent);
114
dc5c1114
GRG
115// discard buffer
116#define MAX_DISCARD_SIZE (10 * 1024)
96db102a 117
9a83f860 118#define wxTRACE_Socket wxT("wxSocket")
007c77ab 119
ef57d866 120// --------------------------------------------------------------------------
bffc1eaa 121// wxWin macros
ef57d866 122// --------------------------------------------------------------------------
81b92e17 123
a737331d
GL
124IMPLEMENT_CLASS(wxSocketBase, wxObject)
125IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
126IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
dc5c1114 127IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
a737331d 128IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
f4ada568 129
00414faf
VZ
130// ----------------------------------------------------------------------------
131// private functions
132// ----------------------------------------------------------------------------
133
134namespace
135{
136
137void SetTimeValFromMS(timeval& tv, unsigned long ms)
138{
139 tv.tv_sec = (ms / 1000);
140 tv.tv_usec = (ms % 1000) * 1000;
141}
142
143} // anonymous namespace
144
bffc1eaa
GRG
145// --------------------------------------------------------------------------
146// private classes
147// --------------------------------------------------------------------------
148
56d8adc0
GRG
149class wxSocketState : public wxObject
150{
a324a7bc 151public:
c2116a35
VZ
152 wxSocketFlags m_flags;
153 wxSocketEventFlags m_eventmask;
154 bool m_notify;
155 void *m_clientData;
a324a7bc
GL
156
157public:
c2116a35 158 wxSocketState() : wxObject() {}
22f3361e 159
c0c133e1 160 wxDECLARE_NO_COPY_CLASS(wxSocketState);
a324a7bc
GL
161};
162
365b8793
VZ
163// wxSocketWaitModeChanger: temporarily change the socket flags affecting its
164// wait mode
165class wxSocketWaitModeChanger
166{
167public:
168 // temporarily set the flags to include the flag value which may be either
169 // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
170 wxSocketWaitModeChanger(wxSocketBase *socket, int flag)
171 : m_socket(socket),
172 m_oldflags(socket->GetFlags())
173
174 {
175 wxASSERT_MSG( flag == wxSOCKET_WAITALL || flag == wxSOCKET_NOWAIT,
176 "not a wait flag" );
177
178 // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
179 // mode but not when switching to wxSOCKET_NOWAIT as the latter is
180 // incompatible with wxSOCKET_BLOCK
181 if ( flag != wxSOCKET_NOWAIT )
182 flag |= m_oldflags & wxSOCKET_BLOCK;
183
184 socket->SetFlags(flag);
185 }
186
187 ~wxSocketWaitModeChanger()
188 {
189 m_socket->SetFlags(m_oldflags);
190 }
191
192private:
193 wxSocketBase * const m_socket;
194 const int m_oldflags;
195
c0c133e1 196 wxDECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger);
365b8793
VZ
197};
198
199// wxSocketRead/WriteGuard are instantiated before starting reading
200// from/writing to the socket
201class wxSocketReadGuard
202{
203public:
204 wxSocketReadGuard(wxSocketBase *socket)
205 : m_socket(socket)
206 {
207 wxASSERT_MSG( !m_socket->m_reading, "read reentrancy?" );
208
209 m_socket->m_reading = true;
210 }
211
212 ~wxSocketReadGuard()
213 {
214 m_socket->m_reading = false;
df21920b 215
f46a0165
VZ
216 // connection could have been lost while reading, in this case calling
217 // ReenableEvents() would assert and is not necessary anyhow
218 wxSocketImpl * const impl = m_socket->m_impl;
219 if ( impl && impl->m_fd != INVALID_SOCKET )
220 impl->ReenableEvents(wxSOCKET_INPUT_FLAG);
365b8793
VZ
221 }
222
223private:
224 wxSocketBase * const m_socket;
225
c0c133e1 226 wxDECLARE_NO_COPY_CLASS(wxSocketReadGuard);
365b8793
VZ
227};
228
229class wxSocketWriteGuard
230{
231public:
232 wxSocketWriteGuard(wxSocketBase *socket)
233 : m_socket(socket)
234 {
235 wxASSERT_MSG( !m_socket->m_writing, "write reentrancy?" );
236
237 m_socket->m_writing = true;
238 }
239
240 ~wxSocketWriteGuard()
241 {
242 m_socket->m_writing = false;
f46a0165
VZ
243
244 wxSocketImpl * const impl = m_socket->m_impl;
245 if ( impl && impl->m_fd != INVALID_SOCKET )
246 impl->ReenableEvents(wxSOCKET_OUTPUT_FLAG);
365b8793
VZ
247 }
248
249private:
250 wxSocketBase * const m_socket;
251
c0c133e1 252 wxDECLARE_NO_COPY_CLASS(wxSocketWriteGuard);
365b8793
VZ
253};
254
2804f77d 255// ============================================================================
51fe4b60 256// wxSocketManager
2804f77d
VZ
257// ============================================================================
258
51fe4b60 259wxSocketManager *wxSocketManager::ms_manager = NULL;
2804f77d
VZ
260
261/* static */
51fe4b60 262void wxSocketManager::Set(wxSocketManager *manager)
2804f77d
VZ
263{
264 wxASSERT_MSG( !ms_manager, "too late to set manager now" );
265
266 ms_manager = manager;
267}
268
269/* static */
51fe4b60 270void wxSocketManager::Init()
2804f77d
VZ
271{
272 wxASSERT_MSG( !ms_manager, "shouldn't be initialized twice" );
273
274 /*
275 Details: Initialize() creates a hidden window as a sink for socket
276 events, such as 'read completed'. wxMSW has only one message loop
277 for the main thread. If Initialize is called in a secondary thread,
278 the socket window will be created for the secondary thread, but
279 since there is no message loop on this thread, it will never
280 receive events and all socket operations will time out.
281 BTW, the main thread must not be stopped using sleep or block
282 on a semaphore (a bad idea in any case) or socket operations
283 will time out.
284
285 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
286 the main thread. Because secondary threads do not have run loops,
287 adding event notifications to the "Current" loop would have no
288 effect at all, events would never fire.
289 */
290 wxASSERT_MSG( wxIsMainThread(),
291 "sockets must be initialized from the main thread" );
292
293 wxAppConsole * const app = wxAppConsole::GetInstance();
294 wxCHECK_RET( app, "sockets can't be initialized without wxApp" );
295
296 ms_manager = app->GetTraits()->GetSocketManager();
297}
298
eb97543d 299// ==========================================================================
51fe4b60 300// wxSocketImpl
eb97543d
VZ
301// ==========================================================================
302
51fe4b60 303wxSocketImpl::wxSocketImpl(wxSocketBase& wxsocket)
53a161e1 304 : m_wxsocket(&wxsocket)
eb97543d
VZ
305{
306 m_fd = INVALID_SOCKET;
51fe4b60 307 m_error = wxSOCKET_NOERROR;
eb97543d
VZ
308 m_server = false;
309 m_stream = true;
53a161e1
VZ
310
311 SetTimeout(wxsocket.GetTimeout() * 1000);
eb97543d
VZ
312
313 m_establishing = false;
314 m_reusable = false;
315 m_broadcast = false;
316 m_dobind = true;
317 m_initialRecvBufferSize = -1;
318 m_initialSendBufferSize = -1;
eb97543d
VZ
319}
320
51fe4b60 321wxSocketImpl::~wxSocketImpl()
eb97543d 322{
c9bccf23 323 if ( m_fd != INVALID_SOCKET )
eb97543d 324 Shutdown();
51fe4b60
VZ
325}
326
c9bccf23 327bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl& addr)
51fe4b60
VZ
328{
329 if ( m_fd != INVALID_SOCKET )
330 {
331 m_error = wxSOCKET_INVSOCK;
332 return false;
333 }
334
c9bccf23 335 if ( !addr.IsOk() )
51fe4b60
VZ
336 {
337 m_error = wxSOCKET_INVADDR;
338 return false;
339 }
340
341 return true;
342}
343
344void wxSocketImpl::PostCreation()
345{
346 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
347#ifdef SO_NOSIGPIPE
348 EnableSocketOption(SO_NOSIGPIPE);
349#endif
350
351 if ( m_reusable )
352 EnableSocketOption(SO_REUSEADDR);
353
354 if ( m_broadcast )
355 {
356 wxASSERT_MSG( !m_stream, "broadcasting is for datagram sockets only" );
357
358 EnableSocketOption(SO_BROADCAST);
359 }
360
361 if ( m_initialRecvBufferSize >= 0 )
362 SetSocketOption(SO_RCVBUF, m_initialRecvBufferSize);
363 if ( m_initialSendBufferSize >= 0 )
364 SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
eb97543d 365
2b036c4b
VZ
366 // we always put our sockets in unblocked mode and handle blocking
367 // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
51fe4b60 368 UnblockAndRegisterWithEventLoop();
eb97543d
VZ
369}
370
51fe4b60
VZ
371wxSocketError wxSocketImpl::UpdateLocalAddress()
372{
7172db18
VZ
373 if ( !m_local.IsOk() )
374 {
375 // ensure that we have a valid object using the correct family: correct
376 // being the same one as our peer uses as we have no other way to
377 // determine it
378 m_local.Create(m_peer.GetFamily());
379 }
380
c9bccf23
VZ
381 WX_SOCKLEN_T lenAddr = m_local.GetLen();
382 if ( getsockname(m_fd, m_local.GetWritableAddr(), &lenAddr) != 0 )
51fe4b60
VZ
383 {
384 Close();
385 m_error = wxSOCKET_IOERR;
386 return m_error;
387 }
388
51fe4b60
VZ
389 return wxSOCKET_NOERROR;
390}
391
392wxSocketError wxSocketImpl::CreateServer()
393{
394 if ( !PreCreateCheck(m_local) )
395 return m_error;
396
397 m_server = true;
398 m_stream = true;
399
400 // do create the socket
c9bccf23 401 m_fd = socket(m_local.GetFamily(), SOCK_STREAM, 0);
51fe4b60
VZ
402
403 if ( m_fd == INVALID_SOCKET )
404 {
405 m_error = wxSOCKET_IOERR;
406 return wxSOCKET_IOERR;
407 }
408
409 PostCreation();
410
411 // and then bind to and listen on it
412 //
413 // FIXME: should we test for m_dobind here?
c9bccf23 414 if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
51fe4b60
VZ
415 m_error = wxSOCKET_IOERR;
416
417 if ( IsOk() )
418 {
419 if ( listen(m_fd, 5) != 0 )
420 m_error = wxSOCKET_IOERR;
421 }
422
423 if ( !IsOk() )
424 {
425 Close();
426 return m_error;
427 }
428
429 // finally retrieve the address we effectively bound to
430 return UpdateLocalAddress();
431}
432
2b036c4b 433wxSocketError wxSocketImpl::CreateClient(bool wait)
51fe4b60
VZ
434{
435 if ( !PreCreateCheck(m_peer) )
436 return m_error;
437
c9bccf23 438 m_fd = socket(m_peer.GetFamily(), SOCK_STREAM, 0);
51fe4b60
VZ
439
440 if ( m_fd == INVALID_SOCKET )
441 {
2b036c4b
VZ
442 m_error = wxSOCKET_IOERR;
443 return wxSOCKET_IOERR;
51fe4b60
VZ
444 }
445
446 PostCreation();
447
448 // If a local address has been set, then bind to it before calling connect
c9bccf23 449 if ( m_local.IsOk() )
51fe4b60 450 {
c9bccf23 451 if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
51fe4b60
VZ
452 {
453 Close();
454 m_error = wxSOCKET_IOERR;
455 return m_error;
456 }
457 }
458
2b036c4b 459 // Do connect now
c9bccf23 460 int rc = connect(m_fd, m_peer.GetAddr(), m_peer.GetLen());
2b036c4b
VZ
461 if ( rc == SOCKET_ERROR )
462 {
463 wxSocketError err = GetLastError();
464 if ( err == wxSOCKET_WOULDBLOCK )
465 {
466 m_establishing = true;
467
468 // block waiting for connection if we should (otherwise just return
469 // wxSOCKET_WOULDBLOCK to the caller)
470 if ( wait )
471 {
472 err = SelectWithTimeout(wxSOCKET_CONNECTION_FLAG)
473 ? wxSOCKET_NOERROR
474 : wxSOCKET_TIMEDOUT;
475 m_establishing = false;
476 }
477 }
478
479 m_error = err;
480 }
481 else // connected
482 {
483 m_error = wxSOCKET_NOERROR;
484 }
485
486 return m_error;
51fe4b60
VZ
487}
488
489
490wxSocketError wxSocketImpl::CreateUDP()
491{
492 if ( !PreCreateCheck(m_local) )
493 return m_error;
494
495 m_stream = false;
496 m_server = false;
497
c9bccf23 498 m_fd = socket(m_local.GetFamily(), SOCK_DGRAM, 0);
51fe4b60
VZ
499
500 if ( m_fd == INVALID_SOCKET )
501 {
502 m_error = wxSOCKET_IOERR;
503 return wxSOCKET_IOERR;
504 }
505
506 PostCreation();
507
508 if ( m_dobind )
509 {
c9bccf23 510 if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
51fe4b60
VZ
511 {
512 Close();
513 m_error = wxSOCKET_IOERR;
514 return m_error;
515 }
516
517 return UpdateLocalAddress();
518 }
519
520 return wxSOCKET_NOERROR;
521}
522
2b036c4b
VZ
523wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket)
524{
c9bccf23 525 wxSockAddressStorage from;
2b036c4b 526 WX_SOCKLEN_T fromlen = sizeof(from);
c9bccf23 527 const SOCKET fd = accept(m_fd, &from.addr, &fromlen);
2b036c4b 528
df21920b
VZ
529 // accepting is similar to reading in the sense that it resets "ready for
530 // read" flag on the socket
531 ReenableEvents(wxSOCKET_INPUT_FLAG);
532
2b036c4b
VZ
533 if ( fd == INVALID_SOCKET )
534 return NULL;
535
4f260c9c
VZ
536 wxSocketManager * const manager = wxSocketManager::Get();
537 if ( !manager )
538 return NULL;
539
540 wxSocketImpl * const sock = manager->CreateSocket(wxsocket);
541 if ( !sock )
542 return NULL;
543
2b036c4b 544 sock->m_fd = fd;
c9bccf23 545 sock->m_peer = wxSockAddressImpl(from.addr, fromlen);
2b036c4b
VZ
546
547 sock->UnblockAndRegisterWithEventLoop();
548
549 return sock;
550}
551
51fe4b60
VZ
552
553void wxSocketImpl::Close()
f0fbbe23
VZ
554{
555 if ( m_fd != INVALID_SOCKET )
556 {
51fe4b60 557 DoClose();
f0fbbe23
VZ
558 m_fd = INVALID_SOCKET;
559 }
560}
561
51fe4b60 562void wxSocketImpl::Shutdown()
eb97543d
VZ
563{
564 if ( m_fd != INVALID_SOCKET )
565 {
566 shutdown(m_fd, 1 /* SD_SEND */);
567 Close();
568 }
eb97543d
VZ
569}
570
51fe4b60 571/*
53a161e1
VZ
572 * Sets the timeout for blocking calls. Time is expressed in
573 * milliseconds.
574 */
51fe4b60 575void wxSocketImpl::SetTimeout(unsigned long millis)
53a161e1 576{
00414faf 577 SetTimeValFromMS(m_timeout, millis);
53a161e1
VZ
578}
579
51fe4b60 580void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event)
53a161e1 581{
51fe4b60 582 m_wxsocket->OnRequest(event);
53a161e1
VZ
583}
584
02564412 585/* Address handling */
c9bccf23 586wxSocketError wxSocketImpl::SetLocal(const wxSockAddressImpl& local)
02564412 587{
c9bccf23
VZ
588 /* the socket must be initialized, or it must be a server */
589 if (m_fd != INVALID_SOCKET && !m_server)
590 {
591 m_error = wxSOCKET_INVSOCK;
592 return wxSOCKET_INVSOCK;
593 }
02564412 594
c9bccf23
VZ
595 if ( !local.IsOk() )
596 {
597 m_error = wxSOCKET_INVADDR;
598 return wxSOCKET_INVADDR;
599 }
02564412 600
c9bccf23 601 m_local = local;
02564412 602
c9bccf23 603 return wxSOCKET_NOERROR;
02564412
VZ
604}
605
c9bccf23 606wxSocketError wxSocketImpl::SetPeer(const wxSockAddressImpl& peer)
02564412 607{
c9bccf23
VZ
608 if ( !peer.IsOk() )
609 {
610 m_error = wxSOCKET_INVADDR;
611 return wxSOCKET_INVADDR;
612 }
02564412 613
c9bccf23 614 m_peer = peer;
02564412 615
c9bccf23 616 return wxSOCKET_NOERROR;
02564412
VZ
617}
618
c9bccf23 619const wxSockAddressImpl& wxSocketImpl::GetLocal()
02564412 620{
c9bccf23
VZ
621 if ( !m_local.IsOk() )
622 UpdateLocalAddress();
02564412 623
c9bccf23 624 return m_local;
02564412
VZ
625}
626
14372de8
VZ
627// ----------------------------------------------------------------------------
628// wxSocketImpl IO
629// ----------------------------------------------------------------------------
630
631// this macro wraps the given expression (normally a syscall) in a loop which
632// ignores any interruptions, i.e. reevaluates it again if it failed and errno
633// is EINTR
634#ifdef __UNIX__
635 #define DO_WHILE_EINTR( rc, syscall ) \
636 do { \
637 rc = (syscall); \
638 } \
639 while ( rc == -1 && errno == EINTR )
640#else
641 #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
642#endif
643
644int wxSocketImpl::RecvStream(void *buffer, int size)
645{
646 int ret;
647 DO_WHILE_EINTR( ret, recv(m_fd, static_cast<char *>(buffer), size, 0) );
648
649 if ( !ret )
650 {
651 // receiving 0 bytes for a TCP socket indicates that the connection was
652 // closed by peer so shut down our end as well (for UDP sockets empty
653 // datagrams are also possible)
654 m_establishing = false;
655 NotifyOnStateChange(wxSOCKET_LOST);
656
657 Shutdown();
658
659 // do not return an error in this case however
660 }
661
662 return ret;
663}
664
665int wxSocketImpl::SendStream(const void *buffer, int size)
666{
335a0bc3 667#ifdef wxNEEDS_IGNORE_SIGPIPE
04b2ab1a
VZ
668 IgnoreSignal ignore(SIGPIPE);
669#endif
670
14372de8
VZ
671 int ret;
672 DO_WHILE_EINTR( ret, send(m_fd, static_cast<const char *>(buffer), size,
673 wxSOCKET_MSG_NOSIGNAL) );
674
675 return ret;
676}
677
678int wxSocketImpl::RecvDgram(void *buffer, int size)
679{
c9bccf23 680 wxSockAddressStorage from;
14372de8
VZ
681 WX_SOCKLEN_T fromlen = sizeof(from);
682
683 int ret;
684 DO_WHILE_EINTR( ret, recvfrom(m_fd, static_cast<char *>(buffer), size,
c9bccf23 685 0, &from.addr, &fromlen) );
14372de8
VZ
686
687 if ( ret == SOCKET_ERROR )
688 return SOCKET_ERROR;
689
c9bccf23
VZ
690 m_peer = wxSockAddressImpl(from.addr, fromlen);
691 if ( !m_peer.IsOk() )
14372de8 692 return -1;
14372de8
VZ
693
694 return ret;
695}
696
697int wxSocketImpl::SendDgram(const void *buffer, int size)
698{
c9bccf23 699 if ( !m_peer.IsOk() )
14372de8
VZ
700 {
701 m_error = wxSOCKET_INVADDR;
702 return -1;
703 }
704
14372de8
VZ
705 int ret;
706 DO_WHILE_EINTR( ret, sendto(m_fd, static_cast<const char *>(buffer), size,
c9bccf23 707 0, m_peer.GetAddr(), m_peer.GetLen()) );
14372de8
VZ
708
709 return ret;
710}
711
712int wxSocketImpl::Read(void *buffer, int size)
713{
714 // server sockets can't be used for IO, only to accept new connections
715 if ( m_fd == INVALID_SOCKET || m_server )
716 {
717 m_error = wxSOCKET_INVSOCK;
718 return -1;
719 }
720
721 int ret = m_stream ? RecvStream(buffer, size)
722 : RecvDgram(buffer, size);
723
724 m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
725
726 return ret;
727}
728
729int wxSocketImpl::Write(const void *buffer, int size)
730{
731 if ( m_fd == INVALID_SOCKET || m_server )
732 {
733 m_error = wxSOCKET_INVSOCK;
734 return -1;
735 }
736
737 int ret = m_stream ? SendStream(buffer, size)
738 : SendDgram(buffer, size);
739
740 m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
741
742 return ret;
743}
744
ef57d866
GRG
745// ==========================================================================
746// wxSocketBase
747// ==========================================================================
748
6c0d0845
VZ
749// --------------------------------------------------------------------------
750// Initialization and shutdown
751// --------------------------------------------------------------------------
752
753// FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
754// to m_countInit with a crit section
755size_t wxSocketBase::m_countInit = 0;
756
757bool wxSocketBase::IsInitialized()
758{
759 return m_countInit > 0;
760}
761
762bool wxSocketBase::Initialize()
763{
764 if ( !m_countInit++ )
765 {
51fe4b60
VZ
766 wxSocketManager * const manager = wxSocketManager::Get();
767 if ( !manager || !manager->OnInit() )
6c0d0845
VZ
768 {
769 m_countInit--;
770
d775fa82 771 return false;
6c0d0845
VZ
772 }
773 }
774
d775fa82 775 return true;
6c0d0845
VZ
776}
777
778void wxSocketBase::Shutdown()
779{
780 // we should be initialized
9a83f860 781 wxASSERT_MSG( m_countInit > 0, wxT("extra call to Shutdown()") );
8d7eaf91 782 if ( --m_countInit == 0 )
6c0d0845 783 {
51fe4b60
VZ
784 wxSocketManager * const manager = wxSocketManager::Get();
785 wxCHECK_RET( manager, "should have a socket manager" );
786
787 manager->OnExit();
6c0d0845
VZ
788 }
789}
790
ef57d866
GRG
791// --------------------------------------------------------------------------
792// Ctor and dtor
793// --------------------------------------------------------------------------
56d8adc0 794
71622a7a 795void wxSocketBase::Init()
f4ada568 796{
365b8793 797 m_impl = NULL;
c2116a35
VZ
798 m_type = wxSOCKET_UNINIT;
799
800 // state
801 m_flags = 0;
802 m_connected =
803 m_establishing =
804 m_reading =
805 m_writing =
c2116a35
VZ
806 m_closed = false;
807 m_lcount = 0;
808 m_timeout = 600;
809 m_beingDeleted = false;
810
811 // pushback buffer
812 m_unread = NULL;
813 m_unrd_size = 0;
814 m_unrd_cur = 0;
815
816 // events
817 m_id = wxID_ANY;
818 m_handler = NULL;
819 m_clientData = NULL;
820 m_notify = false;
5c1193e0
VZ
821 m_eventmask =
822 m_eventsgot = 0;
c2116a35
VZ
823
824 if ( !IsInitialized() )
825 {
826 // this Initialize() will be undone by wxSocketModule::OnExit(), all
827 // the other calls to it should be matched by a call to Shutdown()
54e757fc 828 if (!Initialize())
af588446 829 {
54e757fc 830 wxLogError("Cannot initialize wxSocketBase");
af588446 831 }
c2116a35 832 }
f4ada568
GL
833}
834
f187448d
GRG
835wxSocketBase::wxSocketBase()
836{
c2116a35 837 Init();
f187448d 838}
71622a7a
GRG
839
840wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
f4ada568 841{
c2116a35 842 Init();
71622a7a 843
cc0972a2
VZ
844 SetFlags(flags);
845
846 m_type = type;
f4ada568
GL
847}
848
f4ada568
GL
849wxSocketBase::~wxSocketBase()
850{
c2116a35
VZ
851 // Shutdown and close the socket
852 if (!m_beingDeleted)
853 Close();
9181a383 854
51fe4b60
VZ
855 // Destroy the implementation object
856 delete m_impl;
c2116a35
VZ
857
858 // Free the pushback buffer
3185abc2 859 free(m_unread);
f4ada568
GL
860}
861
ef57d866
GRG
862bool wxSocketBase::Destroy()
863{
c2116a35
VZ
864 // Delayed destruction: the socket will be deleted during the next idle
865 // loop iteration. This ensures that all pending events have been
866 // processed.
867 m_beingDeleted = true;
868
869 // Shutdown and close the socket
870 Close();
871
22185a1f 872 // Suppress events from now on
c2116a35
VZ
873 Notify(false);
874
3185abc2
VZ
875 // Schedule this object for deletion instead of destroying it right now if
876 // possible as we may have other events pending for it
877 if ( wxTheApp )
c2116a35 878 {
3185abc2 879 wxTheApp->ScheduleForDestruction(this);
c2116a35 880 }
3185abc2 881 else // no app
c2116a35
VZ
882 {
883 // in wxBase we might have no app object at all, don't leak memory
884 delete this;
885 }
886
887 return true;
ef57d866 888}
9181a383 889
51fe4b60 890// ----------------------------------------------------------------------------
64b1cea0 891// simple accessors
51fe4b60
VZ
892// ----------------------------------------------------------------------------
893
64b1cea0
VZ
894void wxSocketBase::SetError(wxSocketError error)
895{
896 m_impl->m_error = error;
897}
898
51fe4b60
VZ
899wxSocketError wxSocketBase::LastError() const
900{
901 return m_impl->GetError();
902}
903
ef57d866 904// --------------------------------------------------------------------------
bffc1eaa 905// Basic IO calls
ef57d866
GRG
906// --------------------------------------------------------------------------
907
64b1cea0 908// The following IO operations update m_lcount:
ef57d866 909// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
f4ada568
GL
910bool wxSocketBase::Close()
911{
c2116a35
VZ
912 // Interrupt pending waits
913 InterruptWait();
914
b67397a7 915 ShutdownOutput();
c2116a35
VZ
916
917 m_connected = false;
918 m_establishing = false;
919 return true;
f4ada568
GL
920}
921
b67397a7
VZ
922void wxSocketBase::ShutdownOutput()
923{
924 if ( m_impl )
925 m_impl->Shutdown();
926}
927
f187448d 928wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
f4ada568 929{
365b8793 930 wxSocketReadGuard read(this);
a324a7bc 931
cc0972a2 932 m_lcount = DoRead(buffer, nbytes);
17aa2bec 933
c2116a35 934 return *this;
96db102a
GRG
935}
936
cc0972a2 937wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
96db102a 938{
f5395600
VZ
939 wxCHECK_MSG( m_impl, 0, "socket must be valid" );
940
cc0972a2
VZ
941 // We use pointer arithmetic here which doesn't work with void pointers.
942 char *buffer = static_cast<char *>(buffer_);
f5395600 943 wxCHECK_MSG( buffer, 0, "NULL buffer" );
c2116a35 944
cc0972a2
VZ
945 // Try the push back buffer first, even before checking whether the socket
946 // is valid to allow reading previously pushed back data from an already
947 // closed socket.
948 wxUint32 total = GetPushback(buffer, nbytes, false);
c2116a35 949 nbytes -= total;
cc0972a2 950 buffer += total;
c2116a35 951
f5395600 952 while ( nbytes )
cc0972a2 953 {
f5395600
VZ
954 // our socket is non-blocking so Read() will return immediately if
955 // there is nothing to read yet and it's more efficient to try it first
6f405b31
VZ
956 // before entering DoWait() which is going to start dispatching GUI
957 // events and, even more importantly, we must do this under Windows
f5395600
VZ
958 // where we're not going to get notifications about socket being ready
959 // for reading before we read all the existing data from it
d34f724d
VZ
960 const int ret = !m_impl->m_stream || m_connected
961 ? m_impl->Read(buffer, nbytes)
962 : 0;
64b1cea0
VZ
963 if ( ret == -1 )
964 {
f5395600 965 if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
c2116a35 966 {
f5395600
VZ
967 // if we don't want to wait, just return immediately
968 if ( m_flags & wxSOCKET_NOWAIT )
969 break;
c2116a35 970
6f405b31
VZ
971 // otherwise wait until the socket becomes ready for reading or
972 // an error occurs on it
ebbf7407 973 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG) )
f5395600
VZ
974 {
975 // and exit if the timeout elapsed before it did
976 SetError(wxSOCKET_TIMEDOUT);
977 break;
978 }
c2116a35 979
f5395600
VZ
980 // retry reading
981 continue;
982 }
983 else // "real" error
984 {
985 SetError(wxSOCKET_IOERR);
c2116a35 986 break;
f5395600
VZ
987 }
988 }
989 else if ( ret == 0 )
990 {
991 // for connection-oriented (e.g. TCP) sockets we can only read
992 // 0 bytes if the other end has been closed, and for connectionless
993 // ones (UDP) this flag doesn't make sense anyhow so we can set it
994 // to true too without doing any harm
995 m_closed = true;
996
997 // we're not going to read anything else and so if we haven't read
998 // anything (or not everything in wxSOCKET_WAITALL case) already,
999 // signal an error
1000 if ( (m_flags & wxSOCKET_WAITALL) || !total )
1001 SetError(wxSOCKET_IOERR);
1002 break;
1003 }
c2116a35 1004
f5395600 1005 total += ret;
c2116a35 1006
f5395600
VZ
1007 // if we are happy to read something and not the entire nbytes bytes,
1008 // then we're done
1009 if ( !(m_flags & wxSOCKET_WAITALL) )
1010 break;
64b1cea0 1011
f5395600
VZ
1012 nbytes -= ret;
1013 buffer += ret;
c2116a35 1014 }
96db102a 1015
96db102a 1016 return total;
c2116a35 1017}
f4ada568 1018
c2116a35
VZ
1019wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
1020{
c2116a35
VZ
1021 struct
1022 {
1023 unsigned char sig[4];
1024 unsigned char len[4];
1025 } msg;
1026
365b8793 1027 wxSocketReadGuard read(this);
c2116a35 1028
365b8793 1029 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL);
c9157492 1030
64b1cea0
VZ
1031 bool ok = false;
1032 if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
56d8adc0 1033 {
64b1cea0
VZ
1034 wxUint32 sig = (wxUint32)msg.sig[0];
1035 sig |= (wxUint32)(msg.sig[1] << 8);
1036 sig |= (wxUint32)(msg.sig[2] << 16);
1037 sig |= (wxUint32)(msg.sig[3] << 24);
f4ada568 1038
64b1cea0
VZ
1039 if ( sig == 0xfeeddead )
1040 {
1041 wxUint32 len = (wxUint32)msg.len[0];
1042 len |= (wxUint32)(msg.len[1] << 8);
1043 len |= (wxUint32)(msg.len[2] << 16);
1044 len |= (wxUint32)(msg.len[3] << 24);
f4ada568 1045
64b1cea0
VZ
1046 wxUint32 len2;
1047 if (len > nbytes)
1048 {
1049 len2 = len - nbytes;
1050 len = nbytes;
1051 }
1052 else
1053 len2 = 0;
c2116a35 1054
64b1cea0
VZ
1055 // Don't attempt to read if the msg was zero bytes long.
1056 m_lcount = len ? DoRead(buffer, len) : 0;
c2116a35 1057
64b1cea0
VZ
1058 if ( len2 )
1059 {
1060 char discard_buffer[MAX_DISCARD_SIZE];
1061 long discard_len;
1062
1063 // NOTE: discarded bytes don't add to m_lcount.
1064 do
1065 {
1066 discard_len = len2 > MAX_DISCARD_SIZE
1067 ? MAX_DISCARD_SIZE
1068 : len2;
1069 discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
1070 len2 -= (wxUint32)discard_len;
1071 }
1072 while ((discard_len > 0) && len2);
1073 }
17aa2bec 1074
64b1cea0
VZ
1075 if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1076 {
1077 sig = (wxUint32)msg.sig[0];
1078 sig |= (wxUint32)(msg.sig[1] << 8);
1079 sig |= (wxUint32)(msg.sig[2] << 16);
1080 sig |= (wxUint32)(msg.sig[3] << 24);
c2116a35 1081
64b1cea0
VZ
1082 if ( sig == 0xdeadfeed )
1083 ok = true;
1084 }
c2116a35 1085 }
c2116a35 1086 }
062c4861 1087
64b1cea0
VZ
1088 if ( !ok )
1089 SetError(wxSOCKET_IOERR);
96db102a 1090
c2116a35 1091 return *this;
062c4861
GL
1092}
1093
f187448d 1094wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
f4ada568 1095{
365b8793 1096 wxSocketReadGuard read(this);
96db102a 1097
cc0972a2 1098 m_lcount = DoRead(buffer, nbytes);
96db102a 1099
365b8793 1100 Pushback(buffer, m_lcount);
f4ada568 1101
c2116a35 1102 return *this;
f4ada568
GL
1103}
1104
f187448d 1105wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
f4ada568 1106{
365b8793 1107 wxSocketWriteGuard write(this);
56d8adc0 1108
cc0972a2 1109 m_lcount = DoWrite(buffer, nbytes);
96db102a 1110
c2116a35 1111 return *this;
96db102a
GRG
1112}
1113
cc0972a2 1114// This function is a mirror image of DoRead() except that it doesn't use the
f5395600
VZ
1115// push back buffer and doesn't treat 0 return value specially (normally this
1116// shouldn't happen at all here), so please see comments there for explanations
cc0972a2 1117wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
96db102a 1118{
f5395600
VZ
1119 wxCHECK_MSG( m_impl, 0, "socket must be valid" );
1120
cc0972a2 1121 const char *buffer = static_cast<const char *>(buffer_);
f5395600 1122 wxCHECK_MSG( buffer, 0, "NULL buffer" );
c2116a35 1123
cc0972a2 1124 wxUint32 total = 0;
f5395600 1125 while ( nbytes )
cc0972a2 1126 {
d34f724d 1127 if ( m_impl->m_stream && !m_connected )
f1763270
VZ
1128 {
1129 if ( (m_flags & wxSOCKET_WAITALL) || !total )
1130 SetError(wxSOCKET_IOERR);
1131 break;
1132 }
1133
51fe4b60 1134 const int ret = m_impl->Write(buffer, nbytes);
64b1cea0
VZ
1135 if ( ret == -1 )
1136 {
f5395600 1137 if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
c2116a35 1138 {
f5395600
VZ
1139 if ( m_flags & wxSOCKET_NOWAIT )
1140 break;
5c9eff30 1141
ebbf7407 1142 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG) )
f5395600
VZ
1143 {
1144 SetError(wxSOCKET_TIMEDOUT);
1145 break;
1146 }
a324a7bc 1147
f5395600
VZ
1148 continue;
1149 }
1150 else // "real" error
1151 {
1152 SetError(wxSOCKET_IOERR);
c2116a35 1153 break;
f5395600
VZ
1154 }
1155 }
c9157492 1156
f5395600 1157 total += ret;
c9157492 1158
f5395600
VZ
1159 if ( !(m_flags & wxSOCKET_WAITALL) )
1160 break;
64b1cea0 1161
f5395600
VZ
1162 nbytes -= ret;
1163 buffer += ret;
81b92e17 1164 }
a324a7bc 1165
c2116a35 1166 return total;
f4ada568
GL
1167}
1168
f187448d 1169wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
062c4861 1170{
c2116a35
VZ
1171 struct
1172 {
1173 unsigned char sig[4];
1174 unsigned char len[4];
1175 } msg;
062c4861 1176
365b8793 1177 wxSocketWriteGuard write(this);
96db102a 1178
365b8793 1179 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL);
96db102a 1180
c2116a35
VZ
1181 msg.sig[0] = (unsigned char) 0xad;
1182 msg.sig[1] = (unsigned char) 0xde;
1183 msg.sig[2] = (unsigned char) 0xed;
1184 msg.sig[3] = (unsigned char) 0xfe;
062c4861 1185
c2116a35
VZ
1186 msg.len[0] = (unsigned char) (nbytes & 0xff);
1187 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1188 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1189 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
17aa2bec 1190
64b1cea0
VZ
1191 bool ok = false;
1192 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
1193 {
1194 m_lcount = DoWrite(buffer, nbytes);
1195 if ( m_lcount == nbytes )
1196 {
1197 msg.sig[0] = (unsigned char) 0xed;
1198 msg.sig[1] = (unsigned char) 0xfe;
1199 msg.sig[2] = (unsigned char) 0xad;
1200 msg.sig[3] = (unsigned char) 0xde;
1201 msg.len[0] =
1202 msg.len[1] =
1203 msg.len[2] =
1204 msg.len[3] = (char) 0;
1205
1206 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
1207 ok = true;
1208 }
1209 }
17aa2bec 1210
64b1cea0
VZ
1211 if ( !ok )
1212 SetError(wxSOCKET_IOERR);
96db102a 1213
c2116a35 1214 return *this;
062c4861
GL
1215}
1216
f187448d 1217wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
f4ada568 1218{
c2116a35
VZ
1219 if (nbytes != 0)
1220 Pushback(buffer, nbytes);
f4ada568 1221
64b1cea0 1222 SetError(wxSOCKET_NOERROR);
c2116a35 1223 m_lcount = nbytes;
f4ada568 1224
c2116a35 1225 return *this;
a324a7bc
GL
1226}
1227
96db102a 1228wxSocketBase& wxSocketBase::Discard()
f4ada568 1229{
c2116a35
VZ
1230 char *buffer = new char[MAX_DISCARD_SIZE];
1231 wxUint32 ret;
1232 wxUint32 total = 0;
f4ada568 1233
365b8793 1234 wxSocketReadGuard read(this);
96db102a 1235
365b8793 1236 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
384b4373 1237
c2116a35
VZ
1238 do
1239 {
cc0972a2 1240 ret = DoRead(buffer, MAX_DISCARD_SIZE);
c2116a35
VZ
1241 total += ret;
1242 }
1243 while (ret == MAX_DISCARD_SIZE);
f4ada568 1244
c2116a35
VZ
1245 delete[] buffer;
1246 m_lcount = total;
64b1cea0 1247 SetError(wxSOCKET_NOERROR);
17aa2bec 1248
c2116a35 1249 return *this;
f4ada568
GL
1250}
1251
ef57d866
GRG
1252// --------------------------------------------------------------------------
1253// Wait functions
1254// --------------------------------------------------------------------------
f4ada568 1255
51fe4b60 1256/*
00414faf
VZ
1257 This function will check for the events specified in the flags parameter,
1258 and it will return a mask indicating which operations can be performed.
f0db5d75 1259 */
00414faf 1260wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
2b036c4b 1261 const timeval *timeout)
f0db5d75 1262{
5e9238f9
VZ
1263 if ( m_fd == INVALID_SOCKET )
1264 return (wxSOCKET_LOST_FLAG & flags);
f0db5d75 1265
5e9238f9
VZ
1266 struct timeval tv;
1267 if ( timeout )
1268 tv = *timeout;
1269 else
1270 tv.tv_sec = tv.tv_usec = 0;
f0db5d75 1271
5e9238f9
VZ
1272 // prepare the FD sets, passing NULL for the one(s) we don't use
1273 fd_set
1274 readfds, *preadfds = NULL,
1275 writefds, *pwritefds = NULL,
1276 exceptfds; // always want to know about errors
f0db5d75 1277
5e9238f9
VZ
1278 if ( flags & wxSOCKET_INPUT_FLAG )
1279 {
1280 preadfds = &readfds;
1281 wxFD_ZERO(preadfds);
1282 wxFD_SET(m_fd, preadfds);
1283 }
f0db5d75 1284
5e9238f9
VZ
1285 // when using non-blocking connect() the socket becomes connected
1286 // (successfully or not) when it becomes writable
1287 if ( flags & (wxSOCKET_OUTPUT_FLAG | wxSOCKET_CONNECTION_FLAG) )
1288 {
1289 pwritefds = &writefds;
1290 wxFD_ZERO(pwritefds);
1291 wxFD_SET(m_fd, pwritefds);
1292 }
f0db5d75 1293
5e9238f9
VZ
1294 wxFD_ZERO(&exceptfds);
1295 wxFD_SET(m_fd, &exceptfds);
f0db5d75 1296
5e9238f9
VZ
1297 const int rc = select(m_fd + 1, preadfds, pwritefds, &exceptfds, &tv);
1298
1299 // check for errors first
1300 if ( rc == -1 || wxFD_ISSET(m_fd, &exceptfds) )
f0db5d75 1301 {
5e9238f9
VZ
1302 m_establishing = false;
1303
1304 return wxSOCKET_LOST_FLAG & flags;
f0db5d75 1305 }
f0db5d75 1306
5e9238f9
VZ
1307 if ( rc == 0 )
1308 return 0;
f0db5d75 1309
5e9238f9 1310 wxASSERT_MSG( rc == 1, "unexpected select() return value" );
f0db5d75 1311
5e9238f9
VZ
1312 wxSocketEventFlags detected = 0;
1313 if ( preadfds && wxFD_ISSET(m_fd, preadfds) )
1314 detected |= wxSOCKET_INPUT_FLAG;
1315
1316 if ( pwritefds && wxFD_ISSET(m_fd, pwritefds) )
f0db5d75 1317 {
5e9238f9
VZ
1318 // check for the case of non-blocking connect()
1319 if ( m_establishing && !m_server )
1320 {
1321 int error;
1322 SOCKOPTLEN_T len = sizeof(error);
1323 m_establishing = false;
1324 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1325
1326 if ( error )
1327 detected = wxSOCKET_LOST_FLAG;
1328 else
1329 detected |= wxSOCKET_CONNECTION_FLAG;
1330 }
1331 else // not called to get non-blocking connect() status
1332 {
1333 detected |= wxSOCKET_OUTPUT_FLAG;
1334 }
f0db5d75 1335 }
f0db5d75 1336
5e9238f9 1337 return detected & flags;
f0db5d75
VZ
1338}
1339
ebbf7407 1340int
60ee0172 1341wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
6f405b31
VZ
1342{
1343 // Use either the provided timeout or the default timeout value associated
1344 // with this socket.
1345 //
1346 // TODO: allow waiting forever, see #9443
1347 const long timeout = seconds == -1 ? m_timeout * 1000
1348 : seconds * 1000 + milliseconds;
1349
1350 return DoWait(timeout, flags);
1351}
1352
ebbf7407 1353int
6f405b31 1354wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags)
375abe3d 1355{
ebbf7407 1356 wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" );
375abe3d 1357
1b4b6080
VZ
1358 // we're never going to become ready in a client if we're not connected any
1359 // more (OTOH a server can call this to precisely wait for a connection so
1360 // do wait for it in this case)
1361 if ( !m_impl->IsServer() && !m_connected && !m_establishing )
ebbf7407 1362 return -1;
9588640d 1363
60ee0172 1364 // This can be set to true from Interrupt() to exit this function a.s.a.p.
c2116a35 1365 m_interrupt = false;
81b92e17 1366
af2fd961 1367
60ee0172
VZ
1368 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1369
1370 // Get the active event loop which we'll use for the message dispatching
2b036c4b
VZ
1371 // when running in the main thread unless this was explicitly disabled by
1372 // setting wxSOCKET_BLOCK flag
60ee0172 1373 wxEventLoopBase *eventLoop;
2b036c4b 1374 if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
60ee0172
VZ
1375 {
1376 eventLoop = wxEventLoop::GetActive();
60ee0172
VZ
1377 }
1378 else // in worker thread
af2fd961 1379 {
60ee0172
VZ
1380 // We never dispatch messages from threads other than the main one.
1381 eventLoop = NULL;
af2fd961
GRG
1382 }
1383
5ab2f257
VZ
1384 // Make sure the events we're interested in are enabled before waiting for
1385 // them: this is really necessary here as otherwise this could happen:
1386 // 1. DoRead(wxSOCKET_WAITALL) is called
1387 // 2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called
1388 // 3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting()
1389 // is called and wxSOCKET_INPUT_FLAG events are disabled in it
1390 // 4. Because of wxSOCKET_WAITALL we call DoWait() again but the events
1391 // are still disabled and we block forever
1392 //
1393 // More elegant solution would be nice but for now simply re-enabling the
1394 // events here will do
1395 m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG));
1396
1397
00414faf
VZ
1398 // Wait until we receive the event we're waiting for or the timeout expires
1399 // (but note that we always execute the loop at least once, even if timeout
1400 // is 0 as this is used for polling)
ebbf7407
VZ
1401 int rc = 0;
1402 for ( bool firstTime = true; !m_interrupt; firstTime = false )
af2fd961 1403 {
00414faf
VZ
1404 long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
1405 if ( timeLeft < 0 )
1406 {
1407 if ( !firstTime )
1408 break; // timed out
1409
1410 timeLeft = 0;
1411 }
1412
2f1c8faf
VZ
1413 wxSocketEventFlags events;
1414 if ( eventLoop )
1415 {
00414faf
VZ
1416 // reset them before starting to wait
1417 m_eventsgot = 0;
1418
1419 eventLoop->DispatchTimeout(timeLeft);
2f1c8faf
VZ
1420
1421 events = m_eventsgot;
1422 }
00414faf
VZ
1423 else // no event loop or waiting in another thread
1424 {
1425 // as explained below, we should always check for wxSOCKET_LOST_FLAG
2b036c4b
VZ
1426 timeval tv;
1427 SetTimeValFromMS(tv, timeLeft);
1428 events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
00414faf
VZ
1429 }
1430
1431 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1432 // it, as continuing to wait for anything else after getting it is
1433 // pointless
1434 if ( events & wxSOCKET_LOST_FLAG )
2f1c8faf 1435 {
00414faf
VZ
1436 m_connected = false;
1437 m_establishing = false;
ebbf7407 1438 rc = -1;
00414faf 1439 break;
2f1c8faf 1440 }
60ee0172 1441
00414faf
VZ
1442 // otherwise mask out the bits we're not interested in
1443 events &= flags;
1444
60ee0172 1445 // Incoming connection (server) or connection established (client)?
2f1c8faf 1446 if ( events & wxSOCKET_CONNECTION_FLAG )
c2116a35
VZ
1447 {
1448 m_connected = true;
1449 m_establishing = false;
ebbf7407 1450 rc = true;
c2116a35
VZ
1451 break;
1452 }
c0043a50 1453
60ee0172 1454 // Data available or output buffer ready?
2f1c8faf 1455 if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
b8d1915d 1456 {
ebbf7407 1457 rc = true;
c2116a35 1458 break;
b8d1915d 1459 }
f01bca89 1460 }
f4ada568 1461
ebbf7407 1462 return rc;
f4ada568 1463}
f4ada568 1464
a737331d 1465bool wxSocketBase::Wait(long seconds, long milliseconds)
f4ada568 1466{
60ee0172 1467 return DoWait(seconds, milliseconds,
ebbf7407
VZ
1468 wxSOCKET_INPUT_FLAG |
1469 wxSOCKET_OUTPUT_FLAG |
1470 wxSOCKET_CONNECTION_FLAG) != 0;
f4ada568 1471}
f4ada568 1472
a737331d 1473bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
f4ada568 1474{
60ee0172
VZ
1475 // Check pushback buffer before entering DoWait
1476 if ( m_unread )
c2116a35 1477 return true;
96db102a 1478
6f405b31
VZ
1479 // Check if the socket is not already ready for input, if it is, there is
1480 // no need to start waiting for it (worse, we'll actually never get a
1481 // notification about the socket becoming ready if it is already under
1482 // Windows)
1483 if ( m_impl->Select(wxSOCKET_INPUT_FLAG) )
1484 return true;
1485
ebbf7407 1486 return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG) != 0;
f4ada568
GL
1487}
1488
bfa7bf7d 1489
a737331d 1490bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
f4ada568 1491{
6f405b31
VZ
1492 if ( m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
1493 return true;
1494
ebbf7407 1495 return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG) != 0;
a737331d 1496}
f4ada568 1497
a737331d
GL
1498bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1499{
ebbf7407 1500 return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG) == -1;
f4ada568 1501}
a737331d 1502
ef57d866
GRG
1503// --------------------------------------------------------------------------
1504// Miscellaneous
1505// --------------------------------------------------------------------------
1506
1507//
1508// Get local or peer address
1509//
1510
c9bccf23 1511bool wxSocketBase::GetPeer(wxSockAddress& addr) const
ef57d866 1512{
c9bccf23 1513 wxCHECK_MSG( m_impl, false, "invalid socket" );
ef57d866 1514
c9bccf23
VZ
1515 const wxSockAddressImpl& peer = m_impl->GetPeer();
1516 if ( !peer.IsOk() )
c2116a35 1517 return false;
007c77ab 1518
c9bccf23 1519 addr.SetAddress(peer);
ef57d866 1520
c2116a35 1521 return true;
ef57d866
GRG
1522}
1523
c9bccf23 1524bool wxSocketBase::GetLocal(wxSockAddress& addr) const
ef57d866 1525{
c9bccf23 1526 wxCHECK_MSG( m_impl, false, "invalid socket" );
ef57d866 1527
c9bccf23
VZ
1528 const wxSockAddressImpl& local = m_impl->GetLocal();
1529 if ( !local.IsOk() )
7fb0a11d 1530 return false;
ef57d866 1531
c9bccf23 1532 addr.SetAddress(local);
ef57d866 1533
7fb0a11d 1534 return true;
ef57d866
GRG
1535}
1536
1537//
1538// Save and restore socket state
1539//
1540
1541void wxSocketBase::SaveState()
1542{
7fb0a11d 1543 wxSocketState *state;
ef57d866 1544
7fb0a11d 1545 state = new wxSocketState();
ef57d866 1546
7fb0a11d
WS
1547 state->m_flags = m_flags;
1548 state->m_notify = m_notify;
1549 state->m_eventmask = m_eventmask;
1550 state->m_clientData = m_clientData;
ef57d866 1551
7fb0a11d 1552 m_states.Append(state);
ef57d866
GRG
1553}
1554
1555void wxSocketBase::RestoreState()
1556{
7fb0a11d
WS
1557 wxList::compatibility_iterator node;
1558 wxSocketState *state;
ef57d866 1559
7fb0a11d
WS
1560 node = m_states.GetLast();
1561 if (!node)
1562 return;
ef57d866 1563
7fb0a11d 1564 state = (wxSocketState *)node->GetData();
ef57d866 1565
7fb0a11d
WS
1566 m_flags = state->m_flags;
1567 m_notify = state->m_notify;
1568 m_eventmask = state->m_eventmask;
1569 m_clientData = state->m_clientData;
37340c48 1570
7fb0a11d
WS
1571 m_states.Erase(node);
1572 delete state;
ef57d866
GRG
1573}
1574
1575//
1576// Timeout and flags
1577//
1578
17aa2bec
GRG
1579void wxSocketBase::SetTimeout(long seconds)
1580{
7fb0a11d 1581 m_timeout = seconds;
17aa2bec 1582
51fe4b60
VZ
1583 if (m_impl)
1584 m_impl->SetTimeout(m_timeout * 1000);
17aa2bec
GRG
1585}
1586
71622a7a 1587void wxSocketBase::SetFlags(wxSocketFlags flags)
f4ada568 1588{
cc0972a2
VZ
1589 // Do some sanity checking on the flags used: not all values can be used
1590 // together.
1591 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1592 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1593 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1594 "wxSOCKET_NOWAIT doesn't make sense" );
1595
7fb0a11d 1596 m_flags = flags;
f4ada568 1597}
f0a56ab0 1598
f187448d 1599
ef57d866 1600// --------------------------------------------------------------------------
f187448d 1601// Event handling
ef57d866 1602// --------------------------------------------------------------------------
a324a7bc 1603
bffc1eaa 1604void wxSocketBase::OnRequest(wxSocketNotify notification)
f4ada568 1605{
c2116a35 1606 wxSocketEventFlags flag = 0;
5c1193e0 1607 switch ( notification )
c2116a35 1608 {
5c1193e0
VZ
1609 case wxSOCKET_INPUT:
1610 flag = wxSOCKET_INPUT_FLAG;
1611 break;
1612
1613 case wxSOCKET_OUTPUT:
1614 flag = wxSOCKET_OUTPUT_FLAG;
1615 break;
1616
1617 case wxSOCKET_CONNECTION:
1618 flag = wxSOCKET_CONNECTION_FLAG;
40a983ad
VZ
1619
1620 // we're now successfully connected
1621 m_connected = true;
609aa390
VZ
1622 m_establishing = false;
1623
1624 // error was previously set to wxSOCKET_WOULDBLOCK, but this is not
1625 // the case any longer
1626 SetError(wxSOCKET_NOERROR);
5c1193e0
VZ
1627 break;
1628
1629 case wxSOCKET_LOST:
1630 flag = wxSOCKET_LOST_FLAG;
40a983ad 1631
9038fc94
VZ
1632 // if we lost the connection the socket is now closed and not
1633 // connected any more
1634 m_connected = false;
40a983ad 1635 m_closed = true;
5c1193e0
VZ
1636 break;
1637
c2116a35 1638 default:
5c1193e0 1639 wxFAIL_MSG( "unknown wxSocket notification" );
c2116a35
VZ
1640 }
1641
5c1193e0
VZ
1642 // remember the events which were generated for this socket, we're going to
1643 // use this in DoWait()
1644 m_eventsgot |= flag;
1645
1646 // send the wx event if enabled and we're interested in it
1647 if ( m_notify && (m_eventmask & flag) && m_handler )
c2116a35 1648 {
0ed00ab5
VZ
1649 // don't generate the events when we're inside DoWait() called from our
1650 // own code as we are going to consume the data that has just become
1651 // available ourselves and the user code won't see it at all
1652 if ( (notification == wxSOCKET_INPUT && m_reading) ||
1653 (notification == wxSOCKET_OUTPUT && m_writing) )
1654 {
1655 return;
1656 }
1657
5c1193e0
VZ
1658 wxSocketEvent event(m_id);
1659 event.m_event = notification;
1660 event.m_clientData = m_clientData;
1661 event.SetEventObject(this);
c2116a35 1662
5c1193e0 1663 m_handler->AddPendingEvent(event);
bffc1eaa 1664 }
f4ada568
GL
1665}
1666
f187448d
GRG
1667void wxSocketBase::Notify(bool notify)
1668{
7fb0a11d 1669 m_notify = notify;
f187448d
GRG
1670}
1671
1672void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1673{
7fb0a11d 1674 m_eventmask = flags;
f187448d
GRG
1675}
1676
71622a7a 1677void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
f4ada568 1678{
7fb0a11d
WS
1679 m_handler = &handler;
1680 m_id = id;
f4ada568
GL
1681}
1682
ef57d866
GRG
1683// --------------------------------------------------------------------------
1684// Pushback buffer
1685// --------------------------------------------------------------------------
db131261 1686
f187448d 1687void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
f4ada568 1688{
c2116a35 1689 if (!size) return;
dc5c1114 1690
c2116a35
VZ
1691 if (m_unread == NULL)
1692 m_unread = malloc(size);
1693 else
1694 {
1695 void *tmp;
f4ada568 1696
c2116a35
VZ
1697 tmp = malloc(m_unrd_size + size);
1698 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1699 free(m_unread);
a324a7bc 1700
c2116a35
VZ
1701 m_unread = tmp;
1702 }
31528cd3 1703
c2116a35 1704 m_unrd_size += size;
a324a7bc 1705
c2116a35 1706 memcpy(m_unread, buffer, size);
f4ada568
GL
1707}
1708
f187448d 1709wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
f4ada568 1710{
cc0972a2
VZ
1711 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1712
c2116a35
VZ
1713 if (!m_unrd_size)
1714 return 0;
f4ada568 1715
c2116a35
VZ
1716 if (size > (m_unrd_size-m_unrd_cur))
1717 size = m_unrd_size-m_unrd_cur;
96db102a 1718
c2116a35 1719 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
f4ada568 1720
c2116a35 1721 if (!peek)
dc5c1114 1722 {
c2116a35
VZ
1723 m_unrd_cur += size;
1724 if (m_unrd_size == m_unrd_cur)
1725 {
1726 free(m_unread);
1727 m_unread = NULL;
1728 m_unrd_size = 0;
1729 m_unrd_cur = 0;
1730 }
f4ada568 1731 }
f4ada568 1732
c2116a35 1733 return size;
f4ada568
GL
1734}
1735
f187448d 1736
ef57d866 1737// ==========================================================================
c3e646b4 1738// wxSocketServer
ef57d866 1739// ==========================================================================
f4ada568 1740
ef57d866
GRG
1741// --------------------------------------------------------------------------
1742// Ctor
1743// --------------------------------------------------------------------------
56d8adc0 1744
c9bccf23 1745wxSocketServer::wxSocketServer(const wxSockAddress& addr,
71622a7a
GRG
1746 wxSocketFlags flags)
1747 : wxSocketBase(flags, wxSOCKET_SERVER)
f4ada568 1748{
9a83f860 1749 wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );
f4ada568 1750
4f260c9c
VZ
1751 wxSocketManager * const manager = wxSocketManager::Get();
1752 m_impl = manager ? manager->CreateSocket(*this) : NULL;
384b4373 1753
51fe4b60 1754 if (!m_impl)
007c77ab 1755 {
9a83f860 1756 wxLogTrace( wxTRACE_Socket, wxT("*** Failed to create m_impl") );
007c77ab
RL
1757 return;
1758 }
a737331d 1759
2804f77d 1760 // Setup the socket as server
c9bccf23 1761 m_impl->SetLocal(addr.GetAddress());
d775fa82 1762
74c481d1 1763 if (GetFlags() & wxSOCKET_REUSEADDR) {
51fe4b60 1764 m_impl->SetReusable();
74c481d1 1765 }
60edcf45 1766 if (GetFlags() & wxSOCKET_BROADCAST) {
51fe4b60 1767 m_impl->SetBroadcast();
60edcf45
VZ
1768 }
1769 if (GetFlags() & wxSOCKET_NOBIND) {
51fe4b60 1770 m_impl->DontDoBind();
60edcf45 1771 }
74c481d1 1772
51fe4b60 1773 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
007c77ab 1774 {
51fe4b60
VZ
1775 delete m_impl;
1776 m_impl = NULL;
007c77ab 1777
9a83f860 1778 wxLogTrace( wxTRACE_Socket, wxT("*** CreateServer() failed") );
007c77ab
RL
1779 return;
1780 }
1781
9a83f860 1782 wxLogTrace( wxTRACE_Socket, wxT("wxSocketServer on fd %d"), m_impl->m_fd );
f4ada568
GL
1783}
1784
ef57d866
GRG
1785// --------------------------------------------------------------------------
1786// Accept
1787// --------------------------------------------------------------------------
8c14576d 1788
d80d1aba 1789bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
f4ada568 1790{
2b036c4b
VZ
1791 if ( !m_impl || (m_impl->m_fd == INVALID_SOCKET) || !m_impl->IsServer() )
1792 {
1793 wxFAIL_MSG( "can only be called for a valid server socket" );
1794
64b1cea0 1795 SetError(wxSOCKET_INVSOCK);
2b036c4b 1796
c2116a35 1797 return false;
2b036c4b
VZ
1798 }
1799
1800 if ( wait )
1801 {
1802 // wait until we get a connection
1803 if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
1804 {
64b1cea0 1805 SetError(wxSOCKET_TIMEDOUT);
2b036c4b
VZ
1806
1807 return false;
1808 }
1809 }
17aa2bec 1810
2b036c4b 1811 sock.m_impl = m_impl->Accept(sock);
d80d1aba 1812
51fe4b60 1813 if ( !sock.m_impl )
2b036c4b 1814 {
64b1cea0 1815 SetError(m_impl->GetLastError());
2b036c4b 1816
c2116a35 1817 return false;
2b036c4b 1818 }
d80d1aba 1819
c2116a35 1820 sock.m_type = wxSOCKET_BASE;
c2116a35 1821 sock.m_connected = true;
f4ada568 1822
c2116a35 1823 return true;
f4ada568
GL
1824}
1825
d80d1aba 1826wxSocketBase *wxSocketServer::Accept(bool wait)
f4ada568 1827{
c2116a35 1828 wxSocketBase* sock = new wxSocketBase();
f4ada568 1829
c2116a35 1830 sock->SetFlags(m_flags);
f4ada568 1831
c2116a35
VZ
1832 if (!AcceptWith(*sock, wait))
1833 {
1834 sock->Destroy();
1835 sock = NULL;
1836 }
f4ada568 1837
c2116a35 1838 return sock;
f4ada568
GL
1839}
1840
17aa2bec 1841bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
d80d1aba 1842{
ebbf7407 1843 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) == 1;
d80d1aba
GRG
1844}
1845
bfa7bf7d
VZ
1846bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1847{
9a83f860 1848 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
11734f8a 1849
735ac2bc 1850 SOCKOPTLEN_T lenreal = *optlen;
51fe4b60
VZ
1851 if ( getsockopt(m_impl->m_fd, level, optname,
1852 static_cast<char *>(optval), &lenreal) != 0 )
d775fa82 1853 return false;
51fe4b60
VZ
1854
1855 *optlen = lenreal;
1856
d775fa82 1857 return true;
bfa7bf7d
VZ
1858}
1859
51fe4b60
VZ
1860bool
1861wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
bfa7bf7d 1862{
9a83f860 1863 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
8e3f3880 1864
51fe4b60
VZ
1865 return setsockopt(m_impl->m_fd, level, optname,
1866 static_cast<const char *>(optval), optlen) == 0;
bfa7bf7d
VZ
1867}
1868
72ac4e88 1869bool wxSocketBase::SetLocal(const wxIPV4address& local)
33d925b0 1870{
c9bccf23 1871 m_localAddress = local;
33d925b0 1872
c9bccf23 1873 return true;
33d925b0
KH
1874}
1875
ef57d866 1876// ==========================================================================
8c14576d 1877// wxSocketClient
ef57d866 1878// ==========================================================================
f4ada568 1879
ef57d866
GRG
1880// --------------------------------------------------------------------------
1881// Ctor and dtor
1882// --------------------------------------------------------------------------
56d8adc0 1883
71622a7a
GRG
1884wxSocketClient::wxSocketClient(wxSocketFlags flags)
1885 : wxSocketBase(flags, wxSOCKET_CLIENT)
f4ada568 1886{
089b23d0
VZ
1887 m_initialRecvBufferSize =
1888 m_initialSendBufferSize = -1;
f4ada568
GL
1889}
1890
ef57d866
GRG
1891// --------------------------------------------------------------------------
1892// Connect
1893// --------------------------------------------------------------------------
dc5c1114 1894
2b036c4b 1895bool wxSocketClient::DoConnect(const wxSockAddress& remote,
72ac4e88
VZ
1896 const wxSockAddress* local,
1897 bool wait)
f4ada568 1898{
2b036c4b 1899 if ( m_impl )
c2116a35 1900 {
2b036c4b 1901 // Shutdown and destroy the old socket
c2116a35 1902 Close();
51fe4b60 1903 delete m_impl;
c2116a35 1904 }
a324a7bc 1905
c2116a35
VZ
1906 m_connected = false;
1907 m_establishing = false;
384b4373 1908
2b036c4b 1909 // Create and set up the new one
4f260c9c
VZ
1910 wxSocketManager * const manager = wxSocketManager::Get();
1911 m_impl = manager ? manager->CreateSocket(*this) : NULL;
2b036c4b 1912 if ( !m_impl )
c2116a35 1913 return false;
384b4373 1914
c2116a35
VZ
1915 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1916 if (GetFlags() & wxSOCKET_REUSEADDR)
51fe4b60 1917 m_impl->SetReusable();
c2116a35 1918 if (GetFlags() & wxSOCKET_BROADCAST)
51fe4b60 1919 m_impl->SetBroadcast();
c2116a35 1920 if (GetFlags() & wxSOCKET_NOBIND)
51fe4b60 1921 m_impl->DontDoBind();
33d925b0 1922
2b036c4b
VZ
1923 // Bind to the local IP address and port, when provided or if one had been
1924 // set before
c9bccf23 1925 if ( !local && m_localAddress.GetAddress().IsOk() )
c2116a35 1926 local = &m_localAddress;
c2116a35 1927
2b036c4b
VZ
1928 if ( local )
1929 m_impl->SetLocal(local->GetAddress());
33d925b0 1930
51fe4b60 1931 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
8c029a5b 1932
2b036c4b
VZ
1933 m_impl->SetPeer(remote.GetAddress());
1934
1935 // Finally do create the socket and connect to the peer
1936 const wxSocketError err = m_impl->CreateClient(wait);
791b24c4 1937
2b036c4b 1938 if ( err != wxSOCKET_NOERROR )
c2116a35 1939 {
2b036c4b
VZ
1940 if ( err == wxSOCKET_WOULDBLOCK )
1941 {
1942 wxASSERT_MSG( !wait, "shouldn't get this for blocking connect" );
1943
c2116a35 1944 m_establishing = true;
2b036c4b 1945 }
56d8adc0 1946
c2116a35
VZ
1947 return false;
1948 }
9111db68 1949
c2116a35
VZ
1950 m_connected = true;
1951 return true;
f4ada568
GL
1952}
1953
2b036c4b 1954bool wxSocketClient::Connect(const wxSockAddress& remote, bool wait)
33d925b0 1955{
2b036c4b 1956 return DoConnect(remote, NULL, wait);
33d925b0
KH
1957}
1958
2b036c4b 1959bool wxSocketClient::Connect(const wxSockAddress& remote,
72ac4e88
VZ
1960 const wxSockAddress& local,
1961 bool wait)
33d925b0 1962{
2b036c4b 1963 return DoConnect(remote, &local, wait);
33d925b0
KH
1964}
1965
d80d1aba 1966bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
f4ada568 1967{
60ee0172
VZ
1968 if ( m_connected )
1969 {
1970 // this happens if the initial attempt to connect succeeded without
1971 // blocking
7fb0a11d 1972 return true;
60ee0172 1973 }
d80d1aba 1974
51fe4b60 1975 wxCHECK_MSG( m_establishing && m_impl, false,
60ee0172 1976 "No connection establishment attempt in progress" );
d80d1aba 1977
ebbf7407
VZ
1978 // notice that we return true even if DoWait() returned -1, i.e. if an
1979 // error occurred and connection was lost: this is intentional as we should
1980 // return false only if timeout expired without anything happening
1981 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) != 0;
f4ada568
GL
1982}
1983
ef57d866 1984// ==========================================================================
dc5c1114 1985// wxDatagramSocket
ef57d866 1986// ==========================================================================
dc5c1114 1987
fbfb8bcc 1988wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
71622a7a
GRG
1989 wxSocketFlags flags )
1990 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
dc5c1114 1991{
7fb0a11d 1992 // Create the socket
4f260c9c
VZ
1993 wxSocketManager * const manager = wxSocketManager::Get();
1994 m_impl = manager ? manager->CreateSocket(*this) : NULL;
dc5c1114 1995
51fe4b60 1996 if (!m_impl)
7fb0a11d 1997 return;
53a161e1 1998
7fb0a11d 1999 // Setup the socket as non connection oriented
51fe4b60 2000 m_impl->SetLocal(addr.GetAddress());
28bf2f3c
VZ
2001 if (flags & wxSOCKET_REUSEADDR)
2002 {
51fe4b60 2003 m_impl->SetReusable();
28bf2f3c 2004 }
60edcf45
VZ
2005 if (GetFlags() & wxSOCKET_BROADCAST)
2006 {
51fe4b60 2007 m_impl->SetBroadcast();
60edcf45
VZ
2008 }
2009 if (GetFlags() & wxSOCKET_NOBIND)
2010 {
51fe4b60 2011 m_impl->DontDoBind();
60edcf45 2012 }
51fe4b60
VZ
2013
2014 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
7fb0a11d 2015 {
51fe4b60
VZ
2016 delete m_impl;
2017 m_impl = NULL;
7fb0a11d
WS
2018 return;
2019 }
dc5c1114 2020
7fb0a11d
WS
2021 // Initialize all stuff
2022 m_connected = false;
2023 m_establishing = false;
dc5c1114
GRG
2024}
2025
2026wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
f187448d 2027 void* buf,
dc5c1114
GRG
2028 wxUint32 nBytes )
2029{
2030 Read(buf, nBytes);
2031 GetPeer(addr);
2032 return (*this);
2033}
2034
fbfb8bcc 2035wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
f187448d 2036 const void* buf,
dc5c1114
GRG
2037 wxUint32 nBytes )
2038{
9a83f860 2039 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
8e3f3880 2040
51fe4b60 2041 m_impl->SetPeer(addr.GetAddress());
dc5c1114
GRG
2042 Write(buf, nBytes);
2043 return (*this);
2044}
2045
ef57d866 2046// ==========================================================================
a58d5df4 2047// wxSocketModule
ef57d866 2048// ==========================================================================
dc5c1114 2049
ed4c6c69 2050class wxSocketModule : public wxModule
dc5c1114 2051{
dc5c1114 2052public:
6c0d0845
VZ
2053 virtual bool OnInit()
2054 {
51fe4b60
VZ
2055 // wxSocketBase will call Initialize() itself only if sockets are
2056 // really used, don't do it from here
d775fa82 2057 return true;
6c0d0845
VZ
2058 }
2059
2060 virtual void OnExit()
2061 {
2062 if ( wxSocketBase::IsInitialized() )
2063 wxSocketBase::Shutdown();
2064 }
2065
2066private:
2067 DECLARE_DYNAMIC_CLASS(wxSocketModule)
a58d5df4
GL
2068};
2069
2070IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
2071
4f61df82 2072#if defined(wxUSE_SELECT_DISPATCHER) && wxUSE_SELECT_DISPATCHER
54e757fc
FM
2073// NOTE: we need to force linking against socketiohandler.cpp otherwise in
2074// static builds of wxWidgets the ManagerSetter::ManagerSetter ctor
2075// contained there wouldn't be ever called
2076wxFORCE_LINK_MODULE( socketiohandler )
4f61df82 2077#endif
54e757fc 2078
4f260c9c
VZ
2079// same for ManagerSetter in the MSW file
2080#ifdef __WXMSW__
2081 wxFORCE_LINK_MODULE( mswsocket )
2082#endif
2083
3270038f
VZ
2084// and for OSXManagerSetter in the OS X one
2085#ifdef __WXMAC__
2086 wxFORCE_LINK_MODULE( osxsocket )
2087#endif
2088
c2116a35 2089#endif // wxUSE_SOCKETS