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