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