]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/cfsocket.cpp
DC reorganization
[wxWidgets.git] / src / mac / carbon / cfsocket.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/carbon/cfsocket.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) 2000-1999, Guillermo Rodriguez Garcia
8// RCS_ID: $Id$
9// License: see wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
18#if wxUSE_SOCKETS
19
20#include "wx/socket.h"
21
22#ifndef WX_PRECOMP
23 #include "wx/object.h"
24 #include "wx/string.h"
25 #include "wx/intl.h"
26 #include "wx/log.h"
27 #include "wx/event.h"
28 #include "wx/app.h"
29 #include "wx/utils.h"
30 #include "wx/timer.h"
31 #include "wx/module.h"
32#endif
33
34#include "wx/apptrait.h"
35
36#include "wx/sckaddr.h"
37#include "wx/mac/carbon/private.h"
38
39#include <sys/socket.h>
40#include <netinet/in.h>
41#include <arpa/inet.h>
42#include <netdb.h>
43
44#define HAVE_INET_ATON
45
46// DLL options compatibility check:
47#include "wx/build.h"
48
49WX_CHECK_BUILD_OPTIONS("wxNet")
50
51
52// discard buffer
53#define MAX_DISCARD_SIZE (10 * 1024)
54
55#ifndef INVALID_SOCKET
56#define INVALID_SOCKET -1
57#endif
58
59// what to do within waits: we have 2 cases: from the main thread itself we
60// have to call wxYield() to let the events (including the GUI events and the
61// low-level (not wxWidgets) events from GSocket) be processed. From another
62// thread it is enough to just call wxThread::Yield() which will give away the
63// rest of our time slice: the explanation is that the events will be processed
64// by the main thread anyhow, without calling wxYield(), but we don't want to
65// eat the CPU time uselessly while sitting in the loop waiting for the data
66#if wxUSE_THREADS
67 #define PROCESS_EVENTS() \
68 { \
69 if ( wxThread::IsMain() ) \
70 wxYield(); \
71 else \
72 wxThread::Yield(); \
73 }
74#else // !wxUSE_THREADS
75 #define PROCESS_EVENTS() wxYield()
76#endif // wxUSE_THREADS/!wxUSE_THREADS
77
78#define wxTRACE_Socket _T("wxSocket")
79
80
81IMPLEMENT_CLASS(wxSocketBase, wxObject)
82IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
83IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
84IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
85IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
86
87// --------------------------------------------------------------------------
88// private classes
89// --------------------------------------------------------------------------
90
91class wxSocketState : public wxObject
92{
93public:
94 wxSocketFlags m_flags;
95 wxSocketEventFlags m_eventmask;
96 bool m_notify;
97 void *m_clientData;
98
99public:
100 wxSocketState() : wxObject() {}
101
102 DECLARE_NO_COPY_CLASS(wxSocketState)
103};
104
105struct _GSocket
106{
107 CFSocketNativeHandle m_fd;
108 GAddress *m_local;
109 GAddress *m_peer;
110 GSocketError m_error;
111
112 int m_non_blocking;
113 int m_server;
114 int m_stream;
115 int m_oriented;
116 int m_establishing;
117 unsigned long m_timeout;
118
119 // Callbacks
120 GSocketEventFlags m_detected;
121 GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
122 char *m_data[GSOCK_MAX_EVENT];
123
124 CFSocketRef m_cfSocket;
125 CFRunLoopSourceRef m_runLoopSource;
126 CFReadStreamRef m_readStream ;
127 CFWriteStreamRef m_writeStream ;
128};
129
130struct _GAddress
131{
132 struct sockaddr *m_addr;
133 size_t m_len;
134
135 GAddressType m_family;
136 int m_realfamily;
137
138 GSocketError m_error;
139 int somethingElse ;
140};
141
142void wxMacCFSocketCallback(CFSocketRef s, CFSocketCallBackType callbackType,
143 CFDataRef address, const void* data, void* info) ;
144void _GSocket_Enable(GSocket *socket, GSocketEvent event) ;
145void _GSocket_Disable(GSocket *socket, GSocketEvent event) ;
146
147// ==========================================================================
148// wxSocketBase
149// ==========================================================================
150
151// --------------------------------------------------------------------------
152// Initialization and shutdown
153// --------------------------------------------------------------------------
154
155// FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
156// to m_countInit with a crit section
157size_t wxSocketBase::m_countInit = 0;
158
159bool wxSocketBase::IsInitialized()
160{
161 return m_countInit > 0;
162}
163
164bool wxSocketBase::Initialize()
165{
166 if ( !m_countInit++ )
167 {
168#if 0
169 wxAppTraits *traits = wxAppConsole::GetInstance() ?
170 wxAppConsole::GetInstance()->GetTraits() : NULL;
171 GSocketGUIFunctionsTable *functions =
172 traits ? traits->GetSocketGUIFunctionsTable() : NULL;
173 GSocket_SetGUIFunctions(functions);
174
175 if ( !GSocket_Init() )
176 {
177 m_countInit--;
178
179 return false;
180 }
181#endif
182 }
183
184 return true;
185}
186
187void wxSocketBase::Shutdown()
188{
189 // we should be initialized
190 wxASSERT_MSG( m_countInit, wxT("extra call to Shutdown()") );
191 if ( !--m_countInit )
192 {
193#if 0
194 GSocket_Cleanup();
195#endif
196 }
197}
198
199// --------------------------------------------------------------------------
200// Ctor and dtor
201// --------------------------------------------------------------------------
202
203void wxSocketBase::Init()
204{
205 m_socket = NULL;
206 m_type = wxSOCKET_UNINIT;
207
208 // state
209 m_flags = 0;
210 m_connected =
211 m_establishing =
212 m_reading =
213 m_writing =
214 m_error = false;
215 m_lcount = 0;
216 m_timeout = 600;
217 m_beingDeleted = false;
218
219 // pushback buffer
220 m_unread = NULL;
221 m_unrd_size = 0;
222 m_unrd_cur = 0;
223
224 // events
225 m_id = -1;
226 m_handler = NULL;
227 m_clientData = NULL;
228 m_notify = false;
229 m_eventmask = 0;
230
231 if ( !IsInitialized() )
232 {
233 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
234 // other calls to it should be matched by a call to Shutdown()
235 Initialize();
236 }
237}
238
239wxSocketBase::wxSocketBase()
240{
241 Init();
242}
243
244wxSocketBase::wxSocketBase( wxSocketFlags flags, wxSocketType type)
245{
246 Init();
247
248 m_flags = flags;
249 m_type = type;
250}
251
252wxSocketBase::~wxSocketBase()
253{
254 // Just in case the app called Destroy() *and* then deleted
255 // the socket immediately: don't leave dangling pointers.
256 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
257 if ( traits )
258 traits->RemoveFromPendingDelete(this);
259
260 // Shutdown and close the socket
261 if (!m_beingDeleted)
262 Close();
263
264 // Destroy the GSocket object
265 if (m_socket)
266 {
267 GSocket_destroy(m_socket);
268 }
269
270 // Free the pushback buffer
271 if (m_unread)
272 free(m_unread);
273}
274
275bool wxSocketBase::Destroy()
276{
277 // Delayed destruction: the socket will be deleted during the next
278 // idle loop iteration. This ensures that all pending events have
279 // been processed.
280 m_beingDeleted = true;
281
282 // Shutdown and close the socket
283 Close();
284
285 // Supress events from now on
286 Notify(false);
287
288 // schedule this object for deletion
289 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
290 if ( traits )
291 {
292 // let the traits object decide what to do with us
293 traits->ScheduleForDestroy(this);
294 }
295 else // no app or no traits
296 {
297 // in wxBase we might have no app object at all, don't leak memory
298 delete this;
299 }
300
301 return true;
302}
303
304// --------------------------------------------------------------------------
305// Basic IO calls
306// --------------------------------------------------------------------------
307
308// The following IO operations update m_error and m_lcount:
309// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
310//
311// TODO: Should Connect, Accept and AcceptWith update m_error?
312
313bool wxSocketBase::Close()
314{
315 // Interrupt pending waits
316 InterruptWait();
317
318 if (m_socket)
319 GSocket_Shutdown(m_socket);
320
321 m_connected = false;
322 m_establishing = false;
323
324 return true;
325}
326
327wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
328{
329 // Mask read events
330 m_reading = true;
331
332 m_lcount = _Read(buffer, nbytes);
333
334 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
335 if (m_flags & wxSOCKET_WAITALL)
336 m_error = (m_lcount != nbytes);
337 else
338 m_error = (m_lcount == 0);
339
340 // Allow read events from now on
341 m_reading = false;
342
343 return *this;
344}
345
346wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
347{
348 int total = 0;
349
350 // Try the pushback buffer first
351 total = GetPushback(buffer, nbytes, false);
352 nbytes -= total;
353 buffer = (char *)buffer + total;
354
355 // Return now in one of the following cases:
356 // - the socket is invalid,
357 // - we got all the data,
358 // - we got *some* data and we are not using wxSOCKET_WAITALL.
359 if ( !m_socket ||
360 !nbytes ||
361 ((total != 0) && !(m_flags & wxSOCKET_WAITALL)) )
362 return total;
363
364 // Possible combinations (they are checked in this order)
365 // wxSOCKET_NOWAIT
366 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
367 // wxSOCKET_BLOCK
368 // wxSOCKET_NONE
369 //
370
371 int ret;
372 if (m_flags & wxSOCKET_NOWAIT)
373 {
374 GSocket_SetNonBlocking(m_socket, 1);
375 ret = GSocket_Read(m_socket, (char *)buffer, nbytes);
376 GSocket_SetNonBlocking(m_socket, 0);
377
378 if (ret > 0)
379 total += ret;
380 }
381 else
382 {
383 bool more = true;
384
385 while (more)
386 {
387 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
388 break;
389
390 ret = GSocket_Read(m_socket, (char *)buffer, nbytes);
391
392 if (ret > 0)
393 {
394 total += ret;
395 nbytes -= ret;
396 buffer = (char *)buffer + ret;
397 }
398
399 // If we got here and wxSOCKET_WAITALL is not set, we can leave
400 // now. Otherwise, wait until we recv all the data or until there
401 // is an error.
402 //
403 more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
404 }
405 }
406
407 return total;
408}
409
410wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
411{
412 wxUint32 len, len2, sig, total;
413 bool error;
414 int old_flags;
415 struct
416 {
417 unsigned char sig[4];
418 unsigned char len[4];
419 }
420 msg;
421
422 // Mask read events
423 m_reading = true;
424
425 total = 0;
426 error = true;
427 old_flags = m_flags;
428 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
429
430 if (_Read(&msg, sizeof(msg)) != sizeof(msg))
431 goto exit;
432
433 sig = (wxUint32)msg.sig[0];
434 sig |= (wxUint32)(msg.sig[1] << 8);
435 sig |= (wxUint32)(msg.sig[2] << 16);
436 sig |= (wxUint32)(msg.sig[3] << 24);
437
438 if (sig != 0xfeeddead)
439 {
440 wxLogWarning( wxT("wxSocket: invalid signature in ReadMsg.") );
441 goto exit;
442 }
443
444 len = (wxUint32)msg.len[0];
445 len |= (wxUint32)(msg.len[1] << 8);
446 len |= (wxUint32)(msg.len[2] << 16);
447 len |= (wxUint32)(msg.len[3] << 24);
448
449 if (len > nbytes)
450 {
451 len2 = len - nbytes;
452 len = nbytes;
453 }
454 else
455 len2 = 0;
456
457 // Don't attemp to read if the msg was zero bytes long.
458 if (len)
459 {
460 total = _Read(buffer, len);
461
462 if (total != len)
463 goto exit;
464 }
465 if (len2)
466 {
467 char *discard_buffer = new char[MAX_DISCARD_SIZE];
468 long discard_len;
469
470 // NOTE: discarded bytes don't add to m_lcount.
471 do
472 {
473 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
474 discard_len = _Read(discard_buffer, (wxUint32)discard_len);
475 len2 -= (wxUint32)discard_len;
476 }
477 while ((discard_len > 0) && len2);
478
479 delete [] discard_buffer;
480
481 if (len2 != 0)
482 goto exit;
483 }
484 if (_Read(&msg, sizeof(msg)) != sizeof(msg))
485 goto exit;
486
487 sig = (wxUint32)msg.sig[0];
488 sig |= (wxUint32)(msg.sig[1] << 8);
489 sig |= (wxUint32)(msg.sig[2] << 16);
490 sig |= (wxUint32)(msg.sig[3] << 24);
491
492 if (sig != 0xdeadfeed)
493 {
494 wxLogWarning( wxT("wxSocket: invalid signature in ReadMsg.") );
495 goto exit;
496 }
497
498 // everything was OK
499 error = false;
500
501exit:
502 m_error = error;
503 m_lcount = total;
504 m_reading = false;
505 SetFlags(old_flags);
506
507 return *this;
508}
509
510wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
511{
512 // Mask read events
513 m_reading = true;
514
515 m_lcount = _Read(buffer, nbytes);
516 Pushback(buffer, m_lcount);
517
518 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
519 if (m_flags & wxSOCKET_WAITALL)
520 m_error = (m_lcount != nbytes);
521 else
522 m_error = (m_lcount == 0);
523
524 // Allow read events again
525 m_reading = false;
526
527 return *this;
528}
529
530wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
531{
532 // Mask write events
533 m_writing = true;
534
535 m_lcount = _Write(buffer, nbytes);
536
537 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
538 if (m_flags & wxSOCKET_WAITALL)
539 m_error = (m_lcount != nbytes);
540 else
541 m_error = (m_lcount == 0);
542
543 // Allow write events again
544 m_writing = false;
545
546 return *this;
547}
548
549wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
550{
551 wxUint32 total = 0;
552
553 // If the socket is invalid or parameters are ill, return immediately
554 if (!m_socket || !buffer || !nbytes)
555 return 0;
556
557 // Possible combinations (they are checked in this order)
558 // wxSOCKET_NOWAIT
559 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
560 // wxSOCKET_BLOCK
561 // wxSOCKET_NONE
562 //
563 int ret;
564 if (m_flags & wxSOCKET_NOWAIT)
565 {
566 GSocket_SetNonBlocking(m_socket, 1);
567 ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);
568 GSocket_SetNonBlocking(m_socket, 0);
569
570 if (ret > 0)
571 total = ret;
572 }
573 else
574 {
575 bool more = true;
576
577 while (more)
578 {
579 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
580 break;
581
582 ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);
583
584 if (ret > 0)
585 {
586 total += ret;
587 nbytes -= ret;
588 buffer = (const char *)buffer + ret;
589 }
590
591 // If we got here and wxSOCKET_WAITALL is not set, we can leave
592 // now. Otherwise, wait until we send all the data or until there
593 // is an error.
594 //
595 more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
596 }
597 }
598
599 return total;
600}
601
602wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
603{
604 wxUint32 total;
605 bool error;
606 struct
607 {
608 unsigned char sig[4];
609 unsigned char len[4];
610 }
611 msg;
612
613 // Mask write events
614 m_writing = true;
615
616 error = true;
617 total = 0;
618 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
619
620 msg.sig[0] = (unsigned char) 0xad;
621 msg.sig[1] = (unsigned char) 0xde;
622 msg.sig[2] = (unsigned char) 0xed;
623 msg.sig[3] = (unsigned char) 0xfe;
624
625 msg.len[0] = (unsigned char) (nbytes & 0xff);
626 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
627 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
628 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
629
630 if (_Write(&msg, sizeof(msg)) < sizeof(msg))
631 goto exit;
632
633 total = _Write(buffer, nbytes);
634
635 if (total < nbytes)
636 goto exit;
637
638 msg.sig[0] = (unsigned char) 0xed;
639 msg.sig[1] = (unsigned char) 0xfe;
640 msg.sig[2] = (unsigned char) 0xad;
641 msg.sig[3] = (unsigned char) 0xde;
642 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
643
644 if ((_Write(&msg, sizeof(msg))) < sizeof(msg))
645 goto exit;
646
647 // everything was OK
648 error = false;
649
650exit:
651 m_error = error;
652 m_lcount = total;
653 m_writing = false;
654
655 return *this;
656}
657
658wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
659{
660 if (nbytes != 0)
661 Pushback(buffer, nbytes);
662
663 m_error = false;
664 m_lcount = nbytes;
665
666 return *this;
667}
668
669wxSocketBase& wxSocketBase::Discard()
670{
671 char *buffer = new char[MAX_DISCARD_SIZE];
672 wxUint32 ret;
673 wxUint32 total = 0;
674
675 // Mask read events
676 m_reading = true;
677
678 SetFlags(wxSOCKET_NOWAIT);
679
680 do
681 {
682 ret = _Read(buffer, MAX_DISCARD_SIZE);
683 total += ret;
684 }
685 while (ret == MAX_DISCARD_SIZE);
686
687 delete[] buffer;
688 m_lcount = total;
689 m_error = false;
690
691 // Allow read events again
692 m_reading = false;
693
694 return *this;
695}
696
697// --------------------------------------------------------------------------
698// Wait functions
699// --------------------------------------------------------------------------
700
701// All Wait functions poll the socket using GSocket_Select() to
702// check for the specified combination of conditions, until one
703// of these conditions become true, an error occurs, or the
704// timeout elapses. The polling loop calls PROCESS_EVENTS(), so
705// this won't block the GUI.
706
707bool wxSocketBase::_Wait(long seconds,
708 long milliseconds,
709 wxSocketEventFlags flags)
710{
711 GSocketEventFlags result;
712 long timeout;
713
714 // Set this to true to interrupt ongoing waits
715 m_interrupt = false;
716
717 // Check for valid socket
718 if (!m_socket)
719 return false;
720
721 // Check for valid timeout value.
722 if (seconds != -1)
723 timeout = seconds * 1000 + milliseconds;
724 else
725 timeout = m_timeout * 1000;
726
727#if !defined(wxUSE_GUI) || !wxUSE_GUI
728 GSocket_SetTimeout(m_socket, timeout);
729#endif
730
731 // Wait in an active polling loop.
732 //
733 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
734 // hurt. It has to be here because the (GSocket) event might arrive
735 // a bit delayed, and it has to be in OnRequest as well because we
736 // don't know whether the Wait functions are being used.
737 //
738 // Do this at least once (important if timeout == 0, when
739 // we are just polling). Also, if just polling, do not yield.
740
741 wxStopWatch chrono;
742 bool done = false;
743
744 while (!done)
745 {
746 result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
747
748 // Incoming connection (server) or connection established (client)
749 if (result & GSOCK_CONNECTION_FLAG)
750 {
751 m_connected = true;
752 m_establishing = false;
753
754 return true;
755 }
756
757 // Data available or output buffer ready
758 if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
759 {
760 return true;
761 }
762
763 // Connection lost
764 if (result & GSOCK_LOST_FLAG)
765 {
766 m_connected = false;
767 m_establishing = false;
768
769 return (flags & GSOCK_LOST_FLAG) != 0;
770 }
771
772 // Wait more?
773 if ((!timeout) || (chrono.Time() > timeout) || (m_interrupt))
774 done = true;
775 else
776 PROCESS_EVENTS();
777 }
778
779 return false;
780}
781
782bool wxSocketBase::Wait(long seconds, long milliseconds)
783{
784 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
785 GSOCK_OUTPUT_FLAG |
786 GSOCK_CONNECTION_FLAG |
787 GSOCK_LOST_FLAG);
788}
789
790bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
791{
792 // Check pushback buffer before entering _Wait
793 if (m_unread)
794 return true;
795
796 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
797 // _Wait becuase of the semantics of WaitForRead: a return
798 // value of true means that a GSocket_Read call will return
799 // immediately, not that there is actually data to read.
800
801 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
802}
803
804bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
805{
806 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
807}
808
809bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
810{
811 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
812}
813
814// --------------------------------------------------------------------------
815// Miscellaneous
816// --------------------------------------------------------------------------
817
818//
819// Get local or peer address
820//
821
822bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
823{
824 GAddress *peer;
825
826 if (!m_socket)
827 return false;
828
829 peer = GSocket_GetPeer(m_socket);
830
831 // copying a null address would just trigger an assert anyway
832
833 if (!peer)
834 return false;
835
836 addr_man.SetAddress(peer);
837 GAddress_destroy(peer);
838
839 return true;
840}
841
842bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
843{
844#if 0
845 GAddress *local;
846
847 if (!m_socket)
848 return false;
849
850 local = GSocket_GetLocal(m_socket);
851 addr_man.SetAddress(local);
852 GAddress_destroy(local);
853#endif
854
855 return true;
856}
857
858//
859// Save and restore socket state
860//
861
862void wxSocketBase::SaveState()
863{
864 wxSocketState *state;
865
866 state = new wxSocketState();
867
868 state->m_flags = m_flags;
869 state->m_notify = m_notify;
870 state->m_eventmask = m_eventmask;
871 state->m_clientData = m_clientData;
872
873 m_states.Append(state);
874}
875
876void wxSocketBase::RestoreState()
877{
878 wxList::compatibility_iterator node;
879 wxSocketState *state;
880
881 node = m_states.GetLast();
882 if (!node)
883 return;
884
885 state = (wxSocketState *)node->GetData();
886
887 m_flags = state->m_flags;
888 m_notify = state->m_notify;
889 m_eventmask = state->m_eventmask;
890 m_clientData = state->m_clientData;
891
892 m_states.Erase(node);
893 delete state;
894}
895
896//
897// Timeout and flags
898//
899
900void wxSocketBase::SetTimeout(long seconds)
901{
902 m_timeout = seconds;
903
904#if 0
905 if (m_socket)
906 GSocket_SetTimeout(m_socket, m_timeout * 1000);
907#endif
908}
909
910void wxSocketBase::SetFlags(wxSocketFlags flags)
911{
912 m_flags = flags;
913}
914
915
916// --------------------------------------------------------------------------
917// Event handling
918// --------------------------------------------------------------------------
919
920// A note on how events are processed, which is probably the most
921// difficult thing to get working right while keeping the same API
922// and functionality for all platforms.
923//
924// When GSocket detects an event, it calls wx_socket_callback, which in
925// turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
926// object. OnRequest does some housekeeping, and if the event is to be
927// propagated to the user, it creates a new wxSocketEvent object and
928// posts it. The event is not processed immediately, but delayed with
929// AddPendingEvent instead. This is necessary in order to decouple the
930// event processing from wx_socket_callback; otherwise, subsequent IO
931// calls made from the user event handler would fail, as gtk callbacks
932// are not reentrant.
933//
934// Note that, unlike events, user callbacks (now deprecated) are _not_
935// decoupled from wx_socket_callback and thus they suffer from a variety
936// of problems. Avoid them where possible and use events instead.
937
938extern "C"
939void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
940 GSocketEvent notification,
941 char *cdata)
942{
943 wxSocketBase *sckobj = (wxSocketBase *)cdata;
944
945 sckobj->OnRequest((wxSocketNotify) notification);
946}
947
948void wxSocketBase::OnRequest(wxSocketNotify notification)
949{
950 // NOTE: We duplicate some of the code in _Wait, but this doesn't
951 // hurt. It has to be here because the (GSocket) event might arrive
952 // a bit delayed, and it has to be in _Wait as well because we don't
953 // know whether the Wait functions are being used.
954
955 switch (notification)
956 {
957 case wxSOCKET_CONNECTION:
958 m_establishing = false;
959 m_connected = true;
960 break;
961
962 // If we are in the middle of a R/W operation, do not
963 // propagate events to users. Also, filter 'late' events
964 // which are no longer valid.
965
966 case wxSOCKET_INPUT:
967 if (m_reading || !GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
968 return;
969 break;
970
971 case wxSOCKET_OUTPUT:
972 if (m_writing || !GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
973 return;
974 break;
975
976 case wxSOCKET_LOST:
977 m_connected = false;
978 m_establishing = false;
979 break;
980
981 default:
982 break;
983 }
984
985 // Schedule the event
986
987 wxSocketEventFlags flag = 0;
988 wxUnusedVar(flag);
989 switch (notification)
990 {
991 case GSOCK_INPUT:
992 flag = GSOCK_INPUT_FLAG;
993 break;
994
995 case GSOCK_OUTPUT:
996 flag = GSOCK_OUTPUT_FLAG;
997 break;
998
999 case GSOCK_CONNECTION:
1000 flag = GSOCK_CONNECTION_FLAG;
1001 break;
1002
1003 case GSOCK_LOST:
1004 flag = GSOCK_LOST_FLAG;
1005 break;
1006
1007 default:
1008 wxLogWarning( wxT("wxSocket: unknown event!") );
1009 return;
1010 }
1011
1012 if (((m_eventmask & flag) == flag) && m_notify)
1013 {
1014 if (m_handler)
1015 {
1016 wxSocketEvent event(m_id);
1017 event.m_event = notification;
1018 event.m_clientData = m_clientData;
1019 event.SetEventObject(this);
1020
1021 m_handler->AddPendingEvent(event);
1022 }
1023 }
1024}
1025
1026void wxSocketBase::Notify(bool notify)
1027{
1028 m_notify = notify;
1029}
1030
1031void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1032{
1033 m_eventmask = flags;
1034}
1035
1036void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1037{
1038 m_handler = &handler;
1039 m_id = id;
1040}
1041
1042// --------------------------------------------------------------------------
1043// Pushback buffer
1044// --------------------------------------------------------------------------
1045
1046void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1047{
1048 if (!size)
1049 return;
1050
1051 if (m_unread == NULL)
1052 m_unread = malloc(size);
1053 else
1054 {
1055 void *tmp;
1056
1057 tmp = malloc(m_unrd_size + size);
1058 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1059 free(m_unread);
1060
1061 m_unread = tmp;
1062 }
1063
1064 m_unrd_size += size;
1065
1066 memcpy(m_unread, buffer, size);
1067}
1068
1069wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1070{
1071 if (!m_unrd_size)
1072 return 0;
1073
1074 if (size > (m_unrd_size-m_unrd_cur))
1075 size = m_unrd_size-m_unrd_cur;
1076
1077 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1078
1079 if (!peek)
1080 {
1081 m_unrd_cur += size;
1082 if (m_unrd_size == m_unrd_cur)
1083 {
1084 free(m_unread);
1085 m_unread = NULL;
1086 m_unrd_size = 0;
1087 m_unrd_cur = 0;
1088 }
1089 }
1090
1091 return size;
1092}
1093
1094
1095// ==========================================================================
1096// wxSocketServer
1097// ==========================================================================
1098
1099// --------------------------------------------------------------------------
1100// Ctor
1101// --------------------------------------------------------------------------
1102
1103wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1104 wxSocketFlags flags)
1105 : wxSocketBase(flags, wxSOCKET_SERVER)
1106{
1107 wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );
1108
1109 m_socket = GSocket_new();
1110
1111 if (!m_socket)
1112 {
1113 wxLogTrace( wxTRACE_Socket, wxT("*** GSocket_new failed") );
1114 return;
1115 }
1116
1117 // Setup the socket as server
1118
1119#if 0
1120 GSocket_SetLocal(m_socket, addr_man.GetAddress());
1121 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
1122 {
1123 GSocket_destroy(m_socket);
1124 m_socket = NULL;
1125
1126 wxLogTrace( wxTRACE_Socket, wxT("*** GSocket_SetServer failed") );
1127 return;
1128 }
1129
1130 GSocket_SetTimeout(m_socket, m_timeout * 1000);
1131 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1132 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1133 wx_socket_callback, (char *)this);
1134#endif
1135}
1136
1137// --------------------------------------------------------------------------
1138// Accept
1139// --------------------------------------------------------------------------
1140
1141bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1142{
1143 GSocket *child_socket;
1144
1145 if (!m_socket)
1146 return false;
1147
1148 // If wait == false, then the call should be nonblocking.
1149 // When we are finished, we put the socket to blocking mode
1150 // again.
1151
1152#if 0
1153 if (!wait)
1154 GSocket_SetNonBlocking(m_socket, 1);
1155
1156 child_socket = GSocket_WaitConnection(m_socket);
1157
1158 if (!wait)
1159 GSocket_SetNonBlocking(m_socket, 0);
1160
1161 if (!child_socket)
1162 return false;
1163
1164 sock.m_type = wxSOCKET_BASE;
1165 sock.m_socket = child_socket;
1166 sock.m_connected = true;
1167
1168 GSocket_SetTimeout(sock.m_socket, sock.m_timeout * 1000);
1169 GSocket_SetCallback(sock.m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1170 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1171 wx_socket_callback, (char *)&sock);
1172#endif
1173
1174 return true;
1175}
1176
1177wxSocketBase *wxSocketServer::Accept(bool wait)
1178{
1179 wxSocketBase* sock = new wxSocketBase();
1180
1181 sock->SetFlags(m_flags);
1182
1183 if (!AcceptWith(*sock, wait))
1184 {
1185 sock->Destroy();
1186 sock = NULL;
1187 }
1188
1189 return sock;
1190}
1191
1192bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1193{
1194 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1195}
1196
1197// ==========================================================================
1198// wxSocketClient
1199// ==========================================================================
1200
1201// --------------------------------------------------------------------------
1202// Ctor and dtor
1203// --------------------------------------------------------------------------
1204
1205wxSocketClient::wxSocketClient(wxSocketFlags flags)
1206 : wxSocketBase(flags, wxSOCKET_CLIENT)
1207{
1208}
1209
1210wxSocketClient::~wxSocketClient()
1211{
1212}
1213
1214// --------------------------------------------------------------------------
1215// Connect
1216// --------------------------------------------------------------------------
1217
1218bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1219{
1220 GSocketError err;
1221
1222 if (m_socket)
1223 {
1224 // Shutdown and destroy the socket
1225 Close();
1226 GSocket_destroy(m_socket);
1227 }
1228
1229 m_socket = GSocket_new();
1230 m_connected = false;
1231 m_establishing = false;
1232
1233 if (!m_socket)
1234 return false;
1235
1236 GSocket_SetTimeout(m_socket, m_timeout * 1000);
1237 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1238 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1239 wx_socket_callback, (char *)this);
1240
1241 // If wait == false, then the call should be nonblocking.
1242 // When we are finished, we put the socket to blocking mode
1243 // again.
1244
1245 if (!wait)
1246 GSocket_SetNonBlocking(m_socket, 1);
1247
1248 GSocket_SetPeer(m_socket, addr_man.GetAddress());
1249 err = GSocket_Connect(m_socket, GSOCK_STREAMED);
1250
1251 if (!wait)
1252 GSocket_SetNonBlocking(m_socket, 0);
1253
1254 if (err != GSOCK_NOERROR)
1255 {
1256 if (err == GSOCK_WOULDBLOCK)
1257 m_establishing = true;
1258
1259 return false;
1260 }
1261
1262 m_connected = true;
1263 return true;
1264}
1265
1266bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1267{
1268 if (m_connected) // Already connected
1269 return true;
1270
1271 if (!m_establishing || !m_socket) // No connection in progress
1272 return false;
1273
1274 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
1275}
1276
1277// ==========================================================================
1278// wxDatagramSocket
1279// ==========================================================================
1280
1281/* NOTE: experimental stuff - might change */
1282
1283wxDatagramSocket::wxDatagramSocket( wxSockAddress& addr,
1284 wxSocketFlags flags )
1285 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1286{
1287#if 0
1288 // Create the socket
1289 m_socket = GSocket_new();
1290
1291 if (!m_socket)
1292 return;
1293
1294 // Setup the socket as non connection oriented
1295 GSocket_SetLocal(m_socket, addr.GetAddress());
1296 if( GSocket_SetNonOriented(m_socket) != GSOCK_NOERROR )
1297 {
1298 GSocket_destroy(m_socket);
1299 m_socket = NULL;
1300 return;
1301 }
1302
1303 // Initialize all stuff
1304 m_connected = false;
1305 m_establishing = false;
1306 GSocket_SetTimeout( m_socket, m_timeout );
1307 GSocket_SetCallback( m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1308 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1309 wx_socket_callback, (char*)this );
1310#endif
1311}
1312
1313wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1314 void* buf,
1315 wxUint32 nBytes )
1316{
1317 Read(buf, nBytes);
1318 GetPeer(addr);
1319 return (*this);
1320}
1321
1322wxDatagramSocket& wxDatagramSocket::SendTo( wxSockAddress& addr,
1323 const void* buf,
1324 wxUint32 nBytes )
1325{
1326 GSocket_SetPeer(m_socket, addr.GetAddress());
1327 Write(buf, nBytes);
1328 return (*this);
1329}
1330
1331/*
1332 * -------------------------------------------------------------------------
1333 * GAddress
1334 * -------------------------------------------------------------------------
1335 */
1336
1337/* CHECK_ADDRESS verifies that the current address family is either
1338 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1339 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1340 * an appropiate error code.
1341 *
1342 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1343 */
1344#define CHECK_ADDRESS(address, family) \
1345{ \
1346 if (address->m_family == GSOCK_NOFAMILY) \
1347 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1348 return address->m_error; \
1349 if (address->m_family != GSOCK_##family) \
1350 { \
1351 address->m_error = GSOCK_INVADDR; \
1352 return GSOCK_INVADDR; \
1353 } \
1354}
1355
1356#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1357{ \
1358 if (address->m_family == GSOCK_NOFAMILY) \
1359 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1360 return retval; \
1361 if (address->m_family != GSOCK_##family) \
1362 { \
1363 address->m_error = GSOCK_INVADDR; \
1364 return retval; \
1365 } \
1366}
1367
1368
1369GAddress *GAddress_new(void)
1370{
1371 GAddress *address;
1372
1373 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1374 return NULL;
1375
1376 address->m_family = GSOCK_NOFAMILY;
1377 address->m_addr = NULL;
1378 address->m_len = 0;
1379
1380 return address;
1381}
1382
1383GAddress *GAddress_copy(GAddress *address)
1384{
1385 GAddress *addr2;
1386
1387 assert(address != NULL);
1388
1389 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1390 return NULL;
1391
1392 memcpy(addr2, address, sizeof(GAddress));
1393
1394 if (address->m_addr && address->m_len > 0)
1395 {
1396 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1397 if (addr2->m_addr == NULL)
1398 {
1399 free(addr2);
1400 return NULL;
1401 }
1402
1403 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1404 }
1405
1406 return addr2;
1407}
1408
1409void GAddress_destroy(GAddress *address)
1410{
1411 assert( address != NULL );
1412
1413 if (address->m_addr)
1414 free(address->m_addr);
1415
1416 free(address);
1417}
1418
1419void GAddress_SetFamily(GAddress *address, GAddressType type)
1420{
1421 assert(address != NULL);
1422
1423 address->m_family = type;
1424}
1425
1426GAddressType GAddress_GetFamily(GAddress *address)
1427{
1428 assert( address != NULL );
1429
1430 return address->m_family;
1431}
1432
1433GSocketError _GAddress_translate_from(GAddress *address,
1434 struct sockaddr *addr, int len)
1435{
1436 address->m_realfamily = addr->sa_family;
1437 switch (addr->sa_family)
1438 {
1439 case AF_INET:
1440 address->m_family = GSOCK_INET;
1441 break;
1442
1443 case AF_UNIX:
1444 address->m_family = GSOCK_UNIX;
1445 break;
1446
1447#ifdef AF_INET6
1448 case AF_INET6:
1449 address->m_family = GSOCK_INET6;
1450 break;
1451#endif
1452
1453 default:
1454 {
1455 address->m_error = GSOCK_INVOP;
1456 return GSOCK_INVOP;
1457 }
1458 }
1459
1460 if (address->m_addr)
1461 free(address->m_addr);
1462
1463 address->m_len = len;
1464 address->m_addr = (struct sockaddr *)malloc(len);
1465
1466 if (address->m_addr == NULL)
1467 {
1468 address->m_error = GSOCK_MEMERR;
1469 return GSOCK_MEMERR;
1470 }
1471
1472 memcpy(address->m_addr, addr, len);
1473
1474 return GSOCK_NOERROR;
1475}
1476
1477GSocketError _GAddress_translate_to(GAddress *address,
1478 struct sockaddr **addr, int *len)
1479{
1480 if (!address->m_addr)
1481 {
1482 address->m_error = GSOCK_INVADDR;
1483 return GSOCK_INVADDR;
1484 }
1485
1486 *len = address->m_len;
1487 *addr = (struct sockaddr *)malloc(address->m_len);
1488 if (*addr == NULL)
1489 {
1490 address->m_error = GSOCK_MEMERR;
1491 return GSOCK_MEMERR;
1492 }
1493
1494 memcpy(*addr, address->m_addr, address->m_len);
1495 return GSOCK_NOERROR;
1496}
1497
1498/*
1499 * -------------------------------------------------------------------------
1500 * Internet address family
1501 * -------------------------------------------------------------------------
1502 */
1503
1504GSocketError _GAddress_Init_INET(GAddress *address)
1505{
1506 address->m_len = sizeof(struct sockaddr_in);
1507 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1508 if (address->m_addr == NULL)
1509 {
1510 address->m_error = GSOCK_MEMERR;
1511 return GSOCK_MEMERR;
1512 }
1513
1514 memset( address->m_addr , 0 , address->m_len ) ;
1515 address->m_family = GSOCK_INET;
1516 address->m_realfamily = PF_INET;
1517 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1518 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1519
1520 return GSOCK_NOERROR;
1521}
1522
1523GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1524{
1525 struct hostent *he;
1526 struct in_addr *addr;
1527
1528 assert( address != NULL );
1529 CHECK_ADDRESS( address, INET );
1530
1531 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1532
1533 // If it is a numeric host name, convert it now
1534#if defined(HAVE_INET_ATON)
1535 if (inet_aton(hostname, addr) == 0)
1536 {
1537#elif defined(HAVE_INET_ADDR)
1538 if ( (addr->s_addr = inet_addr(hostname)) == -1 )
1539 {
1540#else
1541 // Use gethostbyname by default
1542#ifndef __WXMAC__
1543 int val = 1; // VA doesn't like constants in conditional expressions
1544 if (val)
1545#endif
1546 {
1547#endif
1548 struct in_addr *array_addr;
1549
1550 // It is a real name, we solve it
1551 if ((he = gethostbyname(hostname)) == NULL)
1552 {
1553 // Reset to invalid address
1554 addr->s_addr = INADDR_NONE;
1555 address->m_error = GSOCK_NOHOST;
1556 return GSOCK_NOHOST;
1557 }
1558 array_addr = (struct in_addr *) *(he->h_addr_list);
1559 addr->s_addr = array_addr[0].s_addr;
1560 }
1561
1562 return GSOCK_NOERROR;
1563}
1564
1565GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
1566{
1567 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
1568}
1569
1570GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1571{
1572 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1573}
1574
1575GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1576 unsigned long hostaddr)
1577{
1578 struct in_addr *addr;
1579
1580 assert( address != NULL );
1581 CHECK_ADDRESS( address, INET );
1582
1583 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1584 addr->s_addr = htonl(hostaddr) ;
1585
1586 return GSOCK_NOERROR;
1587}
1588
1589GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1590 const char *protocol)
1591{
1592 struct servent *se;
1593 struct sockaddr_in *addr;
1594
1595 assert( address != NULL );
1596 CHECK_ADDRESS( address, INET );
1597
1598 if (!port)
1599 {
1600 address->m_error = GSOCK_INVPORT;
1601 return GSOCK_INVPORT;
1602 }
1603
1604 se = getservbyname(port, protocol);
1605 if (!se)
1606 {
1607 // the cast to int suppresses compiler warnings
1608 // about subscript having the type char
1609 if (isdigit((int)port[0]))
1610 {
1611 int port_int;
1612
1613 port_int = atoi(port);
1614 addr = (struct sockaddr_in *)address->m_addr;
1615 addr->sin_port = htons(port_int);
1616 return GSOCK_NOERROR;
1617 }
1618
1619 address->m_error = GSOCK_INVPORT;
1620 return GSOCK_INVPORT;
1621 }
1622
1623 addr = (struct sockaddr_in *)address->m_addr;
1624 addr->sin_port = se->s_port;
1625
1626 return GSOCK_NOERROR;
1627}
1628
1629GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1630{
1631 struct sockaddr_in *addr;
1632
1633 assert( address != NULL );
1634 CHECK_ADDRESS( address, INET );
1635
1636 addr = (struct sockaddr_in *)address->m_addr;
1637 addr->sin_port = htons(port);
1638
1639 return GSOCK_NOERROR;
1640}
1641
1642GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1643{
1644 struct hostent *he;
1645 char *addr_buf;
1646 struct sockaddr_in *addr;
1647
1648 assert( address != NULL );
1649 CHECK_ADDRESS( address, INET );
1650
1651 addr = (struct sockaddr_in *)address->m_addr;
1652 addr_buf = (char *)&(addr->sin_addr);
1653
1654 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1655 if (he == NULL)
1656 {
1657 address->m_error = GSOCK_NOHOST;
1658 return GSOCK_NOHOST;
1659 }
1660
1661 strncpy(hostname, he->h_name, sbuf);
1662
1663 return GSOCK_NOERROR;
1664}
1665
1666unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1667{
1668 struct sockaddr_in *addr;
1669
1670 assert( address != NULL );
1671 CHECK_ADDRESS_RETVAL( address, INET, 0 );
1672
1673 addr = (struct sockaddr_in *)address->m_addr;
1674
1675 return ntohl(addr->sin_addr.s_addr) ;
1676}
1677
1678unsigned short GAddress_INET_GetPort(GAddress *address)
1679{
1680 struct sockaddr_in *addr;
1681
1682 assert( address != NULL );
1683 CHECK_ADDRESS_RETVAL( address, INET, 0 );
1684
1685 addr = (struct sockaddr_in *)address->m_addr;
1686
1687 return ntohs(addr->sin_port);
1688}
1689
1690/*
1691 * -------------------------------------------------------------------------
1692 * Unix address family
1693 * -------------------------------------------------------------------------
1694 */
1695
1696GSocketError _GAddress_Init_UNIX(GAddress *address)
1697{
1698 address->m_len = sizeof(struct sockaddr_un);
1699 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1700 if (address->m_addr == NULL)
1701 {
1702 address->m_error = GSOCK_MEMERR;
1703 return GSOCK_MEMERR;
1704 }
1705
1706 address->m_family = GSOCK_UNIX;
1707 address->m_realfamily = PF_UNIX;
1708 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1709 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1710
1711 return GSOCK_NOERROR;
1712}
1713
1714#define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
1715
1716GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1717{
1718 struct sockaddr_un *addr;
1719
1720 assert( address != NULL );
1721 CHECK_ADDRESS( address, UNIX );
1722
1723 addr = ((struct sockaddr_un *)address->m_addr);
1724 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
1725 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
1726
1727 return GSOCK_NOERROR;
1728}
1729
1730GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1731{
1732 struct sockaddr_un *addr;
1733
1734 assert( address != NULL );
1735 CHECK_ADDRESS( address, UNIX );
1736
1737 addr = (struct sockaddr_un *)address->m_addr;
1738
1739 strncpy(path, addr->sun_path, sbuf);
1740
1741 return GSOCK_NOERROR;
1742}
1743
1744/* Address handling */
1745
1746/* GSocket_SetLocal:
1747 * GSocket_GetLocal:
1748 * GSocket_SetPeer:
1749 * GSocket_GetPeer:
1750 * Set or get the local or peer address for this socket. The 'set'
1751 * functions return GSOCK_NOERROR on success, an error code otherwise.
1752 * The 'get' functions return a pointer to a GAddress object on success,
1753 * or NULL otherwise, in which case they set the error code of the
1754 * corresponding GSocket.
1755 *
1756 * Error codes:
1757 * GSOCK_INVSOCK - the socket is not valid.
1758 * GSOCK_INVADDR - the address is not valid.
1759 */
1760
1761GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
1762{
1763 assert( socket != NULL );
1764
1765 // the socket must be initialized, or it must be a server
1766 if ((socket->m_fd != INVALID_SOCKET && !socket->m_server))
1767 {
1768 socket->m_error = GSOCK_INVSOCK;
1769 return GSOCK_INVSOCK;
1770 }
1771
1772 // check address
1773 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
1774 {
1775 socket->m_error = GSOCK_INVADDR;
1776 return GSOCK_INVADDR;
1777 }
1778
1779 if (socket->m_local)
1780 GAddress_destroy(socket->m_local);
1781
1782 socket->m_local = GAddress_copy(address);
1783
1784 return GSOCK_NOERROR;
1785}
1786
1787GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
1788{
1789 assert(socket != NULL);
1790
1791 // check address
1792 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
1793 {
1794 socket->m_error = GSOCK_INVADDR;
1795 return GSOCK_INVADDR;
1796 }
1797
1798 if (socket->m_peer)
1799 GAddress_destroy(socket->m_peer);
1800
1801 socket->m_peer = GAddress_copy(address);
1802
1803 return GSOCK_NOERROR;
1804}
1805
1806GAddress *GSocket_GetLocal(GSocket *socket)
1807{
1808 GAddress *address;
1809 struct sockaddr addr;
1810 socklen_t size = sizeof(addr);
1811 GSocketError err;
1812
1813 assert( socket != NULL );
1814
1815 // try to get it from the m_local var first
1816 if (socket->m_local)
1817 return GAddress_copy(socket->m_local);
1818
1819 // else, if the socket is initialized, try getsockname
1820 if (socket->m_fd == INVALID_SOCKET)
1821 {
1822 socket->m_error = GSOCK_INVSOCK;
1823 return NULL;
1824 }
1825
1826 if (getsockname(socket->m_fd, &addr, (socklen_t *) &size) < 0)
1827 {
1828 socket->m_error = GSOCK_IOERR;
1829 return NULL;
1830 }
1831
1832 // got a valid address from getsockname, create a GAddress object
1833 address = GAddress_new();
1834 if (address == NULL)
1835 {
1836 socket->m_error = GSOCK_MEMERR;
1837 return NULL;
1838 }
1839
1840 err = _GAddress_translate_from(address, &addr, size);
1841 if (err != GSOCK_NOERROR)
1842 {
1843 GAddress_destroy(address);
1844 socket->m_error = err;
1845 return NULL;
1846 }
1847
1848 return address;
1849}
1850
1851GAddress *GSocket_GetPeer(GSocket *socket)
1852{
1853 assert(socket != NULL);
1854
1855 // try to get it from the m_peer var
1856 if (socket->m_peer)
1857 return GAddress_copy(socket->m_peer);
1858
1859 return NULL;
1860}
1861
1862
1863GSocket *GSocket_new(void)
1864{
1865 GSocket *socket;
1866 socket = (GSocket *)malloc(sizeof(GSocket));
1867
1868 if (socket == NULL)
1869 return NULL;
1870
1871 socket->m_fd = INVALID_SOCKET;
1872
1873 for (int i=0;i<GSOCK_MAX_EVENT;i++)
1874 {
1875 socket->m_cbacks[i] = NULL;
1876 }
1877
1878 socket->m_detected = 0;
1879
1880 socket->m_local = NULL;
1881 socket->m_peer = NULL;
1882 socket->m_error = GSOCK_NOERROR;
1883
1884 socket->m_non_blocking = false ;
1885 socket->m_stream = true;
1886// socket->m_oriented = true;
1887 socket->m_server = false;
1888 socket->m_establishing = false;
1889 socket->m_timeout = 10 * 60 * 1000;
1890 // 10 minutes * 60 sec * 1000 millisec
1891
1892 socket->m_cfSocket = NULL ;
1893 socket->m_runLoopSource = NULL ;
1894 socket->m_readStream = NULL;
1895 socket->m_writeStream = NULL;
1896
1897 return socket ;
1898}
1899
1900void GSocket_close(GSocket *socket)
1901{
1902 if ( socket->m_cfSocket != NULL )
1903 {
1904 if ( socket->m_readStream )
1905 {
1906 CFReadStreamClose(socket->m_readStream);
1907 CFRelease( socket->m_readStream ) ;
1908 socket->m_readStream = NULL ;
1909 }
1910
1911 if ( socket->m_writeStream )
1912 {
1913 CFWriteStreamClose(socket->m_writeStream);
1914 CFRelease( socket->m_writeStream ) ;
1915 socket->m_writeStream = NULL ;
1916 }
1917
1918 CFSocketInvalidate( socket->m_cfSocket ) ;
1919 CFRelease( socket->m_cfSocket ) ;
1920 socket->m_cfSocket = NULL ;
1921 socket->m_fd = INVALID_SOCKET ;
1922 }
1923}
1924
1925void GSocket_Shutdown(GSocket *socket)
1926{
1927 GSocket_close( socket );
1928
1929 // Disable GUI callbacks
1930 for (int evt = 0; evt < GSOCK_MAX_EVENT; evt++)
1931 socket->m_cbacks[evt] = NULL;
1932
1933 socket->m_detected = GSOCK_LOST_FLAG;
1934}
1935
1936void GSocket_destroy(GSocket *socket)
1937{
1938 assert( socket != NULL );
1939
1940 // Check that the socket is really shut down
1941 if (socket->m_fd != INVALID_SOCKET)
1942 GSocket_Shutdown(socket);
1943
1944 // Destroy private addresses
1945 if (socket->m_local)
1946 GAddress_destroy(socket->m_local);
1947
1948 if (socket->m_peer)
1949 GAddress_destroy(socket->m_peer);
1950
1951 // Destroy the socket itself
1952 free(socket);
1953}
1954
1955GSocketError GSocket_Connect(GSocket *socket, GSocketStream stream)
1956{
1957 assert( socket != NULL );
1958
1959 if (socket->m_fd != INVALID_SOCKET)
1960 {
1961 socket->m_error = GSOCK_INVSOCK;
1962 return GSOCK_INVSOCK;
1963 }
1964
1965 if (!socket->m_peer)
1966 {
1967 socket->m_error = GSOCK_INVADDR;
1968 return GSOCK_INVADDR;
1969 }
1970
1971 // Streamed or dgram socket?
1972 socket->m_stream = (stream == GSOCK_STREAMED);
1973 socket->m_oriented = true;
1974 socket->m_server = false;
1975 socket->m_establishing = false;
1976
1977 GSocketError returnErr = GSOCK_NOERROR ;
1978 CFSocketError err ;
1979
1980 CFAllocatorRef alloc = kCFAllocatorDefault ;
1981 CFSocketContext ctx ;
1982 memset( &ctx , 0 , sizeof( ctx ) ) ;
1983 ctx.info = socket ;
1984 socket->m_cfSocket = CFSocketCreate( alloc , socket->m_peer->m_realfamily ,
1985 stream == GSOCK_STREAMED ? SOCK_STREAM : SOCK_DGRAM , 0 ,
1986 kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack , wxMacCFSocketCallback , &ctx ) ;
1987 _GSocket_Enable(socket, GSOCK_CONNECTION);
1988
1989 socket->m_fd = CFSocketGetNative( socket->m_cfSocket ) ;
1990
1991 CFStreamCreatePairWithSocket ( alloc , socket->m_fd , &socket->m_readStream , &socket->m_writeStream );
1992 if ((socket->m_readStream == NULL) || (socket->m_writeStream == NULL))
1993 {
1994 GSocket_close(socket);
1995 socket->m_error = GSOCK_IOERR;
1996 return GSOCK_IOERR;
1997 }
1998
1999 if ( !CFReadStreamOpen( socket->m_readStream ) || !CFWriteStreamOpen( socket->m_writeStream ) )
2000 {
2001 GSocket_close(socket);
2002 socket->m_error = GSOCK_IOERR;
2003 return GSOCK_IOERR;
2004 }
2005
2006 CFRunLoopSourceRef rls = CFSocketCreateRunLoopSource(alloc , socket->m_cfSocket , 0);
2007 CFRunLoopAddSource(CFRunLoopGetCurrent() , rls, kCFRunLoopCommonModes);
2008 CFRelease(rls);
2009
2010 CFDataRef address = CFDataCreateWithBytesNoCopy(alloc, (const UInt8*) socket->m_peer->m_addr, socket->m_peer->m_len , kCFAllocatorNull);
2011 if ( !address )
2012 return GSOCK_MEMERR ;
2013
2014 err = CFSocketConnectToAddress( socket->m_cfSocket , address, socket->m_non_blocking ? -1 : socket->m_timeout / 1000 ) ;
2015 CFRelease(address);
2016
2017 if (err != kCFSocketSuccess)
2018 {
2019 if ( err == kCFSocketTimeout )
2020 {
2021 GSocket_close(socket);
2022 socket->m_error = GSOCK_TIMEDOUT ;
2023 return GSOCK_TIMEDOUT ;
2024 }
2025
2026 // we don't know whether a connect in progress will be issued like this
2027 if ( err != kCFSocketTimeout && socket->m_non_blocking )
2028 {
2029 socket->m_establishing = true;
2030 socket->m_error = GSOCK_WOULDBLOCK;
2031 return GSOCK_WOULDBLOCK;
2032 }
2033
2034 GSocket_close(socket);
2035 socket->m_error = GSOCK_IOERR;
2036 return GSOCK_IOERR;
2037 }
2038
2039 return GSOCK_NOERROR;
2040}
2041
2042/* Flags */
2043
2044/* GSocket_SetNonBlocking:
2045 * Sets the socket to non-blocking mode.
2046 * All IO calls will return immediately.
2047 */
2048void GSocket_SetNonBlocking(GSocket *socket, int non_block)
2049{
2050 assert( socket != NULL );
2051
2052// GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
2053
2054 socket->m_non_blocking = non_block;
2055}
2056
2057/*
2058 * GSocket_SetTimeout:
2059 * Sets the timeout for blocking calls. Time is expressed in
2060 * milliseconds.
2061 */
2062void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
2063{
2064 assert( socket != NULL );
2065
2066 socket->m_timeout = millisec;
2067}
2068
2069/* GSocket_GetError:
2070 * Returns the last error which occurred for this socket. Note that successful
2071 * operations do not clear this back to GSOCK_NOERROR, so use it only
2072 * after an error.
2073 */
2074GSocketError GSocket_GetError(GSocket *socket)
2075{
2076 assert( socket != NULL );
2077
2078 return socket->m_error;
2079}
2080
2081/* Callbacks */
2082
2083/* GSOCK_INPUT:
2084 * There is data to be read in the input buffer. If, after a read
2085 * operation, there is still data available, the callback function will
2086 * be called again.
2087 * GSOCK_OUTPUT:
2088 * The socket is available for writing. That is, the next write call
2089 * won't block. This event is generated only once, when the connection is
2090 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
2091 * when the output buffer empties again. This means that the app should
2092 * assume that it can write since the first OUTPUT event, and no more
2093 * OUTPUT events will be generated unless an error occurs.
2094 * GSOCK_CONNECTION:
2095 * Connection successfully established, for client sockets, or incoming
2096 * client connection, for server sockets. Wait for this event (also watch
2097 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
2098 * GSOCK_LOST:
2099 * The connection is lost (or a connection request failed); this could
2100 * be due to a failure, or due to the peer closing it gracefully.
2101 */
2102
2103/* GSocket_SetCallback:
2104 * Enables the callbacks specified by 'flags'. Note that 'flags'
2105 * may be a combination of flags OR'ed toghether, so the same
2106 * callback function can be made to accept different events.
2107 * The callback function must have the following prototype:
2108 *
2109 * void function(GSocket *socket, GSocketEvent event, char *cdata)
2110 */
2111void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
2112 GSocketCallback callback, char *cdata)
2113{
2114 int count;
2115
2116 assert( socket != NULL );
2117
2118 for (count = 0; count < GSOCK_MAX_EVENT; count++)
2119 {
2120 if ((flags & (1 << count)) != 0)
2121 {
2122 socket->m_cbacks[count] = callback;
2123 socket->m_data[count] = cdata;
2124 }
2125 }
2126}
2127
2128/* GSocket_UnsetCallback:
2129 * Disables all callbacks specified by 'flags', which may be a
2130 * combination of flags OR'ed toghether.
2131 */
2132void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
2133{
2134 int count;
2135
2136 assert(socket != NULL);
2137
2138 for (count = 0; count < GSOCK_MAX_EVENT; count++)
2139 {
2140 if ((flags & (1 << count)) != 0)
2141 {
2142 socket->m_cbacks[count] = NULL;
2143 socket->m_data[count] = NULL;
2144 }
2145 }
2146}
2147
2148
2149#define CALL_CALLBACK(socket, event) { \
2150 _GSocket_Disable(socket, event); \
2151 if (socket->m_cbacks[event]) \
2152 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
2153}
2154
2155void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
2156{
2157 int c;
2158 switch (event)
2159 {
2160 case GSOCK_CONNECTION:
2161 if (socket->m_server)
2162 c = kCFSocketReadCallBack;
2163 else
2164 c = kCFSocketConnectCallBack;
2165 break;
2166
2167 case GSOCK_LOST:
2168 case GSOCK_INPUT:
2169 c = kCFSocketReadCallBack;
2170 break;
2171
2172 case GSOCK_OUTPUT:
2173 c = kCFSocketWriteCallBack;
2174 break;
2175
2176 default:
2177 c = 0;
2178 }
2179
2180 CFSocketEnableCallBacks(socket->m_cfSocket, c);
2181}
2182
2183void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
2184{
2185 int c;
2186 switch (event)
2187 {
2188 case GSOCK_CONNECTION:
2189 if (socket->m_server)
2190 c = kCFSocketReadCallBack;
2191 else
2192 c = kCFSocketConnectCallBack;
2193 break;
2194
2195 case GSOCK_LOST:
2196 case GSOCK_INPUT:
2197 c = kCFSocketReadCallBack;
2198 break;
2199
2200 case GSOCK_OUTPUT:
2201 c = kCFSocketWriteCallBack;
2202 break;
2203
2204 default:
2205 c = 0;
2206 break;
2207 }
2208
2209 CFSocketDisableCallBacks(socket->m_cfSocket, c);
2210}
2211
2212void _GSocket_Enable(GSocket *socket, GSocketEvent event)
2213{
2214 socket->m_detected &= ~(1 << event);
2215 _GSocket_Install_Callback(socket, event);
2216}
2217
2218void _GSocket_Disable(GSocket *socket, GSocketEvent event)
2219{
2220 socket->m_detected |= (1 << event);
2221 _GSocket_Uninstall_Callback(socket, event);
2222}
2223
2224void wxMacCFSocketCallback(CFSocketRef s, CFSocketCallBackType callbackType,
2225 CFDataRef address, const void* data, void* info)
2226{
2227 GSocket* socket = (GSocket*)info;
2228
2229 switch (callbackType)
2230 {
2231 case kCFSocketConnectCallBack:
2232 if ( data )
2233 {
2234 SInt32 error = *((SInt32*)data) ;
2235 CALL_CALLBACK( socket , GSOCK_LOST ) ;
2236 GSocket_Shutdown(socket);
2237 }
2238 else
2239 {
2240 CALL_CALLBACK( socket , GSOCK_CONNECTION ) ;
2241 }
2242 break;
2243
2244 case kCFSocketReadCallBack:
2245 CALL_CALLBACK( socket , GSOCK_INPUT ) ;
2246 break;
2247
2248 case kCFSocketWriteCallBack:
2249 CALL_CALLBACK( socket , GSOCK_OUTPUT ) ;
2250 break;
2251
2252 default:
2253 break; // We shouldn't get here.
2254 }
2255}
2256
2257int GSocket_Read(GSocket *socket, char *buffer, int size)
2258{
2259 int ret = 0 ;
2260
2261 assert(socket != NULL);
2262 // if ( !CFReadStreamHasBytesAvailable() )
2263 ret = CFReadStreamRead( socket->m_readStream , (UInt8*) buffer , size ) ;
2264
2265 return ret;
2266}
2267
2268int GSocket_Write(GSocket *socket, const char *buffer, int size)
2269{
2270 int ret;
2271
2272 assert(socket != NULL);
2273 ret = CFWriteStreamWrite( socket->m_writeStream , (UInt8*) buffer , size ) ;
2274
2275 return ret;
2276}
2277
2278GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
2279{
2280 assert( socket != NULL );
2281
2282 return flags & socket->m_detected;
2283}
2284
2285// ==========================================================================
2286// wxSocketModule
2287// ==========================================================================
2288
2289class wxSocketModule : public wxModule
2290{
2291public:
2292 virtual bool OnInit()
2293 {
2294 // wxSocketBase will call GSocket_Init() itself when/if needed
2295 return true;
2296 }
2297
2298 virtual void OnExit()
2299 {
2300 if ( wxSocketBase::IsInitialized() )
2301 wxSocketBase::Shutdown();
2302 }
2303
2304private:
2305 DECLARE_DYNAMIC_CLASS(wxSocketModule)
2306};
2307
2308IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
2309
2310#endif
2311 // wxUSE_SOCKETS