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