]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
* Big memory bug fixed in socket/getline fixed.
[wxWidgets.git] / src / common / socket.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
5 // Davidson(1995) in wxWeb)
6 // Created: April 1997
7 // Updated: March 1998
8 // Copyright: (C) 1998, 1997, Guilhem Lavaux
9 // RCS_ID: $Id$
10 // License: see wxWindows license
11 ////////////////////////////////////////////////////////////////////////////////
12 #ifdef __GNUG__
13 #pragma implementation "socket.h"
14 #endif
15
16 #ifdef __MWERKS__
17 typedef int socklen_t ;
18 #endif
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 /////////////////////////////////////////////////////////////////////////////
28 // wxWindows headers
29 /////////////////////////////////////////////////////////////////////////////
30 #include <wx/defs.h>
31 #include <wx/object.h>
32 #include <wx/string.h>
33 #include <wx/timer.h>
34 #include <wx/utils.h>
35
36 // Not enough OS behaviour defined for wxStubs
37 #ifndef __WXSTUBS__
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42
43 /////////////////////////////////////////////////////////////////////////////
44 // System specific headers
45 /////////////////////////////////////////////////////////////////////////////
46 #ifdef __WXMAC__
47 // in order to avoid problems with our c library and double definitions
48 #define close closesocket
49 #define ioctl ioctlsocket
50
51 #include <wx/mac/macsock.h>
52 extern GUSISpinFn GUSISpin;
53 #define PROCESS_EVENTS() wxMacProcessEvents()
54 const short kwxMacNetEventsMax = 1000 ;
55 short wxMacNetEventsTop = 0 ;
56 short wxMacNetEventsBottom = 0 ;
57 short wxMacNetEventsEvents[kwxMacNetEventsMax] ;
58 void *wxMacNetEventsReferences[kwxMacNetEventsMax] ;
59
60 #define FD_READ 1
61 #define FD_WRITE 2
62 #define FD_CLOSE 4
63 #define FD_ACCEPT 8
64 #define FD_CONNECT 16
65 #define FD_READY 32
66
67 extern "C" void wxMacSocketHandlerProc( void *refcon , short event ) ; // adds events
68 extern "C" void wxMacSocketOnRequestProc( void *refcon , short event ) ; // consumes them
69 extern "C" void GUSISetReference( short sock , short eventmask , void * data ) ;
70 void wxMacProcessEvents() ;
71 #endif
72
73 #if defined(__WINDOWS__)
74 #include <winsock.h>
75 #endif // __WINDOWS__
76
77 #if defined(__UNIX__)
78
79 #ifdef VMS
80 #include <socket.h>
81 #else
82 #include <sys/socket.h>
83 #endif
84 #include <sys/ioctl.h>
85
86 #include <sys/time.h>
87 #include <unistd.h>
88
89 #ifdef sun
90 #include <sys/filio.h>
91 #endif
92
93 #endif // __UNIX__
94
95 #include <signal.h>
96 #include <errno.h>
97
98 #ifdef __VISUALC__
99 #include <io.h>
100 #endif
101
102 #if defined(__WXMOTIF__) || defined(__WXXT__)
103 #include <X11/Intrinsic.h>
104
105 /////////////////////////////
106 // Needs internal variables
107 /////////////////////////////
108 #ifdef __WXXT__
109 #define Uses_XtIntrinsic
110 #endif
111
112 #endif
113
114 #if defined(__WXGTK__)
115 #include <gtk/gtk.h>
116 #endif
117
118 /////////////////////////////////////////////////////////////////////////////
119 // wxSocket headers
120 /////////////////////////////////////////////////////////////////////////////
121 #include "wx/module.h"
122 #define WXSOCK_INTERNAL
123 #include "wx/sckaddr.h"
124 #include "wx/socket.h"
125
126 /////////////////////////////////////////////////////////////////////////////
127 // Some patch ///// BEGIN
128 /////////////////////////////////////////////////////////////////////////////
129 #ifdef __WINDOWS__
130 #define close closesocket
131 #define ioctl ioctlsocket
132 #ifdef errno
133 #undef errno
134 #endif
135 #define errno WSAGetLastError()
136 #ifdef EWOULDBLOCK
137 #undef EWOULDBLOCK
138 #endif
139 #define EWOULDBLOCK WSAEWOULDBLOCK
140 #define ETIMEDOUT WSAETIMEDOUT
141 #undef EINTR
142 #define EINTR WSAEINTR
143 #endif
144
145 #ifndef __WINDOWS__
146 #define INVALID_SOCKET -1
147 #endif
148
149 #ifdef __WXMOTIF__
150 #define wxAPP_CONTEXT ((XtAppContext)wxTheApp->GetAppContext())
151 #endif
152
153 #ifdef __WINDOWS__
154 // This is an MS TCP/IP routine and is not needed here. Some WinSock
155 // implementations (such as PC-NFS) will require you to include this
156 // or a similar routine (see appendix in WinSock doc or help file).
157
158 #if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ )
159 int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
160 {
161 int i = set->fd_count;
162
163 while (i--)
164 {
165 if (set->fd_array[i] == fd)
166 return 1;
167 }
168
169 return 0;
170 }
171 #endif
172 #endif
173
174 #if defined(__WINDOWS__)
175 #define PROCESS_EVENTS() wxYield()
176 #elif defined(__WXXT__) || defined(__WXMOTIF__)
177 #define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll)
178 #elif defined(__WXGTK__)
179 #define PROCESS_EVENTS() gtk_main_iteration()
180 #endif
181
182 /////////////////////////////////////////////////////////////////////////////
183 // Some patch ///// END
184 /////////////////////////////////////////////////////////////////////////////
185
186 #ifdef GetClassInfo
187 #undef GetClassInfo
188 #endif
189
190 // --------------------------------------------------------------
191 // Module
192 // --------------------------------------------------------------
193 class wxSocketModule: public wxModule
194 {
195 DECLARE_DYNAMIC_CLASS(wxSocketModule)
196 public:
197 wxSocketModule() {}
198 bool OnInit();
199 void OnExit();
200 };
201
202 // --------------------------------------------------------------
203 // ClassInfos
204 // --------------------------------------------------------------
205 #if !USE_SHARED_LIBRARY
206 IMPLEMENT_CLASS(wxSocketBase, wxObject)
207 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
208 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
209 IMPLEMENT_CLASS(wxSocketHandler, wxObject)
210 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
211 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
212 #endif
213
214 class wxSockWakeUp : public wxTimer
215 {
216 public:
217 int *my_id;
218 int n_val;
219 wxSocketBase *sock;
220
221 wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val)
222 {
223 my_id = id; n_val = new_val;
224 sock = _sock;
225 }
226 virtual void Notify()
227 {
228 *my_id = n_val;
229 if (sock) sock->Notify(FALSE);
230 }
231 };
232
233 /// Socket request
234 class SockRequest : public wxObject
235 {
236 public:
237 char *buffer;
238 size_t size, nbytes;
239 bool done;
240 int error;
241 wxSockWakeUp *auto_wakeup;
242 wxSocketBase::wxRequestNotify type;
243 };
244
245
246 /////////////////////////////////////////////////////////////////////////////
247 // Some internal define
248 /////////////////////////////////////////////////////////////////////////////
249
250 // --------------------------------------------------------------
251 // --------- wxSocketBase CONSTRUCTOR ---------------------------
252 // --------------------------------------------------------------
253 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
254 wxSocketBase::wxSockType _type) :
255 wxEvtHandler(),
256 m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
257 m_fd(INVALID_SOCKET), m_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1),
258 m_handler(0),
259 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
260 m_cbkon(FALSE),
261 m_unread(NULL), m_unrd_size(0),
262 m_processing(FALSE),
263 m_timeout(3600), m_wantbuf(0)
264 {
265 m_internal = new wxSockInternal;
266 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
267 m_internal->sock_inputid = 0;
268 m_internal->sock_outputid = 0;
269 m_internal->sock_exceptid = 0;
270 #endif
271 #ifdef __WINDOWS__
272 m_internal->my_msg = 0;
273 #endif
274 }
275
276 wxSocketBase::wxSocketBase() :
277 wxEvtHandler(),
278 m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
279 m_connecting(FALSE), m_fd(INVALID_SOCKET), m_waitflags(0),
280 m_cbk(0), m_cdata(0),
281 m_id(-1), m_handler(0),
282 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
283 m_cbkon(FALSE),
284 m_unread(NULL), m_unrd_size(0),
285 m_processing(FALSE),
286 m_timeout(3600), m_wantbuf(0)
287 {
288 m_internal = new wxSockInternal;
289 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
290 m_internal->sock_inputid = 0;
291 m_internal->sock_outputid = 0;
292 m_internal->sock_exceptid = 0;
293 #endif
294 #ifdef __WINDOWS__
295 m_internal->my_msg = 0;
296 #endif
297 }
298
299 // --------------------------------------------------------------
300 // wxSocketBase
301 // --------------------------------------------------------------
302
303 wxSocketBase::~wxSocketBase()
304 {
305 DestroyCallbacks();
306 Close();
307
308 if (m_unread)
309 free(m_unread);
310 if (m_handler)
311 {
312 #ifdef __WINDOWS__
313 if (m_internal->my_msg)
314 m_handler->DestroyMessage(m_internal->my_msg);
315 #endif
316 m_handler->UnRegister(this);
317 }
318 m_states.DeleteContents(TRUE);
319
320 delete m_internal;
321 }
322
323 bool wxSocketBase::Close()
324 {
325 if (m_fd != INVALID_SOCKET)
326 {
327 for (int i=0;i<3;i++)
328 {
329 wxNode *n, *node = req_list[i].First();
330
331 while (node)
332 {
333 SockRequest *req = (SockRequest *)node->Data();
334 req->done = TRUE;
335
336 n = node->Next();
337 delete node;
338 node = n;
339 }
340 }
341
342 DestroyCallbacks();
343 shutdown(m_fd, 2);
344 close(m_fd);
345 m_fd = INVALID_SOCKET;
346 m_connected = FALSE;
347 }
348
349 return TRUE;
350 }
351
352 // --------------------------------------------------------------
353 // wxSocketBase base IO function
354 // --------------------------------------------------------------
355
356 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
357 {
358 size_t count;
359
360 count = GetPushback(buffer, nbytes, FALSE);
361 nbytes -= count;
362 buffer += count;
363
364 // If we have got the whole needed buffer or if we don't want to
365 // wait then it returns immediately.
366 if (!nbytes || (m_lcount && !(m_flags & WAITALL)) )
367 return *this;
368
369 m_lcount = 0;
370 WantBuffer(buffer, nbytes, EVT_READ);
371 m_lcount += count;
372
373 return *this;
374 }
375
376 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
377 {
378 size_t count;
379
380 count = GetPushback(buffer, nbytes, TRUE);
381 if (nbytes-count == 0)
382 {
383 m_lcount = nbytes;
384 return *this;
385 }
386 buffer += count;
387 nbytes -= count;
388
389 m_lcount = 0;
390 WantBuffer(buffer, nbytes, EVT_PEEK);
391 m_lcount += count;
392
393 return *this;
394 }
395
396 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
397 {
398 WantBuffer((char *)buffer, nbytes, EVT_WRITE);
399 return *this;
400 }
401
402 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
403 {
404 SockMsg msg;
405 size_t len, len2, sig;
406
407 Read((char *)&msg, sizeof(msg));
408 if (m_lcount != sizeof(msg))
409 return *this;
410
411 sig = msg.sig[0] & 0xff;
412 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
413 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
414 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
415
416 if (sig != 0xfeeddead)
417 return *this;
418 len = msg.len[0] & 0xff;
419 len |= (size_t)(msg.len[1] & 0xff) << 8;
420 len |= (size_t)(msg.len[2] & 0xff) << 16;
421 len |= (size_t)(msg.len[3] & 0xff) << 24;
422 len2 = len;
423 if (len > nbytes)
424 len = nbytes;
425 else
426 len2 = 0;
427
428 if (Read(buffer, len).LastCount() != len)
429 return *this;
430 if (len2 && (Read(NULL, len2).LastCount() != len2))
431 return *this;
432 if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
433 return *this;
434
435 sig = msg.sig[0] & 0xff;
436 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
437 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
438 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
439 // ERROR
440 if (sig != 0xdeadfeed)
441 return *this;
442
443 return *this;
444 }
445
446 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
447 {
448 SockMsg msg;
449
450 // warning about 'cast truncates constant value'
451 #ifdef __VISUALC__
452 #pragma warning(disable: 4310)
453 #endif // __VISUALC__
454
455 msg.sig[0] = (char) 0xad;
456 msg.sig[1] = (char) 0xde;
457 msg.sig[2] = (char) 0xed;
458 msg.sig[3] = (char) 0xfe;
459
460 msg.len[0] = (char) nbytes & 0xff;
461 msg.len[1] = (char) (nbytes >> 8) & 0xff;
462 msg.len[2] = (char) (nbytes >> 16) & 0xff;
463 msg.len[3] = (char) (nbytes >> 24) & 0xff;
464
465 if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
466 return *this;
467 if (Write(buffer, nbytes).LastCount() < nbytes)
468 return *this;
469
470 msg.sig[0] = (char) 0xed;
471 msg.sig[1] = (char) 0xfe;
472 msg.sig[2] = (char) 0xad;
473 msg.sig[3] = (char) 0xde;
474 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
475 Write((char *)&msg, sizeof(msg));
476
477 return *this;
478
479 #ifdef __VISUALC__
480 #pragma warning(default: 4310)
481 #endif // __VISUALC__
482 }
483
484 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
485 {
486 CreatePushbackAfter(buffer, nbytes);
487 return *this;
488 }
489
490 bool wxSocketBase::IsData() const
491 {
492 struct timeval tv;
493 fd_set sock_set;
494
495 if (m_fd < 0)
496 return FALSE;
497 if (m_unrd_size > 0)
498 return TRUE;
499
500 tv.tv_sec = 0;
501 tv.tv_usec = 0;
502 FD_ZERO(&sock_set);
503 FD_SET(m_fd, &sock_set);
504 select(FD_SETSIZE, &sock_set, NULL, NULL, &tv);
505 return (FD_ISSET(m_fd, &sock_set) != 0);
506 }
507
508 // ---------------------------------------------------------------------
509 // --------- wxSocketBase Discard(): deletes all byte in the input queue
510 // ---------------------------------------------------------------------
511 void wxSocketBase::Discard()
512 {
513 #define MAX_BUFSIZE (10*1024)
514 char *my_data = new char[MAX_BUFSIZE];
515 size_t recv_size = MAX_BUFSIZE;
516
517 SaveState();
518 SetFlags((wxSockFlags)(NOWAIT | SPEED));
519
520 while (recv_size == MAX_BUFSIZE)
521 {
522 recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
523 }
524
525 RestoreState();
526 delete [] my_data;
527
528 #undef MAX_BUFSIZE
529 }
530
531 // If what? Who seems to need unsigned int?
532 // BTW uint isn't even defined on wxMSW for VC++ for some reason. Even if it
533 // were, getpeername/getsockname don't take unsigned int*, they take int*.
534 //
535 // Under glibc 2.0.7, socketbits.h declares socklen_t to be unsigned int
536 // and it uses *socklen_t as the 3rd parameter. Robert.
537
538 // JACS - How can we detect this?
539 // Meanwhile, if your compiler complains about socklen_t,
540 // switch lines below.
541
542 #if wxHAVE_GLIBC2
543 # define wxSOCKET_INT socklen_t
544 #else
545 # define wxSOCKET_INT int
546 #endif
547
548 // --------------------------------------------------------------
549 // wxSocketBase socket info functions
550 // --------------------------------------------------------------
551
552 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
553 {
554 struct sockaddr my_addr;
555 wxSOCKET_INT len_addr = sizeof(my_addr);
556
557 if (m_fd < 0)
558 return FALSE;
559
560 if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0)
561 return FALSE;
562
563 addr_man.Disassemble(&my_addr, len_addr);
564 return TRUE;
565 }
566
567 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
568 {
569 struct sockaddr my_addr;
570 wxSOCKET_INT len_addr = sizeof(my_addr);
571
572 if (m_fd < 0)
573 return FALSE;
574
575 if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0)
576
577 return FALSE;
578
579 addr_man.Disassemble(&my_addr, len_addr);
580 return TRUE;
581 }
582
583 // --------------------------------------------------------------
584 // wxSocketBase wait functions
585 // --------------------------------------------------------------
586
587 void wxSocketBase::SaveState()
588 {
589 wxSockState *state = new wxSockState;
590
591 state->cbk_on = m_cbkon;
592 state->cbk_set= m_neededreq;
593 state->cbk = m_cbk;
594 state->cdata = m_cdata;
595 state->flags = m_flags;
596 state->notif = m_notifyme;
597
598 m_states.Append(state);
599 }
600
601 void wxSocketBase::RestoreState()
602 {
603 wxNode *node;
604
605 node = m_states.Last();
606 if (!node)
607 return;
608
609 wxSockState *state = (wxSockState *)node->Data();
610
611 SetFlags(state->flags);
612 m_neededreq = state->cbk_set;
613 m_cbk = state->cbk;
614 m_cdata = state->cdata;
615 m_notifyme = state->notif;
616 if (state->cbk_on)
617 SetupCallbacks();
618 else
619 DestroyCallbacks();
620
621 delete node;
622 delete state;
623 }
624
625 // --------------------------------------------------------------
626 // --------- wxSocketBase wait functions ------------------------
627 // --------------------------------------------------------------
628
629 bool wxSocketBase::_Wait(long seconds, long microseconds, int type)
630 {
631 if ((!m_connected && !m_connecting) || m_fd < 0)
632 return FALSE;
633
634 wxSockWakeUp wakeup(this, &m_waitflags, 0);
635
636 SaveState();
637 SetNotify((wxRequestNotify)type);
638 SetupCallbacks();
639
640 if (seconds != -1)
641 wakeup.Start((int)(seconds*1000 + (microseconds / 1000)), TRUE);
642
643 m_waitflags = 0x80 | type;
644 while (m_waitflags & 0x80)
645 PROCESS_EVENTS();
646
647 RestoreState();
648
649 if (m_waitflags & 0x40)
650 {
651 m_waitflags = 0;
652 return TRUE;
653 }
654 m_waitflags = 0;
655
656 return FALSE;
657 }
658
659 bool wxSocketBase::Wait(long seconds, long microseconds)
660 {
661 return _Wait(seconds, microseconds, REQ_ACCEPT | REQ_CONNECT |
662 REQ_READ | REQ_WRITE | REQ_LOST);
663 }
664
665 bool wxSocketBase::WaitForRead(long seconds, long microseconds)
666 {
667 return _Wait(seconds, microseconds, REQ_READ | REQ_LOST);
668 }
669
670 bool wxSocketBase::WaitForWrite(long seconds, long microseconds)
671 {
672 return _Wait(seconds, microseconds, REQ_WRITE);
673 }
674
675 bool wxSocketBase::WaitForLost(long seconds, long microseconds)
676 {
677 return _Wait(seconds, microseconds, REQ_LOST);
678 }
679
680 // --------------------------------------------------------------
681 // --------- wxSocketBase callback management -------------------
682 // --------------------------------------------------------------
683
684 #if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
685 #if defined(__WXMOTIF__) || defined(__WXXT__)
686 static void wx_socket_read(XtPointer client, int *fid,
687 XtInputId *WXUNUSED(id))
688 #define fd *fid
689 #else
690 static void wx_socket_read(gpointer client, gint fd,
691 GdkInputCondition WXUNUSED(cond))
692 #define fd fd
693 #endif
694 {
695 wxSocketBase *sock = (wxSocketBase *)client;
696 char c;
697 int i;
698
699 i = recv(fd, &c, 1, MSG_PEEK);
700
701 if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT))
702 {
703 sock->OnRequest(wxSocketBase::EVT_ACCEPT);
704 return;
705 }
706
707 if (i != 0)
708 {
709 if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
710 {
711 return;
712 }
713
714 sock->OnRequest(wxSocketBase::EVT_READ);
715 }
716 else
717 {
718 if (!(sock->NeededReq() & wxSocketBase::REQ_LOST))
719 {
720 sock->Close();
721 return;
722 }
723
724 sock->OnRequest(wxSocketBase::EVT_LOST);
725 }
726 }
727 #undef fd
728
729 #if defined(__WXMOTIF__) || defined(__WXXT__)
730 static void wx_socket_write(XtPointer client, int *WXUNUSED(fid),
731 XtInputId *WXUNUSED(id))
732 #else
733 static void wx_socket_write(gpointer client, gint WXUNUSED(fd),
734 GdkInputCondition WXUNUSED(cond))
735 #endif
736 {
737 wxSocketBase *sock = (wxSocketBase *)client;
738
739 if (!sock->IsConnected())
740 sock->OnRequest(wxSocketBase::EVT_CONNECT);
741 else
742 sock->OnRequest(wxSocketBase::EVT_WRITE);
743 }
744 #endif
745
746 #ifdef wx_xview
747 Notify_value wx_sock_read_xview (Notify_client client, int fd)
748 {
749 wxSocketBase *sock = (wxSocketBase *)client;
750 char c;
751 int i;
752
753 i = recv(fd, &c, 1, MSG_PEEK);
754
755 if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT))
756 {
757 sock->OnRequest(wxSocketBase::EVT_ACCEPT);
758 return;
759 }
760
761 /* Bytes arrived */
762 if (i != 0)
763 {
764 if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
765 return (Notify_value) FALSE;
766
767 sock->OnRequest(wxSocketBase::EVT_READ);
768 }
769 else
770 {
771 if (!(sock->NeededReq() & wxSocketBase::REQ_LOST))
772 return;
773
774 sock->OnRequest(wxSocketBase::EVT_LOST);
775 }
776
777 return (Notify_value) FALSE;
778 }
779
780 Notify_value wx_sock_write_xview (Notify_client client, int fd)
781 {
782 wxSocketBase *sock = (wxSocketBase *)client;
783
784 if (!sock->IsConnected())
785 sock->OnRequest(wxSocketBase::EVT_CONNECT);
786 else
787 sock->OnRequest(wxSocketBase::EVT_WRITE);
788
789 return (Notify_value) TRUE;
790 }
791 #endif
792
793 wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
794 {
795 switch (evt)
796 {
797 case EVT_READ:
798 return REQ_READ;
799 case EVT_PEEK:
800 return REQ_PEEK;
801 case EVT_WRITE:
802 return REQ_WRITE;
803 case EVT_LOST:
804 return REQ_LOST;
805 case EVT_ACCEPT:
806 return REQ_ACCEPT;
807 case EVT_CONNECT:
808 return REQ_CONNECT;
809 }
810 return 0;
811 }
812
813 void wxSocketBase::SetFlags(wxSockFlags _flags)
814 {
815 m_flags = _flags;
816 if (_flags & SPEED)
817 {
818 unsigned long flag = 0;
819 ioctl(m_fd, FIONBIO, &flag);
820
821 // SPEED and WAITALL are antagonists.
822 m_flags = (wxSockFlags)(m_flags & ~WAITALL);
823
824 Notify(FALSE);
825 }
826 else
827 {
828 unsigned long flag = 1;
829 ioctl(m_fd, FIONBIO, &flag);
830 }
831 }
832
833 void wxSocketBase::SetNotify(wxRequestNotify flags)
834 {
835 wxRequestNotify old_needed_req = m_neededreq;
836 if (flags & REQ_ACCEPT)
837 {
838 /* Check if server */
839 if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer))))
840 flags &= ~REQ_ACCEPT;
841 }
842 m_neededreq = flags;
843
844 /*
845 if (m_cbkon && old_needed_req != flags) seems to be wrong, Robert Roebling
846 SetupCallbacks();
847 */
848
849 if (old_needed_req != flags)
850 SetupCallbacks();
851 }
852
853 void wxSocketBase::SetupCallbacks()
854 {
855 if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED))
856 return;
857
858 #if defined(__WXMOTIF__) || defined(__WXXT__)
859 if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST))
860 {
861 if (m_internal->sock_inputid <= 0)
862 {
863 m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
864 (XtPointer *) XtInputReadMask,
865 (XtInputCallbackProc) wx_socket_read,
866 (XtPointer) this);
867 }
868 }
869 else
870 {
871 if (m_internal->sock_inputid > 0)
872 {
873 XtRemoveInput(m_internal->sock_inputid);
874 m_internal->sock_inputid = 0;
875 }
876 }
877
878 if (m_neededreq & (REQ_CONNECT | REQ_WRITE))
879 {
880 if (m_internal->sock_outputid <= 0)
881 {
882 m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
883 (XtPointer *) XtInputWriteMask,
884 (XtInputCallbackProc) wx_socket_write,
885 (XtPointer) this);
886 }
887 }
888 else
889 {
890 if (m_internal->sock_outputid > 0)
891 {
892 XtRemoveInput(m_internal->sock_outputid);
893 m_internal->sock_outputid = 0;
894 }
895 }
896 #endif
897
898
899 #ifdef __WXGTK__
900 if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST))
901 {
902 if (m_internal->sock_inputid <= 0)
903 {
904 m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ,
905 wx_socket_read, (gpointer)this);
906 }
907 }
908 else
909 {
910 if (m_internal->sock_inputid > 0)
911 {
912 /*
913 gdk_input_remove(m_internal->sock_inputid);
914 m_internal->sock_inputid = 0;
915 */
916 }
917 }
918
919 if (m_neededreq & (REQ_CONNECT | REQ_WRITE))
920 {
921 if (m_internal->sock_outputid <= 0)
922 {
923 m_internal->sock_outputid = gdk_input_add(m_fd, GDK_INPUT_WRITE,
924 wx_socket_write, (gpointer)this);
925 }
926 }
927 else
928 {
929 if (m_internal->sock_outputid > 0)
930 {
931 /*
932 gdk_input_remove(m_internal->sock_outputid);
933 m_internal->sock_outputid = 0;
934 */
935 }
936 }
937 #endif
938
939
940 #ifdef __WXMSW__
941 WORD mask = 0;
942
943 if (m_neededreq & REQ_READ)
944 mask |= FD_READ;
945 if (m_neededreq & REQ_WRITE)
946 mask |= FD_WRITE;
947 if (m_neededreq & REQ_LOST)
948 mask |= FD_CLOSE;
949 if (m_neededreq & REQ_ACCEPT)
950 mask |= FD_ACCEPT;
951 if (m_neededreq & REQ_CONNECT)
952 mask |= FD_CONNECT;
953
954 if (!m_internal->my_msg)
955 m_internal->my_msg = m_handler->NewMessage(this);
956 WSAAsyncSelect(m_fd, m_handler->GetHWND(), m_internal->my_msg, mask);
957 #endif
958 #ifdef __WXMAC__
959 short mask = 0;
960
961 if (m_neededreq & REQ_READ)
962 mask |= FD_READ;
963 if (m_neededreq & REQ_WRITE)
964 mask |= FD_WRITE;
965 if (m_neededreq & REQ_LOST)
966 mask |= FD_CLOSE;
967 if (m_neededreq & REQ_ACCEPT)
968 mask |= FD_ACCEPT;
969 if (m_neededreq & REQ_CONNECT)
970 mask |= FD_CONNECT;
971
972 GUSISetReference( m_fd ,mask, this ) ;
973 unsigned long flag = 1;
974 ioctl(m_fd, FIONBIO, &flag);
975 #endif
976 m_cbkon = TRUE;
977 m_processing = FALSE;
978 }
979
980 void wxSocketBase::DestroyCallbacks()
981 {
982 if (!m_cbkon || !m_handler)
983 return;
984
985 m_cbkon = FALSE;
986 m_processing = FALSE;
987 #if defined(__WXMOTIF__) || defined(__WXXT__)
988 if (m_internal->sock_inputid > 0)
989 XtRemoveInput(m_internal->sock_inputid);
990 m_internal->sock_inputid = 0;
991 if (m_internal->sock_outputid > 0)
992 XtRemoveInput(m_internal->sock_outputid);
993 m_internal->sock_outputid = 0;
994 #endif
995 #ifdef __WXGTK__
996 if (m_internal->sock_inputid > 0)
997 gdk_input_remove(m_internal->sock_inputid);
998 m_internal->sock_inputid = 0;
999 if (m_internal->sock_outputid > 0)
1000 gdk_input_remove(m_internal->sock_outputid);
1001 m_internal->sock_outputid = 0;
1002 #endif
1003 #ifdef __WINDOWS__
1004 WSAAsyncSelect(m_fd, m_handler->GetHWND(), 0, 0);
1005 #endif
1006 #ifdef __WXMAC__
1007 GUSISetReference( m_fd , 0 , 0 ) ;
1008 int bottom = wxMacNetEventsBottom ;
1009 while ( wxMacNetEventsTop != bottom )
1010 {
1011 // set all events that reference this socket to nil
1012 if ( wxMacNetEventsReferences[bottom] == (void*) this )
1013 wxMacNetEventsReferences[bottom] = NULL ;
1014 bottom++ ;
1015 if ( bottom == kwxMacNetEventsMax )
1016 bottom = 0 ;
1017 }
1018 SetFlags( m_flags ) ;
1019 #endif
1020 }
1021
1022 void wxSocketBase::Notify(bool notify)
1023 {
1024 if (m_notifyme == notify)
1025 return;
1026 if (notify)
1027 SetupCallbacks();
1028 else
1029 DestroyCallbacks();
1030 m_notifyme = notify;
1031 }
1032
1033 void wxSocketBase::OnRequest(wxRequestEvent req_evt)
1034 {
1035 wxRequestNotify req_notif = EventToNotify(req_evt);
1036
1037 // Mask the current event
1038 SetNotify(m_neededreq & ~req_notif);
1039
1040 if (req_evt <= EVT_WRITE && DoRequests(req_evt))
1041 return;
1042
1043 if (m_waitflags & 0xF0)
1044 {
1045 // Wake up
1046 if ((m_waitflags & 0x0F) == req_evt)
1047 {
1048 m_waitflags = 0x80;
1049 #ifndef __WXGTK__
1050 DestroyCallbacks();
1051 #endif
1052 }
1053 return;
1054 }
1055
1056 if (req_evt == EVT_LOST)
1057 {
1058 m_connected = FALSE;
1059 Close();
1060 }
1061 if (m_notifyme)
1062 OldOnNotify(req_evt);
1063
1064 // Unmask
1065 SetNotify(m_neededreq | req_notif);
1066 }
1067
1068 wxSocketEvent::wxSocketEvent(int id)
1069 : wxEvent(id)
1070 {
1071 wxEventType type = (wxEventType)wxEVT_SOCKET;
1072
1073 SetEventType(type);
1074 }
1075
1076 void wxSocketBase::OldOnNotify(wxRequestEvent evt)
1077 {
1078 wxSocketEvent event(m_id);
1079
1080 event.SetEventObject(this);
1081 event.m_skevt = evt;
1082 ProcessEvent(event);
1083
1084 if (m_cbk)
1085 m_cbk(*this, evt, m_cdata);
1086 }
1087
1088 // --------------------------------------------------------------
1089 // --------- wxSocketBase functions [Callback, CallbackData] ----
1090 // --------------------------------------------------------------
1091
1092 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk)
1093 {
1094 wxSockCbk old_cbk = m_cbk;
1095
1096 m_cbk = _cbk;
1097 return old_cbk;
1098 }
1099
1100 char *wxSocketBase::CallbackData(char *cdata_)
1101 {
1102 char *old_cdata = m_cdata;
1103
1104 m_cdata = cdata_;
1105 return old_cdata;
1106 }
1107
1108 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
1109 {
1110 SetNextHandler(&h_evt);
1111 m_id = id;
1112 }
1113
1114 // --------------------------------------------------------------
1115 // --------- wxSocketBase pushback library ----------------------
1116 // --------------------------------------------------------------
1117
1118 void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
1119 {
1120 char *curr_pos;
1121
1122 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
1123 curr_pos = m_unread + m_unrd_size;
1124
1125 memcpy(curr_pos, buffer, size);
1126 m_unrd_size += size;
1127 }
1128
1129 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
1130 {
1131 char *curr_pos, *new_buf;
1132
1133 new_buf = (char *) malloc(m_unrd_size+size);
1134 curr_pos = new_buf + size;
1135
1136 memcpy(new_buf, buffer, size);
1137 if (m_unrd_size != 0) {
1138 memcpy(curr_pos, m_unread, m_unrd_size);
1139 free(m_unread);
1140 }
1141 m_unread = new_buf;
1142 m_unrd_size += size;
1143 }
1144
1145 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
1146 {
1147 if (!m_unrd_size)
1148 return 0;
1149
1150 if (size > m_unrd_size)
1151 size = m_unrd_size;
1152 memcpy(buffer, m_unread, size);
1153
1154 if (!peek) {
1155 m_unrd_size -= size;
1156 if (m_unrd_size == 0) {
1157 free(m_unread);
1158 m_unread = NULL;
1159 }
1160 }
1161
1162 return size;
1163 }
1164
1165 // --------------------------------------------------------------
1166 // --------- wxSocketBase "multi-thread" core -------------------
1167 // --------------------------------------------------------------
1168
1169 bool wxSocketBase::DoRequests(wxRequestEvent req_flag)
1170 {
1171 wxNode *node = req_list[req_flag].First();
1172 size_t len;
1173 int ret;
1174
1175 if (!node)
1176 return FALSE;
1177
1178 SockRequest *req = (SockRequest *)node->Data();
1179
1180 delete node;
1181
1182 switch (req->type)
1183 {
1184 case EVT_READ:
1185 case EVT_PEEK:
1186 ret = recv(m_fd, req->buffer, req->size,
1187 (req->type == EVT_PEEK) ? MSG_PEEK : 0);
1188 if (ret < 0)
1189 {
1190 req->error = errno;
1191 req->done = TRUE;
1192 break;
1193 }
1194 len = ret;
1195 if ((len < req->size) && (m_flags & WAITALL))
1196 {
1197 req->size -= len;
1198 req->nbytes += len;
1199 req->buffer += len;
1200 req->auto_wakeup->Start(m_timeout*1000, TRUE);
1201 req_list[req_flag].Insert(req);
1202 break;
1203 }
1204 req->done = TRUE;
1205 req->nbytes += len;
1206 #ifndef __WXGTK__
1207 DestroyCallbacks();
1208 #endif
1209 break;
1210 case EVT_WRITE:
1211 ret = send(m_fd, req->buffer, req->size, 0);
1212 if (ret < 0)
1213 {
1214 req->error = errno;
1215 req->done = TRUE;
1216 break;
1217 }
1218 len = ret;
1219 if ((len < req->size) && (m_flags & WAITALL))
1220 {
1221 req->size -= len;
1222 req->nbytes += len;
1223 req->buffer += len;
1224 req->auto_wakeup->Start(m_timeout*1000, TRUE);
1225 req_list[req_flag].Insert(req);
1226 break;
1227 }
1228 req->done = TRUE;
1229 req->nbytes += len;
1230 #ifndef __WXGTK__
1231 DestroyCallbacks();
1232 #endif
1233 break;
1234 default:
1235 return FALSE;
1236 }
1237 return TRUE;
1238 }
1239
1240 void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes,
1241 wxRequestEvent evt)
1242 {
1243 int ret = 0;
1244
1245 switch (evt)
1246 {
1247 case EVT_PEEK:
1248 case EVT_READ:
1249 ret = recv(m_fd, buffer, nbytes,
1250 (evt == EVT_PEEK) ? MSG_PEEK : 0);
1251 break;
1252 case EVT_WRITE:
1253 ret = send(m_fd, buffer, nbytes, 0);
1254 break;
1255 }
1256 if (ret < 0)
1257 {
1258 m_lcount = 0;
1259 m_error = errno;
1260 }
1261 else
1262 {
1263 m_lcount = ret;
1264 m_error = 0;
1265 }
1266 }
1267
1268 void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
1269 wxRequestEvent evt)
1270 {
1271 bool buf_timed_out;
1272
1273 if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
1274 return;
1275
1276 if (m_flags & SPEED)
1277 {
1278 WantSpeedBuffer(buffer, nbytes, evt);
1279 return;
1280 }
1281
1282 SockRequest *buf = new SockRequest;
1283 wxSockWakeUp s_wake(NULL, (int *)&buf_timed_out, (int)TRUE);
1284
1285 m_wantbuf++;
1286 req_list[evt].Append(buf);
1287
1288 SaveState();
1289 SetNotify(REQ_LOST | EventToNotify(evt));
1290 SetupCallbacks();
1291 buf->buffer = buffer;
1292 buf->size = nbytes;
1293 buf->done = FALSE;
1294 buf->type = evt;
1295 buf->nbytes = 0;
1296 buf->auto_wakeup = &s_wake;
1297 buf->error = 0;
1298 buf_timed_out = FALSE;
1299
1300 s_wake.Start(m_timeout*1000, TRUE);
1301 if (m_flags & NOWAIT)
1302 {
1303 DoRequests(evt);
1304 }
1305 else
1306 {
1307 while (!buf->done && !buf_timed_out)
1308 PROCESS_EVENTS();
1309 }
1310 m_wantbuf--;
1311 m_lcount = buf->nbytes;
1312 if (buf_timed_out)
1313 m_error = ETIMEDOUT;
1314 else
1315 m_error = buf->error;
1316
1317 delete buf;
1318 RestoreState();
1319 }
1320
1321 // --------------------------------------------------------------
1322 // wxSocketServer
1323 // --------------------------------------------------------------
1324
1325 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1326 wxSockFlags flags) :
1327 wxSocketBase(flags, SOCK_SERVER)
1328 {
1329 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
1330
1331 if (m_fd == INVALID_SOCKET)
1332 return;
1333
1334 int flag = 1;
1335 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
1336
1337 struct sockaddr *myaddr;
1338 size_t len;
1339
1340 addr_man.Build(myaddr, len);
1341 if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0)
1342 return;
1343
1344 if (listen(m_fd, 5) < 0) {
1345 m_fd = INVALID_SOCKET;
1346 return;
1347 }
1348 }
1349
1350 // --------------------------------------------------------------
1351 // wxSocketServer Accept
1352 // --------------------------------------------------------------
1353
1354 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
1355 {
1356 int fd2;
1357
1358 if ((fd2 = accept(m_fd, 0, 0)) < 0)
1359 return FALSE;
1360
1361 struct linger linger;
1362 linger.l_onoff = 0;
1363 linger.l_linger = 1;
1364
1365 setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
1366
1367 int flag = 0;
1368 setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
1369
1370 if (!(sock.m_flags & SPEED))
1371 {
1372 unsigned long flag2 = 1;
1373 ioctl(fd2, FIONBIO, &flag2);
1374 }
1375
1376 sock.m_type = SOCK_INTERNAL;
1377 sock.m_fd = fd2;
1378 sock.m_connected = TRUE;
1379
1380 return TRUE;
1381 }
1382
1383 wxSocketBase *wxSocketServer::Accept()
1384 {
1385 wxSocketBase* sock = new wxSocketBase();
1386
1387 sock->SetFlags((wxSockFlags)m_flags);
1388
1389 if (!AcceptWith(*sock))
1390 return NULL;
1391
1392 if (m_handler)
1393 m_handler->Register(sock);
1394
1395 return sock;
1396 }
1397
1398 // --------------------------------------------------------------
1399 // wxSocketServer callbacks
1400 // --------------------------------------------------------------
1401
1402 void wxSocketServer::OnRequest(wxRequestEvent evt)
1403 {
1404 if (evt == EVT_ACCEPT)
1405 {
1406 OldOnNotify(EVT_ACCEPT);
1407 }
1408 }
1409
1410 // --------------------------------------------------------------
1411 // wxSocketClient
1412 // --------------------------------------------------------------
1413
1414 // --------- wxSocketClient CONSTRUCTOR -------------------------
1415 // --------------------------------------------------------------
1416 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
1417 wxSocketBase(_flags, SOCK_CLIENT)
1418 {
1419 }
1420
1421 // --------------------------------------------------------------
1422 // --------- wxSocketClient DESTRUCTOR --------------------------
1423 // --------------------------------------------------------------
1424 wxSocketClient::~wxSocketClient()
1425 {
1426 }
1427
1428 // --------------------------------------------------------------
1429 // --------- wxSocketClient Connect functions -------------------
1430 // --------------------------------------------------------------
1431 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
1432 {
1433 struct linger linger;
1434
1435 if (IsConnected())
1436 Close();
1437
1438 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
1439
1440 if (m_fd < 0)
1441 return FALSE;
1442
1443 m_connected = FALSE;
1444
1445 linger.l_onoff = 1;
1446 linger.l_linger = 5;
1447 setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
1448
1449 // Stay in touch with the state of things...
1450
1451 unsigned long flag = 1;
1452 setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
1453
1454 // Disable the nagle algorithm, which delays sends till the
1455 // buffer is full (or a certain time period has passed?)...
1456
1457 #if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY))
1458 flag = 1;
1459 setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
1460 #endif
1461
1462 struct sockaddr *remote;
1463 size_t len;
1464
1465 addr_man.Build(remote, len);
1466
1467 if (connect(m_fd, remote, len) != 0)
1468 return FALSE;
1469
1470 if (!(m_flags & SPEED))
1471 {
1472 flag = 1;
1473 ioctl(m_fd, FIONBIO, &flag);
1474 }
1475
1476 Notify(TRUE);
1477
1478 m_connected = TRUE;
1479 return TRUE;
1480 }
1481
1482 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
1483 {
1484 int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST);
1485
1486 if (ret)
1487 m_connected = TRUE;
1488
1489 return m_connected;
1490 }
1491
1492 void wxSocketClient::OnRequest(wxRequestEvent evt)
1493 {
1494 if (evt == EVT_CONNECT)
1495 {
1496 if (m_connected)
1497 {
1498 #ifndef __WXGTK__
1499 SetNotify(m_neededreq & ~REQ_CONNECT);
1500 #endif
1501 return;
1502 }
1503 m_waitflags = 0x40;
1504 m_connected = TRUE;
1505 OldOnNotify(EVT_CONNECT);
1506 #ifndef __WXGTK__
1507 DestroyCallbacks();
1508 #endif
1509 return;
1510 }
1511 wxSocketBase::OnRequest(evt);
1512 }
1513
1514 /////////////////////////////////////////////////////////////////
1515 // wxSocketHandler ///////////////////////////////////////////////
1516 /////////////////////////////////////////////////////////////////
1517
1518 wxSocketHandler *wxSocketHandler::master = NULL;
1519 #if defined(__WINDOWS__)
1520 static int win_initialized = 0;
1521 #endif
1522
1523 // --------------------------------------------------------------
1524 // --------- wxSocketHandler CONSTRUCTOR ------------------------
1525 // --------------------------------------------------------------
1526 #ifdef __WXMAC__
1527
1528 extern "C" int updatestatus(int s) ;
1529
1530 void wxMacSocketOnRequestProc( void *refcon , short event )
1531 {
1532 if ( refcon )
1533 {
1534 wxSocketBase *sock = (wxSocketBase *) refcon ;
1535
1536 wxSocketBase::wxRequestEvent sk_req;
1537
1538 int canRead ;
1539 int canWrite ;
1540 int exception ;
1541
1542 switch (event) {
1543 case FD_READ:
1544 sk_req = wxSocketBase::EVT_READ;
1545 sock->OnRequest(sk_req);
1546 break;
1547 case FD_WRITE:
1548 sk_req = wxSocketBase::EVT_WRITE;
1549 sock->OnRequest(sk_req);
1550 break;
1551 case FD_CLOSE:
1552 sk_req = wxSocketBase::EVT_LOST;
1553 sock->OnRequest(sk_req);
1554 break;
1555 case FD_ACCEPT:
1556 sk_req = wxSocketBase::EVT_ACCEPT;
1557 sock->OnRequest(sk_req);
1558 break;
1559 case FD_CONNECT:
1560 sk_req = wxSocketBase::EVT_CONNECT;
1561 sock->OnRequest(sk_req);
1562 break;
1563 case FD_READY :
1564 break ;
1565 }
1566 updatestatus ( sock->m_fd ) ;
1567 }
1568 }
1569
1570 void wxMacSocketHandlerProc( void *refcon , short event )
1571 {
1572 wxMacNetEventsReferences[wxMacNetEventsTop] = refcon ;
1573 wxMacNetEventsEvents[wxMacNetEventsTop] = event ;
1574
1575 // clumsy construct in order to never have a incorrect wxMacNetEventsTop (above limits)
1576
1577 if ( wxMacNetEventsTop + 1 == kwxMacNetEventsMax )
1578 wxMacNetEventsTop = 0 ;
1579 else
1580 wxMacNetEventsTop++ ;
1581 }
1582
1583 #endif
1584 #ifdef __WINDOWS__
1585
1586 extern char wxPanelClassName[];
1587
1588 LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message,
1589 WPARAM wParam, LPARAM lParam)
1590 {
1591 if(message==WM_DESTROY)
1592 {
1593 ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc);
1594 return DefWindowProc(hWnd, message, wParam, lParam);
1595 }
1596 wxSocketHandler *h_sock = (wxSocketHandler *)GetWindowLong(hWnd, GWL_USERDATA);
1597 wxNode *node = h_sock->smsg_list->Find(message);
1598 wxSocketBase *sock;
1599 wxSocketBase::wxRequestEvent sk_req;
1600 UINT event = WSAGETSELECTEVENT(lParam);
1601
1602 if (!node)
1603 return DefWindowProc(hWnd, message, wParam, lParam);
1604
1605 sock = (wxSocketBase *)node->Data();
1606
1607 switch (event) {
1608 case FD_READ:
1609 sk_req = wxSocketBase::EVT_READ;
1610 break;
1611 case FD_WRITE:
1612 sk_req = wxSocketBase::EVT_WRITE;
1613 break;
1614 case FD_CLOSE:
1615 sk_req = wxSocketBase::EVT_LOST;
1616 break;
1617 case FD_ACCEPT:
1618 sk_req = wxSocketBase::EVT_ACCEPT;
1619 break;
1620 case FD_CONNECT:
1621 sk_req = wxSocketBase::EVT_CONNECT;
1622 break;
1623
1624 default:
1625 wxFAIL_MSG("invalid socket event");
1626 return (LRESULT)0;
1627 }
1628
1629 sock->OnRequest(sk_req);
1630
1631 return (LRESULT)0;
1632 }
1633
1634 FARPROC wxSocketSubClassProc = NULL;
1635
1636 #endif
1637
1638 wxSocketHandler::wxSocketHandler()
1639 {
1640 #if defined(__WINDOWS__)
1641 if (!win_initialized)
1642 {
1643 WSADATA wsaData;
1644
1645 WSAStartup((1 << 8) | 1, &wsaData);
1646 win_initialized = 1;
1647 }
1648 internal = new wxSockHandlerInternal;
1649 internal->sockWin = ::CreateWindow(wxPanelClassName, NULL, 0,
1650 0, 0, 0, 0, NULL, (HMENU) NULL,
1651 wxhInstance, 0);
1652
1653 // Subclass the window
1654 if (!wxSocketSubClassProc)
1655 wxSocketSubClassProc = MakeProcInstance((FARPROC) wxSocketHandlerWndProc, wxhInstance);
1656 ::SetWindowLong(internal->sockWin, GWL_WNDPROC, (LONG) wxSocketSubClassProc);
1657 ::SetWindowLong(internal->sockWin, GWL_USERDATA, (LONG) this);
1658
1659 internal->firstAvailableMsg = 5000;
1660 smsg_list = new wxList(wxKEY_INTEGER);
1661 #endif
1662
1663 socks = new wxList;
1664
1665 #ifndef __WINDOWS__
1666 signal(SIGPIPE, SIG_IGN);
1667 #endif
1668 }
1669
1670 // --------------------------------------------------------------
1671 // --------- wxSocketHandler DESTRUCTOR -------------------------
1672 // --------------------------------------------------------------
1673 wxSocketHandler::~wxSocketHandler()
1674 {
1675 wxNode *next_node, *node = socks->First();
1676
1677 while (node)
1678 {
1679 wxSocketBase* sock = (wxSocketBase*)node->Data();
1680
1681 delete sock;
1682 next_node = node->Next();
1683 delete node;
1684 node = next_node;
1685 }
1686
1687 delete socks;
1688
1689 #ifdef __WINDOWS__
1690 delete smsg_list;
1691
1692 ::DestroyWindow(internal->sockWin);
1693 WSACleanup();
1694 win_initialized = 0;
1695
1696 delete internal;
1697 #endif
1698 }
1699
1700 // --------------------------------------------------------------
1701 // --------- wxSocketHandler registering functions --------------
1702 // --------------------------------------------------------------
1703
1704 void wxSocketHandler::Register(wxSocketBase* sock)
1705 {
1706 wxNode *node;
1707
1708 for (node = socks->First(); node != NULL; node = node->Next())
1709 {
1710 wxSocketBase* s = (wxSocketBase*)node->Data();
1711
1712 if (s == sock)
1713 return;
1714 }
1715
1716 if (sock)
1717 {
1718 socks->Append(sock);
1719 sock->SetHandler(this);
1720 sock->SetupCallbacks();
1721 }
1722 }
1723
1724 void wxSocketHandler::UnRegister(wxSocketBase* sock)
1725 {
1726 wxNode *node;
1727
1728 for (node = socks->First(); node; node = node->Next())
1729 {
1730 wxSocketBase* s = (wxSocketBase*)node->Data();
1731
1732 if (s == sock)
1733 {
1734 delete node;
1735 sock->DestroyCallbacks();
1736 sock->SetHandler(NULL);
1737 return;
1738 }
1739 }
1740 }
1741
1742 unsigned long wxSocketHandler::Count() const
1743 {
1744 return socks->Number();
1745 }
1746
1747 // --------------------------------------------------------------
1748 // --------- wxSocketHandler "big" wait functions ---------------
1749 // --------------------------------------------------------------
1750 void handler_cbk(wxSocketBase& sock,
1751 wxSocketBase::wxRequestEvent WXUNUSED(flags),
1752 char *cdata)
1753 {
1754 int *a_wait = (int *)cdata;
1755
1756 (*a_wait)++;
1757 sock.Notify(FALSE);
1758 }
1759
1760 int wxSocketHandler::Wait(long seconds, long microseconds)
1761 {
1762 int i;
1763 int on_wait;
1764 wxSockWakeUp s_wake(NULL, &on_wait, -2);
1765 wxNode *node;
1766
1767 for (node = socks->First(), i=0; node; node = node->Next(), i++)
1768 {
1769 wxSocketBase *sock = (wxSocketBase *)node->Data();
1770
1771 sock->SaveState();
1772
1773 sock->SetupCallbacks();
1774
1775 sock->Callback(handler_cbk);
1776 sock->CallbackData((char *)&on_wait);
1777 }
1778 on_wait = 0;
1779 if (seconds != -1)
1780 s_wake.Start((seconds*1000) + (microseconds/1000), TRUE);
1781
1782 while (!on_wait)
1783 PROCESS_EVENTS();
1784
1785 for (node = socks->First(), i=0; node; node = node->Next(), i++)
1786 {
1787 wxSocketBase *sock = (wxSocketBase *)node->Data();
1788
1789 sock->RestoreState();
1790 }
1791
1792 if (on_wait == -2)
1793 return 0;
1794
1795 return on_wait;
1796 }
1797
1798 void wxSocketHandler::YieldSock()
1799 {
1800 wxNode *node;
1801
1802 for (node = socks->First(); node; node = node->Next() )
1803 {
1804 wxSocketBase *sock = (wxSocketBase *)node->Data();
1805
1806 sock->SaveState();
1807
1808 sock->SetFlags(wxSocketBase::SPEED);
1809 if (sock->IsData())
1810 sock->DoRequests(wxSocketBase::EVT_READ);
1811 sock->DoRequests(wxSocketBase::EVT_WRITE);
1812
1813 sock->RestoreState();
1814 }
1815 }
1816
1817 // --------------------------------------------------------------
1818 // --------- wxSocketHandler: create and register the socket ----
1819 // --------------------------------------------------------------
1820 wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
1821 wxSocketBase::wxSockFlags flags)
1822 {
1823 wxSocketServer *serv = new wxSocketServer(addr, flags);
1824
1825 Register(serv);
1826 return serv;
1827 }
1828
1829 wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
1830 {
1831 wxSocketClient *client = new wxSocketClient(flags);
1832
1833 Register(client);
1834 return client;
1835 }
1836
1837 #ifdef __WINDOWS__
1838 // --------------------------------------------------------------
1839 // --------- wxSocketHandler: Windows specific methods ----------
1840 // --------------------------------------------------------------
1841
1842 UINT wxSocketHandler::NewMessage(wxSocketBase *sock)
1843 {
1844 internal->firstAvailableMsg++;
1845 smsg_list->Append(internal->firstAvailableMsg, sock);
1846 return internal->firstAvailableMsg;
1847 }
1848
1849 void wxSocketHandler::DestroyMessage(UINT msg)
1850 {
1851 wxNode *node = smsg_list->Find(msg);
1852 delete node;
1853 }
1854
1855 HWND wxSocketHandler::GetHWND() const
1856 {
1857 return internal->sockWin;
1858 }
1859
1860 #endif
1861
1862 bool wxSocketModule::OnInit()
1863 {
1864 wxSocketHandler::master = new wxSocketHandler();
1865 return TRUE;
1866 }
1867
1868 void wxSocketModule::OnExit()
1869 {
1870 delete wxSocketHandler::master;
1871 wxSocketHandler::master = NULL;
1872 }
1873
1874 #ifdef __WXMAC__
1875 void wxMacProcessSocketEvents() ;
1876 void wxMacProcessEvents()
1877 {
1878 wxMacProcessSocketEvents() ;
1879 (*GUSISpin)(SP_MISC, 0) ;
1880 }
1881
1882 void wxMacProcessSocketEvents()
1883 {
1884 while ( wxMacNetEventsTop != wxMacNetEventsBottom )
1885 {
1886 // consume event at wxMacNetEventsBottom
1887 wxMacSocketOnRequestProc(wxMacNetEventsReferences[wxMacNetEventsBottom] , wxMacNetEventsEvents[wxMacNetEventsBottom] ) ;
1888 wxMacNetEventsBottom++ ;
1889 if ( wxMacNetEventsBottom == kwxMacNetEventsMax )
1890 wxMacNetEventsBottom = 0 ;
1891 }
1892 }
1893 #endif
1894
1895 #endif
1896 // __WXSTUBS__