]> git.saurik.com Git - wxWidgets.git/blame - src/common/socket.cpp
Explicitly unregister custom wxWebViewIE namespaces when we are done with them. Also...
[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$
526954c5 10// Licence: 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
4017f5ca
VZ
753namespace
754{
755
44c2703f
VZ
756// counts the number of calls to Initialize() minus the number of calls to
757// Shutdown(): we don't really need it any more but it was documented that
758// Shutdown() must be called the same number of times as Initialize() and using
759// a counter helps us to check it
760int gs_socketInitCount = 0;
4017f5ca
VZ
761
762} // anonymous namespace
6c0d0845
VZ
763
764bool wxSocketBase::IsInitialized()
765{
4017f5ca
VZ
766 wxASSERT_MSG( wxIsMainThread(), "unsafe to call from other threads" );
767
44c2703f 768 return gs_socketInitCount != 0;
6c0d0845
VZ
769}
770
771bool wxSocketBase::Initialize()
772{
4017f5ca
VZ
773 wxCHECK_MSG( wxIsMainThread(), false,
774 "must be called from the main thread" );
775
44c2703f 776 if ( !gs_socketInitCount )
6c0d0845 777 {
51fe4b60
VZ
778 wxSocketManager * const manager = wxSocketManager::Get();
779 if ( !manager || !manager->OnInit() )
d775fa82 780 return false;
6c0d0845
VZ
781 }
782
44c2703f
VZ
783 gs_socketInitCount++;
784
d775fa82 785 return true;
6c0d0845
VZ
786}
787
788void wxSocketBase::Shutdown()
789{
4017f5ca 790 wxCHECK_RET( wxIsMainThread(), "must be called from the main thread" );
51fe4b60 791
44c2703f 792 wxCHECK_RET( gs_socketInitCount > 0, "too many calls to Shutdown()" );
4017f5ca 793
44c2703f
VZ
794 if ( !--gs_socketInitCount )
795 {
796 wxSocketManager * const manager = wxSocketManager::Get();
797 wxCHECK_RET( manager, "should have a socket manager" );
4017f5ca 798
44c2703f
VZ
799 manager->OnExit();
800 }
6c0d0845
VZ
801}
802
ef57d866
GRG
803// --------------------------------------------------------------------------
804// Ctor and dtor
805// --------------------------------------------------------------------------
56d8adc0 806
71622a7a 807void wxSocketBase::Init()
f4ada568 808{
365b8793 809 m_impl = NULL;
c2116a35
VZ
810 m_type = wxSOCKET_UNINIT;
811
812 // state
813 m_flags = 0;
814 m_connected =
815 m_establishing =
816 m_reading =
817 m_writing =
c2116a35
VZ
818 m_closed = false;
819 m_lcount = 0;
294a09aa
VZ
820 m_lcount_read = 0;
821 m_lcount_write = 0;
c2116a35
VZ
822 m_timeout = 600;
823 m_beingDeleted = false;
824
825 // pushback buffer
826 m_unread = NULL;
827 m_unrd_size = 0;
828 m_unrd_cur = 0;
829
830 // events
831 m_id = wxID_ANY;
832 m_handler = NULL;
833 m_clientData = NULL;
834 m_notify = false;
5c1193e0
VZ
835 m_eventmask =
836 m_eventsgot = 0;
c2116a35 837
4017f5ca
VZ
838 // when we create the first socket in the main thread we initialize the
839 // OS-dependent socket stuff: notice that this means that the user code
840 // needs to call wxSocket::Initialize() itself if the first socket it
841 // creates is not created in the main thread
842 if ( wxIsMainThread() )
c2116a35 843 {
4017f5ca 844 if ( !Initialize() )
af588446 845 {
4017f5ca 846 wxLogError(_("Cannot initialize sockets"));
af588446 847 }
c2116a35 848 }
f4ada568
GL
849}
850
f187448d
GRG
851wxSocketBase::wxSocketBase()
852{
c2116a35 853 Init();
f187448d 854}
71622a7a
GRG
855
856wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
f4ada568 857{
c2116a35 858 Init();
71622a7a 859
cc0972a2
VZ
860 SetFlags(flags);
861
862 m_type = type;
f4ada568
GL
863}
864
f4ada568
GL
865wxSocketBase::~wxSocketBase()
866{
c2116a35
VZ
867 // Shutdown and close the socket
868 if (!m_beingDeleted)
869 Close();
9181a383 870
51fe4b60
VZ
871 // Destroy the implementation object
872 delete m_impl;
c2116a35
VZ
873
874 // Free the pushback buffer
3185abc2 875 free(m_unread);
f4ada568
GL
876}
877
ef57d866
GRG
878bool wxSocketBase::Destroy()
879{
c2116a35
VZ
880 // Delayed destruction: the socket will be deleted during the next idle
881 // loop iteration. This ensures that all pending events have been
882 // processed.
883 m_beingDeleted = true;
884
885 // Shutdown and close the socket
886 Close();
887
22185a1f 888 // Suppress events from now on
c2116a35
VZ
889 Notify(false);
890
3185abc2 891 // Schedule this object for deletion instead of destroying it right now if
ee5cc630
VZ
892 // it can have other events pending for it and we have a way to do it.
893 //
894 // Notice that sockets used in other threads won't have any events for them
895 // and we shouldn't use delayed destruction mechanism for them as it's not
896 // MT-safe.
897 if ( wxIsMainThread() && wxTheApp )
c2116a35 898 {
3185abc2 899 wxTheApp->ScheduleForDestruction(this);
c2116a35 900 }
3185abc2 901 else // no app
c2116a35
VZ
902 {
903 // in wxBase we might have no app object at all, don't leak memory
904 delete this;
905 }
906
907 return true;
ef57d866 908}
9181a383 909
51fe4b60 910// ----------------------------------------------------------------------------
64b1cea0 911// simple accessors
51fe4b60
VZ
912// ----------------------------------------------------------------------------
913
64b1cea0
VZ
914void wxSocketBase::SetError(wxSocketError error)
915{
916 m_impl->m_error = error;
917}
918
51fe4b60
VZ
919wxSocketError wxSocketBase::LastError() const
920{
921 return m_impl->GetError();
922}
923
ef57d866 924// --------------------------------------------------------------------------
bffc1eaa 925// Basic IO calls
ef57d866
GRG
926// --------------------------------------------------------------------------
927
64b1cea0 928// The following IO operations update m_lcount:
ef57d866 929// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
f4ada568
GL
930bool wxSocketBase::Close()
931{
c2116a35
VZ
932 // Interrupt pending waits
933 InterruptWait();
934
b67397a7 935 ShutdownOutput();
c2116a35
VZ
936
937 m_connected = false;
938 m_establishing = false;
939 return true;
f4ada568
GL
940}
941
b67397a7
VZ
942void wxSocketBase::ShutdownOutput()
943{
944 if ( m_impl )
945 m_impl->Shutdown();
946}
947
f187448d 948wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
f4ada568 949{
365b8793 950 wxSocketReadGuard read(this);
a324a7bc 951
294a09aa
VZ
952 m_lcount_read = DoRead(buffer, nbytes);
953 m_lcount = m_lcount_read;
17aa2bec 954
c2116a35 955 return *this;
96db102a
GRG
956}
957
cc0972a2 958wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
96db102a 959{
f5395600
VZ
960 wxCHECK_MSG( m_impl, 0, "socket must be valid" );
961
cc0972a2
VZ
962 // We use pointer arithmetic here which doesn't work with void pointers.
963 char *buffer = static_cast<char *>(buffer_);
f5395600 964 wxCHECK_MSG( buffer, 0, "NULL buffer" );
c2116a35 965
cc0972a2
VZ
966 // Try the push back buffer first, even before checking whether the socket
967 // is valid to allow reading previously pushed back data from an already
968 // closed socket.
969 wxUint32 total = GetPushback(buffer, nbytes, false);
c2116a35 970 nbytes -= total;
cc0972a2 971 buffer += total;
c2116a35 972
f5395600 973 while ( nbytes )
cc0972a2 974 {
f5395600
VZ
975 // our socket is non-blocking so Read() will return immediately if
976 // there is nothing to read yet and it's more efficient to try it first
6f405b31
VZ
977 // before entering DoWait() which is going to start dispatching GUI
978 // events and, even more importantly, we must do this under Windows
f5395600
VZ
979 // where we're not going to get notifications about socket being ready
980 // for reading before we read all the existing data from it
d34f724d
VZ
981 const int ret = !m_impl->m_stream || m_connected
982 ? m_impl->Read(buffer, nbytes)
983 : 0;
64b1cea0
VZ
984 if ( ret == -1 )
985 {
f5395600 986 if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
c2116a35 987 {
f5395600 988 // if we don't want to wait, just return immediately
294a09aa 989 if ( m_flags & (wxSOCKET_NOWAIT|wxSOCKET_NOWAIT_READ ))
686d0cc0
VZ
990 {
991 // this shouldn't be counted as an error in this case
992 SetError(wxSOCKET_NOERROR);
f5395600 993 break;
686d0cc0 994 }
c2116a35 995
6f405b31
VZ
996 // otherwise wait until the socket becomes ready for reading or
997 // an error occurs on it
ebbf7407 998 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG) )
f5395600
VZ
999 {
1000 // and exit if the timeout elapsed before it did
1001 SetError(wxSOCKET_TIMEDOUT);
1002 break;
1003 }
c2116a35 1004
f5395600
VZ
1005 // retry reading
1006 continue;
1007 }
1008 else // "real" error
1009 {
1010 SetError(wxSOCKET_IOERR);
c2116a35 1011 break;
f5395600
VZ
1012 }
1013 }
1014 else if ( ret == 0 )
1015 {
1016 // for connection-oriented (e.g. TCP) sockets we can only read
1017 // 0 bytes if the other end has been closed, and for connectionless
1018 // ones (UDP) this flag doesn't make sense anyhow so we can set it
1019 // to true too without doing any harm
1020 m_closed = true;
1021
1022 // we're not going to read anything else and so if we haven't read
1023 // anything (or not everything in wxSOCKET_WAITALL case) already,
1024 // signal an error
294a09aa 1025 if ( (m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ)) || !total )
f5395600
VZ
1026 SetError(wxSOCKET_IOERR);
1027 break;
1028 }
c2116a35 1029
f5395600 1030 total += ret;
c2116a35 1031
f5395600
VZ
1032 // if we are happy to read something and not the entire nbytes bytes,
1033 // then we're done
294a09aa 1034 if ( !(m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ)) )
f5395600 1035 break;
64b1cea0 1036
f5395600
VZ
1037 nbytes -= ret;
1038 buffer += ret;
c2116a35 1039 }
96db102a 1040
96db102a 1041 return total;
c2116a35 1042}
f4ada568 1043
c2116a35
VZ
1044wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
1045{
c2116a35
VZ
1046 struct
1047 {
1048 unsigned char sig[4];
1049 unsigned char len[4];
1050 } msg;
1051
365b8793 1052 wxSocketReadGuard read(this);
c2116a35 1053
294a09aa 1054 wxSocketWaitModeChanger changeFlags(this, (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ));
c9157492 1055
64b1cea0
VZ
1056 bool ok = false;
1057 if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
56d8adc0 1058 {
64b1cea0
VZ
1059 wxUint32 sig = (wxUint32)msg.sig[0];
1060 sig |= (wxUint32)(msg.sig[1] << 8);
1061 sig |= (wxUint32)(msg.sig[2] << 16);
1062 sig |= (wxUint32)(msg.sig[3] << 24);
f4ada568 1063
64b1cea0
VZ
1064 if ( sig == 0xfeeddead )
1065 {
1066 wxUint32 len = (wxUint32)msg.len[0];
1067 len |= (wxUint32)(msg.len[1] << 8);
1068 len |= (wxUint32)(msg.len[2] << 16);
1069 len |= (wxUint32)(msg.len[3] << 24);
f4ada568 1070
64b1cea0
VZ
1071 wxUint32 len2;
1072 if (len > nbytes)
1073 {
1074 len2 = len - nbytes;
1075 len = nbytes;
1076 }
1077 else
1078 len2 = 0;
c2116a35 1079
64b1cea0 1080 // Don't attempt to read if the msg was zero bytes long.
294a09aa
VZ
1081 m_lcount_read = len ? DoRead(buffer, len) : 0;
1082 m_lcount = m_lcount_read;
c2116a35 1083
64b1cea0
VZ
1084 if ( len2 )
1085 {
1086 char discard_buffer[MAX_DISCARD_SIZE];
1087 long discard_len;
1088
1089 // NOTE: discarded bytes don't add to m_lcount.
1090 do
1091 {
1092 discard_len = len2 > MAX_DISCARD_SIZE
1093 ? MAX_DISCARD_SIZE
1094 : len2;
1095 discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
1096 len2 -= (wxUint32)discard_len;
1097 }
1098 while ((discard_len > 0) && len2);
1099 }
17aa2bec 1100
64b1cea0
VZ
1101 if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1102 {
1103 sig = (wxUint32)msg.sig[0];
1104 sig |= (wxUint32)(msg.sig[1] << 8);
1105 sig |= (wxUint32)(msg.sig[2] << 16);
1106 sig |= (wxUint32)(msg.sig[3] << 24);
c2116a35 1107
64b1cea0
VZ
1108 if ( sig == 0xdeadfeed )
1109 ok = true;
1110 }
c2116a35 1111 }
c2116a35 1112 }
062c4861 1113
64b1cea0
VZ
1114 if ( !ok )
1115 SetError(wxSOCKET_IOERR);
96db102a 1116
c2116a35 1117 return *this;
062c4861
GL
1118}
1119
f187448d 1120wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
f4ada568 1121{
365b8793 1122 wxSocketReadGuard read(this);
96db102a 1123
896576e3
VZ
1124 // Peek() should never block
1125 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1126
cc0972a2 1127 m_lcount = DoRead(buffer, nbytes);
96db102a 1128
365b8793 1129 Pushback(buffer, m_lcount);
f4ada568 1130
c2116a35 1131 return *this;
f4ada568
GL
1132}
1133
f187448d 1134wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
f4ada568 1135{
365b8793 1136 wxSocketWriteGuard write(this);
56d8adc0 1137
294a09aa
VZ
1138 m_lcount_write = DoWrite(buffer, nbytes);
1139 m_lcount = m_lcount_write;
96db102a 1140
c2116a35 1141 return *this;
96db102a
GRG
1142}
1143
cc0972a2 1144// This function is a mirror image of DoRead() except that it doesn't use the
f5395600
VZ
1145// push back buffer and doesn't treat 0 return value specially (normally this
1146// shouldn't happen at all here), so please see comments there for explanations
cc0972a2 1147wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
96db102a 1148{
f5395600
VZ
1149 wxCHECK_MSG( m_impl, 0, "socket must be valid" );
1150
cc0972a2 1151 const char *buffer = static_cast<const char *>(buffer_);
f5395600 1152 wxCHECK_MSG( buffer, 0, "NULL buffer" );
c2116a35 1153
cc0972a2 1154 wxUint32 total = 0;
f5395600 1155 while ( nbytes )
cc0972a2 1156 {
d34f724d 1157 if ( m_impl->m_stream && !m_connected )
f1763270 1158 {
294a09aa 1159 if ( (m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE)) || !total )
f1763270
VZ
1160 SetError(wxSOCKET_IOERR);
1161 break;
1162 }
1163
51fe4b60 1164 const int ret = m_impl->Write(buffer, nbytes);
64b1cea0
VZ
1165 if ( ret == -1 )
1166 {
f5395600 1167 if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
c2116a35 1168 {
294a09aa 1169 if ( m_flags & (wxSOCKET_NOWAIT|wxSOCKET_NOWAIT_WRITE) )
f5395600 1170 break;
5c9eff30 1171
ebbf7407 1172 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG) )
f5395600
VZ
1173 {
1174 SetError(wxSOCKET_TIMEDOUT);
1175 break;
1176 }
a324a7bc 1177
f5395600
VZ
1178 continue;
1179 }
1180 else // "real" error
1181 {
1182 SetError(wxSOCKET_IOERR);
c2116a35 1183 break;
f5395600
VZ
1184 }
1185 }
c9157492 1186
f5395600 1187 total += ret;
c9157492 1188
294a09aa 1189 if ( !(m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE)) )
f5395600 1190 break;
64b1cea0 1191
f5395600
VZ
1192 nbytes -= ret;
1193 buffer += ret;
81b92e17 1194 }
a324a7bc 1195
c2116a35 1196 return total;
f4ada568
GL
1197}
1198
f187448d 1199wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
062c4861 1200{
c2116a35
VZ
1201 struct
1202 {
1203 unsigned char sig[4];
1204 unsigned char len[4];
1205 } msg;
062c4861 1206
365b8793 1207 wxSocketWriteGuard write(this);
96db102a 1208
294a09aa 1209 wxSocketWaitModeChanger changeFlags(this, (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE));
96db102a 1210
c2116a35
VZ
1211 msg.sig[0] = (unsigned char) 0xad;
1212 msg.sig[1] = (unsigned char) 0xde;
1213 msg.sig[2] = (unsigned char) 0xed;
1214 msg.sig[3] = (unsigned char) 0xfe;
062c4861 1215
c2116a35
VZ
1216 msg.len[0] = (unsigned char) (nbytes & 0xff);
1217 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1218 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1219 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
17aa2bec 1220
64b1cea0
VZ
1221 bool ok = false;
1222 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
1223 {
294a09aa
VZ
1224 m_lcount_write = DoWrite(buffer, nbytes);
1225 m_lcount = m_lcount_write;
1226 if ( m_lcount_write == nbytes )
64b1cea0
VZ
1227 {
1228 msg.sig[0] = (unsigned char) 0xed;
1229 msg.sig[1] = (unsigned char) 0xfe;
1230 msg.sig[2] = (unsigned char) 0xad;
1231 msg.sig[3] = (unsigned char) 0xde;
1232 msg.len[0] =
1233 msg.len[1] =
1234 msg.len[2] =
1235 msg.len[3] = (char) 0;
1236
1237 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
1238 ok = true;
1239 }
1240 }
17aa2bec 1241
64b1cea0
VZ
1242 if ( !ok )
1243 SetError(wxSOCKET_IOERR);
96db102a 1244
c2116a35 1245 return *this;
062c4861
GL
1246}
1247
f187448d 1248wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
f4ada568 1249{
c2116a35
VZ
1250 if (nbytes != 0)
1251 Pushback(buffer, nbytes);
f4ada568 1252
64b1cea0 1253 SetError(wxSOCKET_NOERROR);
c2116a35 1254 m_lcount = nbytes;
f4ada568 1255
c2116a35 1256 return *this;
a324a7bc
GL
1257}
1258
96db102a 1259wxSocketBase& wxSocketBase::Discard()
f4ada568 1260{
c2116a35
VZ
1261 char *buffer = new char[MAX_DISCARD_SIZE];
1262 wxUint32 ret;
1263 wxUint32 total = 0;
f4ada568 1264
365b8793 1265 wxSocketReadGuard read(this);
96db102a 1266
365b8793 1267 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
384b4373 1268
c2116a35
VZ
1269 do
1270 {
cc0972a2 1271 ret = DoRead(buffer, MAX_DISCARD_SIZE);
c2116a35
VZ
1272 total += ret;
1273 }
1274 while (ret == MAX_DISCARD_SIZE);
f4ada568 1275
c2116a35
VZ
1276 delete[] buffer;
1277 m_lcount = total;
64b1cea0 1278 SetError(wxSOCKET_NOERROR);
17aa2bec 1279
c2116a35 1280 return *this;
f4ada568
GL
1281}
1282
ef57d866
GRG
1283// --------------------------------------------------------------------------
1284// Wait functions
1285// --------------------------------------------------------------------------
f4ada568 1286
51fe4b60 1287/*
00414faf
VZ
1288 This function will check for the events specified in the flags parameter,
1289 and it will return a mask indicating which operations can be performed.
f0db5d75 1290 */
00414faf 1291wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
2b036c4b 1292 const timeval *timeout)
f0db5d75 1293{
5e9238f9
VZ
1294 if ( m_fd == INVALID_SOCKET )
1295 return (wxSOCKET_LOST_FLAG & flags);
f0db5d75 1296
5e9238f9
VZ
1297 struct timeval tv;
1298 if ( timeout )
1299 tv = *timeout;
1300 else
1301 tv.tv_sec = tv.tv_usec = 0;
f0db5d75 1302
5e9238f9
VZ
1303 // prepare the FD sets, passing NULL for the one(s) we don't use
1304 fd_set
1305 readfds, *preadfds = NULL,
1306 writefds, *pwritefds = NULL,
1307 exceptfds; // always want to know about errors
f0db5d75 1308
5e9238f9 1309 if ( flags & wxSOCKET_INPUT_FLAG )
5e9238f9 1310 preadfds = &readfds;
9be02147
VZ
1311
1312 if ( flags & wxSOCKET_OUTPUT_FLAG )
1313 pwritefds = &writefds;
1314
1315 // When using non-blocking connect() the client socket becomes connected
1316 // (successfully or not) when it becomes writable but when using
1317 // non-blocking accept() the server socket becomes connected when it
1318 // becomes readable.
1319 if ( flags & wxSOCKET_CONNECTION_FLAG )
1320 {
1321 if ( m_server )
1322 preadfds = &readfds;
1323 else
1324 pwritefds = &writefds;
1325 }
1326
1327 if ( preadfds )
1328 {
5e9238f9
VZ
1329 wxFD_ZERO(preadfds);
1330 wxFD_SET(m_fd, preadfds);
1331 }
f0db5d75 1332
9be02147 1333 if ( pwritefds )
5e9238f9 1334 {
5e9238f9
VZ
1335 wxFD_ZERO(pwritefds);
1336 wxFD_SET(m_fd, pwritefds);
1337 }
f0db5d75 1338
5e9238f9
VZ
1339 wxFD_ZERO(&exceptfds);
1340 wxFD_SET(m_fd, &exceptfds);
f0db5d75 1341
5e9238f9
VZ
1342 const int rc = select(m_fd + 1, preadfds, pwritefds, &exceptfds, &tv);
1343
1344 // check for errors first
1345 if ( rc == -1 || wxFD_ISSET(m_fd, &exceptfds) )
f0db5d75 1346 {
5e9238f9
VZ
1347 m_establishing = false;
1348
1349 return wxSOCKET_LOST_FLAG & flags;
f0db5d75 1350 }
f0db5d75 1351
5e9238f9
VZ
1352 if ( rc == 0 )
1353 return 0;
f0db5d75 1354
5e9238f9 1355 wxASSERT_MSG( rc == 1, "unexpected select() return value" );
f0db5d75 1356
5e9238f9
VZ
1357 wxSocketEventFlags detected = 0;
1358 if ( preadfds && wxFD_ISSET(m_fd, preadfds) )
1359 detected |= wxSOCKET_INPUT_FLAG;
1360
1361 if ( pwritefds && wxFD_ISSET(m_fd, pwritefds) )
f0db5d75 1362 {
5e9238f9
VZ
1363 // check for the case of non-blocking connect()
1364 if ( m_establishing && !m_server )
1365 {
1366 int error;
1367 SOCKOPTLEN_T len = sizeof(error);
1368 m_establishing = false;
1369 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1370
1371 if ( error )
1372 detected = wxSOCKET_LOST_FLAG;
1373 else
1374 detected |= wxSOCKET_CONNECTION_FLAG;
1375 }
1376 else // not called to get non-blocking connect() status
1377 {
1378 detected |= wxSOCKET_OUTPUT_FLAG;
1379 }
f0db5d75 1380 }
f0db5d75 1381
5e9238f9 1382 return detected & flags;
f0db5d75
VZ
1383}
1384
ebbf7407 1385int
60ee0172 1386wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
6f405b31
VZ
1387{
1388 // Use either the provided timeout or the default timeout value associated
1389 // with this socket.
1390 //
1391 // TODO: allow waiting forever, see #9443
1392 const long timeout = seconds == -1 ? m_timeout * 1000
1393 : seconds * 1000 + milliseconds;
1394
1395 return DoWait(timeout, flags);
1396}
1397
ebbf7407 1398int
6f405b31 1399wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags)
375abe3d 1400{
ebbf7407 1401 wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" );
375abe3d 1402
1632883f
VZ
1403 // we're never going to become ready in a TCP client if we're not connected
1404 // any more (OTOH a server can call this to precisely wait for a connection
1405 // so do wait for it in this case and UDP client is never "connected")
1406 if ( !m_impl->IsServer() &&
1407 m_impl->m_stream && !m_connected && !m_establishing )
ebbf7407 1408 return -1;
9588640d 1409
60ee0172 1410 // This can be set to true from Interrupt() to exit this function a.s.a.p.
c2116a35 1411 m_interrupt = false;
81b92e17 1412
af2fd961 1413
60ee0172
VZ
1414 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1415
1416 // Get the active event loop which we'll use for the message dispatching
2b036c4b
VZ
1417 // when running in the main thread unless this was explicitly disabled by
1418 // setting wxSOCKET_BLOCK flag
60ee0172 1419 wxEventLoopBase *eventLoop;
2b036c4b 1420 if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
60ee0172
VZ
1421 {
1422 eventLoop = wxEventLoop::GetActive();
60ee0172
VZ
1423 }
1424 else // in worker thread
af2fd961 1425 {
60ee0172
VZ
1426 // We never dispatch messages from threads other than the main one.
1427 eventLoop = NULL;
af2fd961
GRG
1428 }
1429
5ab2f257
VZ
1430 // Make sure the events we're interested in are enabled before waiting for
1431 // them: this is really necessary here as otherwise this could happen:
1432 // 1. DoRead(wxSOCKET_WAITALL) is called
1433 // 2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called
1434 // 3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting()
1435 // is called and wxSOCKET_INPUT_FLAG events are disabled in it
1436 // 4. Because of wxSOCKET_WAITALL we call DoWait() again but the events
1437 // are still disabled and we block forever
1438 //
1439 // More elegant solution would be nice but for now simply re-enabling the
1440 // events here will do
1441 m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG));
1442
1443
00414faf
VZ
1444 // Wait until we receive the event we're waiting for or the timeout expires
1445 // (but note that we always execute the loop at least once, even if timeout
1446 // is 0 as this is used for polling)
ebbf7407
VZ
1447 int rc = 0;
1448 for ( bool firstTime = true; !m_interrupt; firstTime = false )
af2fd961 1449 {
00414faf
VZ
1450 long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
1451 if ( timeLeft < 0 )
1452 {
1453 if ( !firstTime )
1454 break; // timed out
1455
1456 timeLeft = 0;
1457 }
1458
2f1c8faf
VZ
1459 wxSocketEventFlags events;
1460 if ( eventLoop )
1461 {
00414faf
VZ
1462 // reset them before starting to wait
1463 m_eventsgot = 0;
1464
1465 eventLoop->DispatchTimeout(timeLeft);
2f1c8faf
VZ
1466
1467 events = m_eventsgot;
1468 }
00414faf
VZ
1469 else // no event loop or waiting in another thread
1470 {
1471 // as explained below, we should always check for wxSOCKET_LOST_FLAG
2b036c4b
VZ
1472 timeval tv;
1473 SetTimeValFromMS(tv, timeLeft);
1474 events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
00414faf
VZ
1475 }
1476
1477 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1478 // it, as continuing to wait for anything else after getting it is
1479 // pointless
1480 if ( events & wxSOCKET_LOST_FLAG )
2f1c8faf 1481 {
00414faf
VZ
1482 m_connected = false;
1483 m_establishing = false;
ebbf7407 1484 rc = -1;
00414faf 1485 break;
2f1c8faf 1486 }
60ee0172 1487
00414faf
VZ
1488 // otherwise mask out the bits we're not interested in
1489 events &= flags;
1490
60ee0172 1491 // Incoming connection (server) or connection established (client)?
2f1c8faf 1492 if ( events & wxSOCKET_CONNECTION_FLAG )
c2116a35
VZ
1493 {
1494 m_connected = true;
1495 m_establishing = false;
ebbf7407 1496 rc = true;
c2116a35
VZ
1497 break;
1498 }
c0043a50 1499
60ee0172 1500 // Data available or output buffer ready?
2f1c8faf 1501 if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
b8d1915d 1502 {
ebbf7407 1503 rc = true;
c2116a35 1504 break;
b8d1915d 1505 }
f01bca89 1506 }
f4ada568 1507
ebbf7407 1508 return rc;
f4ada568 1509}
f4ada568 1510
a737331d 1511bool wxSocketBase::Wait(long seconds, long milliseconds)
f4ada568 1512{
60ee0172 1513 return DoWait(seconds, milliseconds,
ebbf7407
VZ
1514 wxSOCKET_INPUT_FLAG |
1515 wxSOCKET_OUTPUT_FLAG |
1516 wxSOCKET_CONNECTION_FLAG) != 0;
f4ada568 1517}
f4ada568 1518
a737331d 1519bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
f4ada568 1520{
60ee0172
VZ
1521 // Check pushback buffer before entering DoWait
1522 if ( m_unread )
c2116a35 1523 return true;
96db102a 1524
6f405b31
VZ
1525 // Check if the socket is not already ready for input, if it is, there is
1526 // no need to start waiting for it (worse, we'll actually never get a
1527 // notification about the socket becoming ready if it is already under
1528 // Windows)
1529 if ( m_impl->Select(wxSOCKET_INPUT_FLAG) )
1530 return true;
1531
ebbf7407 1532 return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG) != 0;
f4ada568
GL
1533}
1534
bfa7bf7d 1535
a737331d 1536bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
f4ada568 1537{
6f405b31
VZ
1538 if ( m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
1539 return true;
1540
ebbf7407 1541 return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG) != 0;
a737331d 1542}
f4ada568 1543
a737331d
GL
1544bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1545{
ebbf7407 1546 return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG) == -1;
f4ada568 1547}
a737331d 1548
ef57d866
GRG
1549// --------------------------------------------------------------------------
1550// Miscellaneous
1551// --------------------------------------------------------------------------
1552
1553//
1554// Get local or peer address
1555//
1556
c9bccf23 1557bool wxSocketBase::GetPeer(wxSockAddress& addr) const
ef57d866 1558{
c9bccf23 1559 wxCHECK_MSG( m_impl, false, "invalid socket" );
ef57d866 1560
c9bccf23
VZ
1561 const wxSockAddressImpl& peer = m_impl->GetPeer();
1562 if ( !peer.IsOk() )
c2116a35 1563 return false;
007c77ab 1564
c9bccf23 1565 addr.SetAddress(peer);
ef57d866 1566
c2116a35 1567 return true;
ef57d866
GRG
1568}
1569
c9bccf23 1570bool wxSocketBase::GetLocal(wxSockAddress& addr) const
ef57d866 1571{
c9bccf23 1572 wxCHECK_MSG( m_impl, false, "invalid socket" );
ef57d866 1573
c9bccf23
VZ
1574 const wxSockAddressImpl& local = m_impl->GetLocal();
1575 if ( !local.IsOk() )
7fb0a11d 1576 return false;
ef57d866 1577
c9bccf23 1578 addr.SetAddress(local);
ef57d866 1579
7fb0a11d 1580 return true;
ef57d866
GRG
1581}
1582
1583//
1584// Save and restore socket state
1585//
1586
1587void wxSocketBase::SaveState()
1588{
7fb0a11d 1589 wxSocketState *state;
ef57d866 1590
7fb0a11d 1591 state = new wxSocketState();
ef57d866 1592
7fb0a11d
WS
1593 state->m_flags = m_flags;
1594 state->m_notify = m_notify;
1595 state->m_eventmask = m_eventmask;
1596 state->m_clientData = m_clientData;
ef57d866 1597
7fb0a11d 1598 m_states.Append(state);
ef57d866
GRG
1599}
1600
1601void wxSocketBase::RestoreState()
1602{
7fb0a11d
WS
1603 wxList::compatibility_iterator node;
1604 wxSocketState *state;
ef57d866 1605
7fb0a11d
WS
1606 node = m_states.GetLast();
1607 if (!node)
1608 return;
ef57d866 1609
7fb0a11d 1610 state = (wxSocketState *)node->GetData();
ef57d866 1611
7fb0a11d
WS
1612 m_flags = state->m_flags;
1613 m_notify = state->m_notify;
1614 m_eventmask = state->m_eventmask;
1615 m_clientData = state->m_clientData;
37340c48 1616
7fb0a11d
WS
1617 m_states.Erase(node);
1618 delete state;
ef57d866
GRG
1619}
1620
1621//
1622// Timeout and flags
1623//
1624
17aa2bec
GRG
1625void wxSocketBase::SetTimeout(long seconds)
1626{
7fb0a11d 1627 m_timeout = seconds;
17aa2bec 1628
51fe4b60
VZ
1629 if (m_impl)
1630 m_impl->SetTimeout(m_timeout * 1000);
17aa2bec
GRG
1631}
1632
71622a7a 1633void wxSocketBase::SetFlags(wxSocketFlags flags)
f4ada568 1634{
cc0972a2
VZ
1635 // Do some sanity checking on the flags used: not all values can be used
1636 // together.
1637 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1638 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1639 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1640 "wxSOCKET_NOWAIT doesn't make sense" );
1641
7fb0a11d 1642 m_flags = flags;
f4ada568 1643}
f0a56ab0 1644
f187448d 1645
ef57d866 1646// --------------------------------------------------------------------------
f187448d 1647// Event handling
ef57d866 1648// --------------------------------------------------------------------------
a324a7bc 1649
bffc1eaa 1650void wxSocketBase::OnRequest(wxSocketNotify notification)
f4ada568 1651{
c2116a35 1652 wxSocketEventFlags flag = 0;
5c1193e0 1653 switch ( notification )
c2116a35 1654 {
5c1193e0
VZ
1655 case wxSOCKET_INPUT:
1656 flag = wxSOCKET_INPUT_FLAG;
1657 break;
1658
1659 case wxSOCKET_OUTPUT:
1660 flag = wxSOCKET_OUTPUT_FLAG;
1661 break;
1662
1663 case wxSOCKET_CONNECTION:
1664 flag = wxSOCKET_CONNECTION_FLAG;
40a983ad
VZ
1665
1666 // we're now successfully connected
1667 m_connected = true;
609aa390
VZ
1668 m_establishing = false;
1669
1670 // error was previously set to wxSOCKET_WOULDBLOCK, but this is not
1671 // the case any longer
1672 SetError(wxSOCKET_NOERROR);
5c1193e0
VZ
1673 break;
1674
1675 case wxSOCKET_LOST:
1676 flag = wxSOCKET_LOST_FLAG;
40a983ad 1677
9038fc94
VZ
1678 // if we lost the connection the socket is now closed and not
1679 // connected any more
1680 m_connected = false;
40a983ad 1681 m_closed = true;
5c1193e0
VZ
1682 break;
1683
c2116a35 1684 default:
5c1193e0 1685 wxFAIL_MSG( "unknown wxSocket notification" );
c2116a35
VZ
1686 }
1687
5c1193e0
VZ
1688 // remember the events which were generated for this socket, we're going to
1689 // use this in DoWait()
1690 m_eventsgot |= flag;
1691
1692 // send the wx event if enabled and we're interested in it
1693 if ( m_notify && (m_eventmask & flag) && m_handler )
c2116a35 1694 {
0ed00ab5
VZ
1695 // don't generate the events when we're inside DoWait() called from our
1696 // own code as we are going to consume the data that has just become
1697 // available ourselves and the user code won't see it at all
1698 if ( (notification == wxSOCKET_INPUT && m_reading) ||
1699 (notification == wxSOCKET_OUTPUT && m_writing) )
1700 {
1701 return;
1702 }
1703
5c1193e0
VZ
1704 wxSocketEvent event(m_id);
1705 event.m_event = notification;
1706 event.m_clientData = m_clientData;
1707 event.SetEventObject(this);
c2116a35 1708
5c1193e0 1709 m_handler->AddPendingEvent(event);
bffc1eaa 1710 }
f4ada568
GL
1711}
1712
f187448d
GRG
1713void wxSocketBase::Notify(bool notify)
1714{
7fb0a11d 1715 m_notify = notify;
f187448d
GRG
1716}
1717
1718void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1719{
7fb0a11d 1720 m_eventmask = flags;
f187448d
GRG
1721}
1722
71622a7a 1723void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
f4ada568 1724{
7fb0a11d
WS
1725 m_handler = &handler;
1726 m_id = id;
f4ada568
GL
1727}
1728
ef57d866
GRG
1729// --------------------------------------------------------------------------
1730// Pushback buffer
1731// --------------------------------------------------------------------------
db131261 1732
f187448d 1733void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
f4ada568 1734{
c2116a35 1735 if (!size) return;
dc5c1114 1736
c2116a35
VZ
1737 if (m_unread == NULL)
1738 m_unread = malloc(size);
1739 else
1740 {
1741 void *tmp;
f4ada568 1742
c2116a35
VZ
1743 tmp = malloc(m_unrd_size + size);
1744 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1745 free(m_unread);
a324a7bc 1746
c2116a35
VZ
1747 m_unread = tmp;
1748 }
31528cd3 1749
c2116a35 1750 m_unrd_size += size;
a324a7bc 1751
c2116a35 1752 memcpy(m_unread, buffer, size);
f4ada568
GL
1753}
1754
f187448d 1755wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
f4ada568 1756{
cc0972a2
VZ
1757 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1758
c2116a35
VZ
1759 if (!m_unrd_size)
1760 return 0;
f4ada568 1761
c2116a35
VZ
1762 if (size > (m_unrd_size-m_unrd_cur))
1763 size = m_unrd_size-m_unrd_cur;
96db102a 1764
c2116a35 1765 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
f4ada568 1766
c2116a35 1767 if (!peek)
dc5c1114 1768 {
c2116a35
VZ
1769 m_unrd_cur += size;
1770 if (m_unrd_size == m_unrd_cur)
1771 {
1772 free(m_unread);
1773 m_unread = NULL;
1774 m_unrd_size = 0;
1775 m_unrd_cur = 0;
1776 }
f4ada568 1777 }
f4ada568 1778
c2116a35 1779 return size;
f4ada568
GL
1780}
1781
f187448d 1782
ef57d866 1783// ==========================================================================
c3e646b4 1784// wxSocketServer
ef57d866 1785// ==========================================================================
f4ada568 1786
ef57d866
GRG
1787// --------------------------------------------------------------------------
1788// Ctor
1789// --------------------------------------------------------------------------
56d8adc0 1790
c9bccf23 1791wxSocketServer::wxSocketServer(const wxSockAddress& addr,
71622a7a
GRG
1792 wxSocketFlags flags)
1793 : wxSocketBase(flags, wxSOCKET_SERVER)
f4ada568 1794{
9a83f860 1795 wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );
f4ada568 1796
4f260c9c
VZ
1797 wxSocketManager * const manager = wxSocketManager::Get();
1798 m_impl = manager ? manager->CreateSocket(*this) : NULL;
384b4373 1799
51fe4b60 1800 if (!m_impl)
007c77ab 1801 {
9a83f860 1802 wxLogTrace( wxTRACE_Socket, wxT("*** Failed to create m_impl") );
007c77ab
RL
1803 return;
1804 }
a737331d 1805
2804f77d 1806 // Setup the socket as server
c9bccf23 1807 m_impl->SetLocal(addr.GetAddress());
d775fa82 1808
74c481d1 1809 if (GetFlags() & wxSOCKET_REUSEADDR) {
51fe4b60 1810 m_impl->SetReusable();
74c481d1 1811 }
60edcf45 1812 if (GetFlags() & wxSOCKET_BROADCAST) {
51fe4b60 1813 m_impl->SetBroadcast();
60edcf45
VZ
1814 }
1815 if (GetFlags() & wxSOCKET_NOBIND) {
51fe4b60 1816 m_impl->DontDoBind();
60edcf45 1817 }
74c481d1 1818
51fe4b60 1819 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
007c77ab 1820 {
5276b0a5 1821 wxDELETE(m_impl);
007c77ab 1822
9a83f860 1823 wxLogTrace( wxTRACE_Socket, wxT("*** CreateServer() failed") );
007c77ab
RL
1824 return;
1825 }
1826
45cecdf9
VZ
1827 // Notice that we need a cast as SOCKET is 64 bit under Win64 and that the
1828 // cast is safe because a SOCKET is a handle and so limited to 32 (or,
1829 // actually, even 24) bit values anyhow.
1830 wxLogTrace( wxTRACE_Socket, wxT("wxSocketServer on fd %u"),
1831 static_cast<unsigned>(m_impl->m_fd) );
f4ada568
GL
1832}
1833
ef57d866
GRG
1834// --------------------------------------------------------------------------
1835// Accept
1836// --------------------------------------------------------------------------
8c14576d 1837
d80d1aba 1838bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
f4ada568 1839{
2b036c4b
VZ
1840 if ( !m_impl || (m_impl->m_fd == INVALID_SOCKET) || !m_impl->IsServer() )
1841 {
1842 wxFAIL_MSG( "can only be called for a valid server socket" );
1843
64b1cea0 1844 SetError(wxSOCKET_INVSOCK);
2b036c4b 1845
c2116a35 1846 return false;
2b036c4b
VZ
1847 }
1848
1849 if ( wait )
1850 {
1851 // wait until we get a connection
1852 if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
1853 {
64b1cea0 1854 SetError(wxSOCKET_TIMEDOUT);
2b036c4b
VZ
1855
1856 return false;
1857 }
1858 }
17aa2bec 1859
2b036c4b 1860 sock.m_impl = m_impl->Accept(sock);
d80d1aba 1861
51fe4b60 1862 if ( !sock.m_impl )
2b036c4b 1863 {
64b1cea0 1864 SetError(m_impl->GetLastError());
2b036c4b 1865
c2116a35 1866 return false;
2b036c4b 1867 }
d80d1aba 1868
c2116a35 1869 sock.m_type = wxSOCKET_BASE;
c2116a35 1870 sock.m_connected = true;
f4ada568 1871
c2116a35 1872 return true;
f4ada568
GL
1873}
1874
d80d1aba 1875wxSocketBase *wxSocketServer::Accept(bool wait)
f4ada568 1876{
c2116a35 1877 wxSocketBase* sock = new wxSocketBase();
f4ada568 1878
c2116a35 1879 sock->SetFlags(m_flags);
f4ada568 1880
c2116a35
VZ
1881 if (!AcceptWith(*sock, wait))
1882 {
1883 sock->Destroy();
1884 sock = NULL;
1885 }
f4ada568 1886
c2116a35 1887 return sock;
f4ada568
GL
1888}
1889
17aa2bec 1890bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
d80d1aba 1891{
ebbf7407 1892 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) == 1;
d80d1aba
GRG
1893}
1894
bfa7bf7d
VZ
1895bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1896{
9a83f860 1897 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
11734f8a 1898
735ac2bc 1899 SOCKOPTLEN_T lenreal = *optlen;
51fe4b60
VZ
1900 if ( getsockopt(m_impl->m_fd, level, optname,
1901 static_cast<char *>(optval), &lenreal) != 0 )
d775fa82 1902 return false;
51fe4b60
VZ
1903
1904 *optlen = lenreal;
1905
d775fa82 1906 return true;
bfa7bf7d
VZ
1907}
1908
51fe4b60
VZ
1909bool
1910wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
bfa7bf7d 1911{
9a83f860 1912 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
8e3f3880 1913
51fe4b60
VZ
1914 return setsockopt(m_impl->m_fd, level, optname,
1915 static_cast<const char *>(optval), optlen) == 0;
bfa7bf7d
VZ
1916}
1917
72ac4e88 1918bool wxSocketBase::SetLocal(const wxIPV4address& local)
33d925b0 1919{
c9bccf23 1920 m_localAddress = local;
33d925b0 1921
c9bccf23 1922 return true;
33d925b0
KH
1923}
1924
ef57d866 1925// ==========================================================================
8c14576d 1926// wxSocketClient
ef57d866 1927// ==========================================================================
f4ada568 1928
ef57d866
GRG
1929// --------------------------------------------------------------------------
1930// Ctor and dtor
1931// --------------------------------------------------------------------------
56d8adc0 1932
71622a7a
GRG
1933wxSocketClient::wxSocketClient(wxSocketFlags flags)
1934 : wxSocketBase(flags, wxSOCKET_CLIENT)
f4ada568 1935{
089b23d0
VZ
1936 m_initialRecvBufferSize =
1937 m_initialSendBufferSize = -1;
f4ada568
GL
1938}
1939
ef57d866
GRG
1940// --------------------------------------------------------------------------
1941// Connect
1942// --------------------------------------------------------------------------
dc5c1114 1943
2b036c4b 1944bool wxSocketClient::DoConnect(const wxSockAddress& remote,
72ac4e88
VZ
1945 const wxSockAddress* local,
1946 bool wait)
f4ada568 1947{
2b036c4b 1948 if ( m_impl )
c2116a35 1949 {
2b036c4b 1950 // Shutdown and destroy the old socket
c2116a35 1951 Close();
51fe4b60 1952 delete m_impl;
c2116a35 1953 }
a324a7bc 1954
c2116a35
VZ
1955 m_connected = false;
1956 m_establishing = false;
384b4373 1957
2b036c4b 1958 // Create and set up the new one
4f260c9c
VZ
1959 wxSocketManager * const manager = wxSocketManager::Get();
1960 m_impl = manager ? manager->CreateSocket(*this) : NULL;
2b036c4b 1961 if ( !m_impl )
c2116a35 1962 return false;
384b4373 1963
c2116a35
VZ
1964 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1965 if (GetFlags() & wxSOCKET_REUSEADDR)
51fe4b60 1966 m_impl->SetReusable();
c2116a35 1967 if (GetFlags() & wxSOCKET_BROADCAST)
51fe4b60 1968 m_impl->SetBroadcast();
c2116a35 1969 if (GetFlags() & wxSOCKET_NOBIND)
51fe4b60 1970 m_impl->DontDoBind();
33d925b0 1971
2b036c4b
VZ
1972 // Bind to the local IP address and port, when provided or if one had been
1973 // set before
c9bccf23 1974 if ( !local && m_localAddress.GetAddress().IsOk() )
c2116a35 1975 local = &m_localAddress;
c2116a35 1976
2b036c4b
VZ
1977 if ( local )
1978 m_impl->SetLocal(local->GetAddress());
33d925b0 1979
51fe4b60 1980 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
8c029a5b 1981
2b036c4b
VZ
1982 m_impl->SetPeer(remote.GetAddress());
1983
1984 // Finally do create the socket and connect to the peer
1985 const wxSocketError err = m_impl->CreateClient(wait);
791b24c4 1986
2b036c4b 1987 if ( err != wxSOCKET_NOERROR )
c2116a35 1988 {
2b036c4b
VZ
1989 if ( err == wxSOCKET_WOULDBLOCK )
1990 {
1991 wxASSERT_MSG( !wait, "shouldn't get this for blocking connect" );
1992
c2116a35 1993 m_establishing = true;
2b036c4b 1994 }
56d8adc0 1995
c2116a35
VZ
1996 return false;
1997 }
9111db68 1998
c2116a35
VZ
1999 m_connected = true;
2000 return true;
f4ada568
GL
2001}
2002
2b036c4b 2003bool wxSocketClient::Connect(const wxSockAddress& remote, bool wait)
33d925b0 2004{
2b036c4b 2005 return DoConnect(remote, NULL, wait);
33d925b0
KH
2006}
2007
2b036c4b 2008bool wxSocketClient::Connect(const wxSockAddress& remote,
72ac4e88
VZ
2009 const wxSockAddress& local,
2010 bool wait)
33d925b0 2011{
2b036c4b 2012 return DoConnect(remote, &local, wait);
33d925b0
KH
2013}
2014
d80d1aba 2015bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
f4ada568 2016{
60ee0172
VZ
2017 if ( m_connected )
2018 {
2019 // this happens if the initial attempt to connect succeeded without
2020 // blocking
7fb0a11d 2021 return true;
60ee0172 2022 }
d80d1aba 2023
51fe4b60 2024 wxCHECK_MSG( m_establishing && m_impl, false,
60ee0172 2025 "No connection establishment attempt in progress" );
d80d1aba 2026
ebbf7407
VZ
2027 // notice that we return true even if DoWait() returned -1, i.e. if an
2028 // error occurred and connection was lost: this is intentional as we should
2029 // return false only if timeout expired without anything happening
2030 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) != 0;
f4ada568
GL
2031}
2032
ef57d866 2033// ==========================================================================
dc5c1114 2034// wxDatagramSocket
ef57d866 2035// ==========================================================================
dc5c1114 2036
fbfb8bcc 2037wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
71622a7a
GRG
2038 wxSocketFlags flags )
2039 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
dc5c1114 2040{
7fb0a11d 2041 // Create the socket
4f260c9c
VZ
2042 wxSocketManager * const manager = wxSocketManager::Get();
2043 m_impl = manager ? manager->CreateSocket(*this) : NULL;
dc5c1114 2044
51fe4b60 2045 if (!m_impl)
7fb0a11d 2046 return;
53a161e1 2047
7fb0a11d 2048 // Setup the socket as non connection oriented
51fe4b60 2049 m_impl->SetLocal(addr.GetAddress());
28bf2f3c
VZ
2050 if (flags & wxSOCKET_REUSEADDR)
2051 {
51fe4b60 2052 m_impl->SetReusable();
28bf2f3c 2053 }
60edcf45
VZ
2054 if (GetFlags() & wxSOCKET_BROADCAST)
2055 {
51fe4b60 2056 m_impl->SetBroadcast();
60edcf45
VZ
2057 }
2058 if (GetFlags() & wxSOCKET_NOBIND)
2059 {
51fe4b60 2060 m_impl->DontDoBind();
60edcf45 2061 }
51fe4b60
VZ
2062
2063 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
7fb0a11d 2064 {
5276b0a5 2065 wxDELETE(m_impl);
7fb0a11d
WS
2066 return;
2067 }
dc5c1114 2068
7fb0a11d
WS
2069 // Initialize all stuff
2070 m_connected = false;
2071 m_establishing = false;
dc5c1114
GRG
2072}
2073
2074wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
f187448d 2075 void* buf,
dc5c1114
GRG
2076 wxUint32 nBytes )
2077{
2078 Read(buf, nBytes);
2079 GetPeer(addr);
2080 return (*this);
2081}
2082
fbfb8bcc 2083wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
f187448d 2084 const void* buf,
dc5c1114
GRG
2085 wxUint32 nBytes )
2086{
9a83f860 2087 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
8e3f3880 2088
51fe4b60 2089 m_impl->SetPeer(addr.GetAddress());
dc5c1114
GRG
2090 Write(buf, nBytes);
2091 return (*this);
2092}
2093
ef57d866 2094// ==========================================================================
a58d5df4 2095// wxSocketModule
ef57d866 2096// ==========================================================================
dc5c1114 2097
ed4c6c69 2098class wxSocketModule : public wxModule
dc5c1114 2099{
dc5c1114 2100public:
6c0d0845
VZ
2101 virtual bool OnInit()
2102 {
51fe4b60
VZ
2103 // wxSocketBase will call Initialize() itself only if sockets are
2104 // really used, don't do it from here
d775fa82 2105 return true;
6c0d0845
VZ
2106 }
2107
2108 virtual void OnExit()
2109 {
2110 if ( wxSocketBase::IsInitialized() )
2111 wxSocketBase::Shutdown();
2112 }
2113
2114private:
2115 DECLARE_DYNAMIC_CLASS(wxSocketModule)
a58d5df4
GL
2116};
2117
2118IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
2119
4f61df82 2120#if defined(wxUSE_SELECT_DISPATCHER) && wxUSE_SELECT_DISPATCHER
54e757fc
FM
2121// NOTE: we need to force linking against socketiohandler.cpp otherwise in
2122// static builds of wxWidgets the ManagerSetter::ManagerSetter ctor
2123// contained there wouldn't be ever called
2124wxFORCE_LINK_MODULE( socketiohandler )
4f61df82 2125#endif
54e757fc 2126
4f260c9c 2127// same for ManagerSetter in the MSW file
bb5a9514 2128#ifdef __WINDOWS__
4f260c9c
VZ
2129 wxFORCE_LINK_MODULE( mswsocket )
2130#endif
2131
3270038f 2132// and for OSXManagerSetter in the OS X one
74b1f0b4 2133#ifdef __WXOSX__
3270038f
VZ
2134 wxFORCE_LINK_MODULE( osxsocket )
2135#endif
2136
c2116a35 2137#endif // wxUSE_SOCKETS