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