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