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