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