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