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