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