X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f4ada568223b79c8a5769cc351c36a8e2ccd7841..3e418ffc1002c514f0e3e876809c33ae9ad8695b:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index f880c2d6e5..4f3b8085e5 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -9,12 +9,23 @@ // RCS_ID: $Id$ // License: see wxWindows license //////////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#ifdef __GNUG__ #pragma implementation "socket.h" -#pragma interface -#pragma implementation "socket.cpp" #endif +#ifdef __MWERKS__ +typedef int socklen_t ; +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#if wxUSE_SOCKETS + ///////////////////////////////////////////////////////////////////////////// // wxWindows headers ///////////////////////////////////////////////////////////////////////////// @@ -24,6 +35,9 @@ #include #include +// Not enough OS behaviour defined for wxStubs +#ifndef __WXSTUBS__ + #include #include #include @@ -31,6 +45,33 @@ ///////////////////////////////////////////////////////////////////////////// // System specific headers ///////////////////////////////////////////////////////////////////////////// +#ifdef __WXMAC__ +// in order to avoid problems with our c library and double definitions +#define close closesocket +#define ioctl ioctlsocket + +#include +extern GUSISpinFn GUSISpin; +#define PROCESS_EVENTS() wxMacProcessEvents() +const short kwxMacNetEventsMax = 1000 ; +short wxMacNetEventsTop = 0 ; +short wxMacNetEventsBottom = 0 ; +short wxMacNetEventsEvents[kwxMacNetEventsMax] ; +void *wxMacNetEventsReferences[kwxMacNetEventsMax] ; + +#define FD_READ 1 +#define FD_WRITE 2 +#define FD_CLOSE 4 +#define FD_ACCEPT 8 +#define FD_CONNECT 16 +#define FD_READY 32 + +extern "C" void wxMacSocketHandlerProc( void *refcon , short event ) ; // adds events +extern "C" void wxMacSocketOnRequestProc( void *refcon , short event ) ; // consumes them +extern "C" void GUSISetReference( short sock , short eventmask , void * data ) ; +void wxMacProcessEvents() ; +#endif + #if defined(__WINDOWS__) #include #endif // __WINDOWS__ @@ -47,11 +88,19 @@ #include #include +#ifdef sun +#include +#endif + #endif // __UNIX__ #include #include +#ifdef __VISUALC__ +#include +#endif + #if defined(__WXMOTIF__) || defined(__WXXT__) #include @@ -71,20 +120,20 @@ ///////////////////////////////////////////////////////////////////////////// // wxSocket headers ///////////////////////////////////////////////////////////////////////////// +#include "wx/module.h" #define WXSOCK_INTERNAL #include "wx/sckaddr.h" #include "wx/socket.h" -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - ///////////////////////////////////////////////////////////////////////////// // Some patch ///// BEGIN ///////////////////////////////////////////////////////////////////////////// #ifdef __WINDOWS__ #define close closesocket #define ioctl ioctlsocket +#ifdef errno +#undef errno +#endif #define errno WSAGetLastError() #ifdef EWOULDBLOCK #undef EWOULDBLOCK @@ -100,7 +149,7 @@ #endif #ifdef __WXMOTIF__ -#define wxAPP_CONTEXT wxTheApp->appContext +#define wxAPP_CONTEXT ((XtAppContext)wxTheApp->GetAppContext()) #endif #ifdef __WINDOWS__ @@ -108,18 +157,18 @@ // implementations (such as PC-NFS) will require you to include this // or a similar routine (see appendix in WinSock doc or help file). -#if defined( NEED_WSAFDIsSet ) || defined( _MSC_VER ) +#if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ ) int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) { - int i = set->fd_count; + int i = set->fd_count; - while (i--) - { - if (set->fd_array[i] == fd) - return 1; - } + while (i--) + { + if (set->fd_array[i] == fd) + return 1; + } - return 0; + return 0; } #endif #endif @@ -136,6 +185,22 @@ int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) // Some patch ///// END ///////////////////////////////////////////////////////////////////////////// +#ifdef GetClassInfo +#undef GetClassInfo +#endif + +// -------------------------------------------------------------- +// Module +// -------------------------------------------------------------- +class wxSocketModule: public wxModule +{ + DECLARE_DYNAMIC_CLASS(wxSocketModule) +public: + wxSocketModule() {} + bool OnInit(); + void OnExit(); +}; + // -------------------------------------------------------------- // ClassInfos // -------------------------------------------------------------- @@ -145,26 +210,31 @@ IMPLEMENT_CLASS(wxSocketServer, wxSocketBase) IMPLEMENT_CLASS(wxSocketClient, wxSocketBase) IMPLEMENT_CLASS(wxSocketHandler, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent) +IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule) #endif -class wxSockWakeUp : public wxTimer { +class wxSockWakeUp : public wxTimer +{ public: int *my_id; int n_val; wxSocketBase *sock; - wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val) { + wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val) + { my_id = id; n_val = new_val; sock = _sock; } - virtual void Notify() { + virtual void Notify() + { *my_id = n_val; if (sock) sock->Notify(FALSE); } }; /// Socket request -class SockRequest : public wxObject { +class SockRequest : public wxObject +{ public: char *buffer; size_t size, nbytes; @@ -173,7 +243,7 @@ public: wxSockWakeUp *auto_wakeup; wxSocketBase::wxRequestNotify type; }; - + ///////////////////////////////////////////////////////////////////////////// // Some internal define @@ -183,7 +253,7 @@ public: // --------- wxSocketBase CONSTRUCTOR --------------------------- // -------------------------------------------------------------- wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags, - wxSocketBase::wxSockType _type) : + wxSocketBase::wxSockType _type) : wxEvtHandler(), m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE), m_fd(INVALID_SOCKET), m_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1), @@ -229,8 +299,9 @@ wxSocketBase::wxSocketBase() : } // -------------------------------------------------------------- -// --------- wxSocketBase CONSTRUCTOR --------------------------- +// wxSocketBase // -------------------------------------------------------------- + wxSocketBase::~wxSocketBase() { DestroyCallbacks(); @@ -238,7 +309,8 @@ wxSocketBase::~wxSocketBase() if (m_unread) free(m_unread); - if (m_handler) { + if (m_handler) + { #ifdef __WINDOWS__ if (m_internal->my_msg) m_handler->DestroyMessage(m_internal->my_msg); @@ -252,14 +324,17 @@ wxSocketBase::~wxSocketBase() bool wxSocketBase::Close() { - if (m_fd != INVALID_SOCKET) { - for (int i=0;i<3;i++) { + if (m_fd != INVALID_SOCKET) + { + for (int i=0;i<3;i++) + { wxNode *n, *node = req_list[i].First(); - while (node) { + while (node) + { SockRequest *req = (SockRequest *)node->Data(); req->done = TRUE; - + n = node->Next(); delete node; node = n; @@ -277,33 +352,47 @@ bool wxSocketBase::Close() } // -------------------------------------------------------------- -// --------- wxSocketBase base IO functions --------------------- +// wxSocketBase base IO function // -------------------------------------------------------------- + wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) { - m_lcount = GetPushback(buffer, nbytes, FALSE); + size_t count; + + count = GetPushback(buffer, nbytes, FALSE); + nbytes -= count; + buffer += count; // If we have got the whole needed buffer or if we don't want to // wait then it returns immediately. - if (!nbytes || (m_lcount && !(m_flags & WAITALL)) ) + if (!nbytes || (count && !(m_flags & WAITALL)) ) { + m_lcount = count; return *this; + } + m_lcount = 0; WantBuffer(buffer, nbytes, EVT_READ); + m_lcount += count; return *this; } wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) { - size_t nbytes_old = nbytes; + size_t count; - nbytes -= GetPushback(buffer, nbytes, TRUE); - if (!nbytes) { - m_lcount = nbytes_old; + count = GetPushback(buffer, nbytes, TRUE); + if (nbytes-count == 0) + { + m_lcount = nbytes; return *this; } + buffer += count; + nbytes -= count; + m_lcount = 0; WantBuffer(buffer, nbytes, EVT_PEEK); + m_lcount += count; return *this; } @@ -318,7 +407,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) { SockMsg msg; size_t len, len2, sig; - + Read((char *)&msg, sizeof(msg)); if (m_lcount != sizeof(msg)) return *this; @@ -361,30 +450,39 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) { SockMsg msg; - - msg.sig[0] = 0xad; - msg.sig[1] = 0xde; - msg.sig[2] = 0xed; - msg.sig[3] = 0xfe; - msg.len[0] = nbytes & 0xff; - msg.len[1] = (nbytes >> 8) & 0xff; - msg.len[2] = (nbytes >> 16) & 0xff; - msg.len[3] = (nbytes >> 24) & 0xff; + // warning about 'cast truncates constant value' +#ifdef __VISUALC__ + #pragma warning(disable: 4310) +#endif // __VISUALC__ + + msg.sig[0] = (char) 0xad; + msg.sig[1] = (char) 0xde; + msg.sig[2] = (char) 0xed; + msg.sig[3] = (char) 0xfe; + + msg.len[0] = (char) nbytes & 0xff; + msg.len[1] = (char) (nbytes >> 8) & 0xff; + msg.len[2] = (char) (nbytes >> 16) & 0xff; + msg.len[3] = (char) (nbytes >> 24) & 0xff; if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg)) return *this; if (Write(buffer, nbytes).LastCount() < nbytes) - return *this; + return *this; - msg.sig[0] = 0xed; - msg.sig[1] = 0xfe; - msg.sig[2] = 0xad; - msg.sig[3] = 0xde; - msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = 0; + msg.sig[0] = (char) 0xed; + msg.sig[1] = (char) 0xfe; + msg.sig[2] = (char) 0xad; + msg.sig[3] = (char) 0xde; + msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0; Write((char *)&msg, sizeof(msg)); return *this; + +#ifdef __VISUALC__ + #pragma warning(default: 4310) +#endif // __VISUALC__ } wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes) @@ -408,7 +506,7 @@ bool wxSocketBase::IsData() const FD_ZERO(&sock_set); FD_SET(m_fd, &sock_set); select(FD_SETSIZE, &sock_set, NULL, NULL, &tv); - return FD_ISSET(m_fd, &sock_set); + return (FD_ISSET(m_fd, &sock_set) != 0); } // --------------------------------------------------------------------- @@ -422,8 +520,9 @@ void wxSocketBase::Discard() SaveState(); SetFlags((wxSockFlags)(NOWAIT | SPEED)); - - while (recv_size == MAX_BUFSIZE) { + + while (recv_size == MAX_BUFSIZE) + { recv_size = Read(my_data, MAX_BUFSIZE).LastCount(); } @@ -433,23 +532,37 @@ void wxSocketBase::Discard() #undef MAX_BUFSIZE } +// If what? Who seems to need unsigned int? +// BTW uint isn't even defined on wxMSW for VC++ for some reason. Even if it +// were, getpeername/getsockname don't take unsigned int*, they take int*. +// +// Under glibc 2.0.7, socketbits.h declares socklen_t to be unsigned int +// and it uses *socklen_t as the 3rd parameter. Robert. + +// JACS - How can we detect this? +// Meanwhile, if your compiler complains about socklen_t, +// switch lines below. + +#if wxHAVE_GLIBC2 +# define wxSOCKET_INT socklen_t +#else +# define wxSOCKET_INT int +#endif + // -------------------------------------------------------------- -// --------- wxSocketBase socket info functions ----------------- +// wxSocketBase socket info functions // -------------------------------------------------------------- + bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const { struct sockaddr my_addr; - size_t len_addr = sizeof(my_addr); + wxSOCKET_INT len_addr = sizeof(my_addr); if (m_fd < 0) return FALSE; -#ifdef __WINDOWS__ - if (getpeername(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0) -#else - if (getpeername(m_fd, (struct sockaddr *)&my_addr, (unsigned int *)&len_addr) < 0) -#endif - return FALSE; + if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) + return FALSE; addr_man.Disassemble(&my_addr, len_addr); return TRUE; @@ -458,16 +571,13 @@ bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const { struct sockaddr my_addr; - size_t len_addr = sizeof(my_addr); + wxSOCKET_INT len_addr = sizeof(my_addr); if (m_fd < 0) return FALSE; -#ifdef __WINDOWS__ - if (getsockname(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0) -#else - if (getsockname(m_fd, (struct sockaddr *)&my_addr, (unsigned int *)&len_addr) < 0) -#endif + if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) + return FALSE; addr_man.Disassemble(&my_addr, len_addr); @@ -475,8 +585,9 @@ bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const } // -------------------------------------------------------------- -// --------- wxSocketBase wait functions ------------------------ +// wxSocketBase wait functions // -------------------------------------------------------------- + void wxSocketBase::SaveState() { wxSockState *state = new wxSockState; @@ -500,7 +611,7 @@ void wxSocketBase::RestoreState() return; wxSockState *state = (wxSockState *)node->Data(); - + SetFlags(state->flags); m_neededreq = state->cbk_set; m_cbk = state->cbk; @@ -518,7 +629,7 @@ void wxSocketBase::RestoreState() // -------------------------------------------------------------- // --------- wxSocketBase wait functions ------------------------ // -------------------------------------------------------------- -// + bool wxSocketBase::_Wait(long seconds, long microseconds, int type) { if ((!m_connected && !m_connecting) || m_fd < 0) @@ -532,14 +643,15 @@ bool wxSocketBase::_Wait(long seconds, long microseconds, int type) if (seconds != -1) wakeup.Start((int)(seconds*1000 + (microseconds / 1000)), TRUE); - + m_waitflags = 0x80 | type; while (m_waitflags & 0x80) PROCESS_EVENTS(); RestoreState(); - if (m_waitflags & 0x40) { + if (m_waitflags & 0x40) + { m_waitflags = 0; return TRUE; } @@ -573,10 +685,24 @@ bool wxSocketBase::WaitForLost(long seconds, long microseconds) // --------- wxSocketBase callback management ------------------- // -------------------------------------------------------------- +#ifdef __WXGTK__ +void wxPrereadSocket(wxSocketBase *sock) +{ + char tmp_buf[1024]; + int got = 0; + + do { + got = recv(sock->m_fd, tmp_buf, 1024, 0); + if (got > 0) + sock->CreatePushbackAfter(tmp_buf, got); + } while (got > 0); +} +#endif + #if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__) #if defined(__WXMOTIF__) || defined(__WXXT__) static void wx_socket_read(XtPointer client, int *fid, - XtInputId *WXUNUSED(id)) + XtInputId *WXUNUSED(id)) #define fd *fid #else static void wx_socket_read(gpointer client, gint fd, @@ -590,18 +716,34 @@ static void wx_socket_read(gpointer client, gint fd, i = recv(fd, &c, 1, MSG_PEEK); - if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) { + if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) + { sock->OnRequest(wxSocketBase::EVT_ACCEPT); return; } - if (i != 0) { + if (i != 0) + { if (!(sock->NeededReq() & wxSocketBase::REQ_READ)) + { +#ifdef __WXGTK__ + // We can't exit from the GDK main loop because it doesn't accept + // destroying input event while we are in a event dispatch. + // So we will preread socket and we put the data in the pushback. + wxPrereadSocket(sock); + // Then we set the socket as BLOCKING + int flag = 0; + ioctl(fd, FIONBIO, &flag); +#endif return; + } sock->OnRequest(wxSocketBase::EVT_READ); - } else { - if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) { + } + else + { + if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) + { sock->Close(); return; } @@ -613,10 +755,10 @@ static void wx_socket_read(gpointer client, gint fd, #if defined(__WXMOTIF__) || defined(__WXXT__) static void wx_socket_write(XtPointer client, int *WXUNUSED(fid), - XtInputId *WXUNUSED(id)) + XtInputId *WXUNUSED(id)) #else static void wx_socket_write(gpointer client, gint WXUNUSED(fd), - GdkInputCondition WXUNUSED(cond)) + GdkInputCondition WXUNUSED(cond)) #endif { wxSocketBase *sock = (wxSocketBase *)client; @@ -637,18 +779,22 @@ Notify_value wx_sock_read_xview (Notify_client client, int fd) i = recv(fd, &c, 1, MSG_PEEK); - if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) { + if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) + { sock->OnRequest(wxSocketBase::EVT_ACCEPT); return; } /* Bytes arrived */ - if (i != 0) { + if (i != 0) + { if (!(sock->NeededReq() & wxSocketBase::REQ_READ)) return (Notify_value) FALSE; sock->OnRequest(wxSocketBase::EVT_READ); - } else { + } + else + { if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) return; @@ -673,7 +819,8 @@ Notify_value wx_sock_write_xview (Notify_client client, int fd) wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt) { - switch (evt) { + switch (evt) + { case EVT_READ: return REQ_READ; case EVT_PEEK: @@ -693,7 +840,8 @@ wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt) void wxSocketBase::SetFlags(wxSockFlags _flags) { m_flags = _flags; - if (_flags & SPEED) { + if (_flags & SPEED) + { unsigned long flag = 0; ioctl(m_fd, FIONBIO, &flag); @@ -701,7 +849,9 @@ void wxSocketBase::SetFlags(wxSockFlags _flags) m_flags = (wxSockFlags)(m_flags & ~WAITALL); Notify(FALSE); - } else { + } + else + { unsigned long flag = 1; ioctl(m_fd, FIONBIO, &flag); } @@ -710,13 +860,20 @@ void wxSocketBase::SetFlags(wxSockFlags _flags) void wxSocketBase::SetNotify(wxRequestNotify flags) { wxRequestNotify old_needed_req = m_neededreq; - if (flags & REQ_ACCEPT) { + if (flags & REQ_ACCEPT) + { /* Check if server */ if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer)))) flags &= ~REQ_ACCEPT; } m_neededreq = flags; - if (m_cbkon && old_needed_req != flags) + +/* + if (m_cbkon && old_needed_req != flags) seems to be wrong, Robert Roebling + SetupCallbacks(); +*/ + + if (old_needed_req != flags) SetupCallbacks(); } @@ -725,33 +882,89 @@ void wxSocketBase::SetupCallbacks() if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED)) return; -#if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__) - if (m_cbkon) - DestroyCallbacks(); - if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) { -#ifdef __WXGTK__ - m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ, - wx_socket_read, (gpointer)this); -#else - m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, +#if defined(__WXMOTIF__) || defined(__WXXT__) + if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) + { + if (m_internal->sock_inputid <= 0) + { + m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, (XtPointer *) XtInputReadMask, (XtInputCallbackProc) wx_socket_read, (XtPointer) this); -#endif + } } - if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) { -#ifdef __WXGTK__ - m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_WRITE, - wx_socket_write, (gpointer)this); -#else - m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, + else + { + if (m_internal->sock_inputid > 0) + { + XtRemoveInput(m_internal->sock_inputid); + m_internal->sock_inputid = 0; + } + } + + if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) + { + if (m_internal->sock_outputid <= 0) + { + m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, (XtPointer *) XtInputWriteMask, (XtInputCallbackProc) wx_socket_write, (XtPointer) this); + } + } + else + { + if (m_internal->sock_outputid > 0) + { + XtRemoveInput(m_internal->sock_outputid); + m_internal->sock_outputid = 0; + } + } #endif + + +#ifdef __WXGTK__ + if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) + { + if (m_internal->sock_inputid <= 0) + { + m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ, + wx_socket_read, (gpointer)this); + } + } + else + { + if (m_internal->sock_inputid > 0) + { +/* + gdk_input_remove(m_internal->sock_inputid); + m_internal->sock_inputid = 0; +*/ + } + } + + if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) + { + if (m_internal->sock_outputid <= 0) + { + m_internal->sock_outputid = gdk_input_add(m_fd, GDK_INPUT_WRITE, + wx_socket_write, (gpointer)this); + } + } + else + { + if (m_internal->sock_outputid > 0) + { +/* + gdk_input_remove(m_internal->sock_outputid); + m_internal->sock_outputid = 0; +*/ + } } #endif -#ifdef __WINDOWS__ + + +#ifdef __WXMSW__ WORD mask = 0; if (m_neededreq & REQ_READ) @@ -768,6 +981,24 @@ void wxSocketBase::SetupCallbacks() if (!m_internal->my_msg) m_internal->my_msg = m_handler->NewMessage(this); WSAAsyncSelect(m_fd, m_handler->GetHWND(), m_internal->my_msg, mask); +#endif +#ifdef __WXMAC__ + short mask = 0; + + if (m_neededreq & REQ_READ) + mask |= FD_READ; + if (m_neededreq & REQ_WRITE) + mask |= FD_WRITE; + if (m_neededreq & REQ_LOST) + mask |= FD_CLOSE; + if (m_neededreq & REQ_ACCEPT) + mask |= FD_ACCEPT; + if (m_neededreq & REQ_CONNECT) + mask |= FD_CONNECT; + + GUSISetReference( m_fd ,mask, this ) ; + unsigned long flag = 1; + ioctl(m_fd, FIONBIO, &flag); #endif m_cbkon = TRUE; m_processing = FALSE; @@ -777,6 +1008,7 @@ void wxSocketBase::DestroyCallbacks() { if (!m_cbkon || !m_handler) return; + m_cbkon = FALSE; m_processing = FALSE; #if defined(__WXMOTIF__) || defined(__WXXT__) @@ -798,6 +1030,20 @@ void wxSocketBase::DestroyCallbacks() #ifdef __WINDOWS__ WSAAsyncSelect(m_fd, m_handler->GetHWND(), 0, 0); #endif +#ifdef __WXMAC__ + GUSISetReference( m_fd , 0 , 0 ) ; + int bottom = wxMacNetEventsBottom ; + while ( wxMacNetEventsTop != bottom ) + { + // set all events that reference this socket to nil + if ( wxMacNetEventsReferences[bottom] == (void*) this ) + wxMacNetEventsReferences[bottom] = NULL ; + bottom++ ; + if ( bottom == kwxMacNetEventsMax ) + bottom = 0 ; + } + SetFlags( m_flags ) ; +#endif } void wxSocketBase::Notify(bool notify) @@ -816,23 +1062,26 @@ void wxSocketBase::OnRequest(wxRequestEvent req_evt) wxRequestNotify req_notif = EventToNotify(req_evt); // Mask the current event - SetNotify(m_neededreq & ~req_notif); - + SetNotify(m_neededreq & ~req_notif); + if (req_evt <= EVT_WRITE && DoRequests(req_evt)) return; - if (m_waitflags & 0xF0) { + if (m_waitflags & 0xF0) + { // Wake up - if ((m_waitflags & 0x0F) == req_evt) { + if ((m_waitflags & 0x0F) == req_evt) + { m_waitflags = 0x80; #ifndef __WXGTK__ - DestroyCallbacks(); // I disable it to prevent infinite loop on X11. + DestroyCallbacks(); #endif } return; } - if (req_evt == EVT_LOST) { + if (req_evt == EVT_LOST) + { m_connected = FALSE; Close(); } @@ -866,6 +1115,7 @@ void wxSocketBase::OldOnNotify(wxRequestEvent evt) // -------------------------------------------------------------- // --------- wxSocketBase functions [Callback, CallbackData] ---- // -------------------------------------------------------------- + wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk) { wxSockCbk old_cbk = m_cbk; @@ -891,11 +1141,15 @@ void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id) // -------------------------------------------------------------- // --------- wxSocketBase pushback library ---------------------- // -------------------------------------------------------------- + void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) { char *curr_pos; - m_unread = (char *) realloc(m_unread, m_unrd_size+size); + if (m_unread != NULL) + m_unread = (char *) realloc(m_unread, m_unrd_size+size); + else + m_unread = (char *) malloc(size); curr_pos = m_unread + m_unrd_size; memcpy(curr_pos, buffer, size); @@ -910,9 +1164,10 @@ void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size) curr_pos = new_buf + size; memcpy(new_buf, buffer, size); - memcpy(curr_pos, m_unread, m_unrd_size); - - free(m_unread); + if (m_unrd_size != 0) { + memcpy(curr_pos, m_unread, m_unrd_size); + free(m_unread); + } m_unread = new_buf; m_unrd_size += size; } @@ -928,7 +1183,7 @@ size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek) if (!peek) { m_unrd_size -= size; - if (!m_unrd_size) { + if (m_unrd_size == 0) { free(m_unread); m_unread = NULL; } @@ -954,18 +1209,21 @@ bool wxSocketBase::DoRequests(wxRequestEvent req_flag) delete node; - switch (req->type) { + switch (req->type) + { case EVT_READ: case EVT_PEEK: ret = recv(m_fd, req->buffer, req->size, (req->type == EVT_PEEK) ? MSG_PEEK : 0); - if (ret < 0) { + if (ret < 0) + { req->error = errno; req->done = TRUE; break; } len = ret; - if ((len < req->size) && (m_flags & WAITALL)) { + if ((len < req->size) && (m_flags & WAITALL)) + { req->size -= len; req->nbytes += len; req->buffer += len; @@ -981,13 +1239,15 @@ bool wxSocketBase::DoRequests(wxRequestEvent req_flag) break; case EVT_WRITE: ret = send(m_fd, req->buffer, req->size, 0); - if (ret < 0) { + if (ret < 0) + { req->error = errno; req->done = TRUE; break; } len = ret; - if ((len < req->size) && (m_flags & WAITALL)) { + if ((len < req->size) && (m_flags & WAITALL)) + { req->size -= len; req->nbytes += len; req->buffer += len; @@ -1010,40 +1270,48 @@ bool wxSocketBase::DoRequests(wxRequestEvent req_flag) void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes, wxRequestEvent evt) { - int ret; + int ret = 0; - switch (evt) { + switch (evt) + { case EVT_PEEK: case EVT_READ: - ret = read(m_fd, buffer, nbytes); + ret = recv(m_fd, buffer, nbytes, + (evt == EVT_PEEK) ? MSG_PEEK : 0); break; case EVT_WRITE: - ret = write(m_fd, buffer, nbytes); + ret = send(m_fd, buffer, nbytes, 0); break; } - if (ret < 0) { + if (ret < 0) + { m_lcount = 0; m_error = errno; - } else + } + else + { m_lcount = ret; + m_error = 0; + } } void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, - wxRequestEvent evt) + wxRequestEvent evt) { bool buf_timed_out; if (m_fd == INVALID_SOCKET || !m_handler || !m_connected) return; - if (m_flags & SPEED) { + if (m_flags & SPEED) + { WantSpeedBuffer(buffer, nbytes, evt); return; } SockRequest *buf = new SockRequest; wxSockWakeUp s_wake(NULL, (int *)&buf_timed_out, (int)TRUE); - + m_wantbuf++; req_list[evt].Append(buf); @@ -1060,9 +1328,12 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, buf_timed_out = FALSE; s_wake.Start(m_timeout*1000, TRUE); - if (m_flags & NOWAIT) { + if (m_flags & NOWAIT) + { DoRequests(evt); - } else { + } + else + { while (!buf->done && !buf_timed_out) PROCESS_EVENTS(); } @@ -1078,31 +1349,28 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, } // -------------------------------------------------------------- -// wxSocketServer /////////////////////////////////////////////// +// wxSocketServer // -------------------------------------------------------------- -// -------------------------------------------------------------- -// --------- wxSocketServer CONSTRUCTOR ------------------------- -// -------------------------------------------------------------- wxSocketServer::wxSocketServer(wxSockAddress& addr_man, - wxSockFlags flags) : + wxSockFlags flags) : wxSocketBase(flags, SOCK_SERVER) { m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0); if (m_fd == INVALID_SOCKET) return; - + int flag = 1; setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int)); - + struct sockaddr *myaddr; size_t len; - + addr_man.Build(myaddr, len); if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0) return; - + if (listen(m_fd, 5) < 0) { m_fd = INVALID_SOCKET; return; @@ -1110,29 +1378,31 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man, } // -------------------------------------------------------------- -// --------- wxSocketServer Accept ------------------------------ +// wxSocketServer Accept // -------------------------------------------------------------- + bool wxSocketServer::AcceptWith(wxSocketBase& sock) { int fd2; - + if ((fd2 = accept(m_fd, 0, 0)) < 0) return FALSE; struct linger linger; linger.l_onoff = 0; linger.l_linger = 1; - + setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); - + int flag = 0; setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int)); - - if (!(sock.m_flags & SPEED)) { + + if (!(sock.m_flags & SPEED)) + { unsigned long flag2 = 1; ioctl(fd2, FIONBIO, &flag2); } - + sock.m_type = SOCK_INTERNAL; sock.m_fd = fd2; sock.m_connected = TRUE; @@ -1156,23 +1426,25 @@ wxSocketBase *wxSocketServer::Accept() } // -------------------------------------------------------------- -// --------- wxSocketServer callbacks --------------------------- +// wxSocketServer callbacks // -------------------------------------------------------------- + void wxSocketServer::OnRequest(wxRequestEvent evt) { - if (evt == EVT_ACCEPT) { + if (evt == EVT_ACCEPT) + { OldOnNotify(EVT_ACCEPT); } } // -------------------------------------------------------------- -// wxSocketClient /////////////////////////////////////////////// +// wxSocketClient // -------------------------------------------------------------- // --------- wxSocketClient CONSTRUCTOR ------------------------- // -------------------------------------------------------------- wxSocketClient::wxSocketClient(wxSockFlags _flags) : - wxSocketBase(_flags, SOCK_CLIENT) + wxSocketBase(_flags, SOCK_CLIENT) { } @@ -1186,7 +1458,7 @@ wxSocketClient::~wxSocketClient() // -------------------------------------------------------------- // --------- wxSocketClient Connect functions ------------------- // -------------------------------------------------------------- -bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) +bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) ) { struct linger linger; @@ -1194,21 +1466,21 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) Close(); m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0); - + if (m_fd < 0) return FALSE; - + m_connected = FALSE; linger.l_onoff = 1; - linger.l_linger = 5; + linger.l_linger = 5; setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); - + // Stay in touch with the state of things... - + unsigned long flag = 1; setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int)); - + // Disable the nagle algorithm, which delays sends till the // buffer is full (or a certain time period has passed?)... @@ -1216,7 +1488,7 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) flag = 1; setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); #endif - + struct sockaddr *remote; size_t len; @@ -1225,38 +1497,45 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) if (connect(m_fd, remote, len) != 0) return FALSE; - if (!(m_flags & SPEED)) { + if (!(m_flags & SPEED)) + { flag = 1; ioctl(m_fd, FIONBIO, &flag); } - + Notify(TRUE); m_connected = TRUE; return TRUE; } -bool wxSocketClient::WaitOnConnect(long seconds) +bool wxSocketClient::WaitOnConnect(long seconds, long microseconds) { - int ret = _Wait(seconds, 0, REQ_CONNECT | REQ_LOST); - + int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST); + if (ret) m_connected = TRUE; - - return m_connected; + + return m_connected; } void wxSocketClient::OnRequest(wxRequestEvent evt) { - if (evt == EVT_CONNECT) { - if (m_connected) { + if (evt == EVT_CONNECT) + { + if (m_connected) + { +#ifndef __WXGTK__ SetNotify(m_neededreq & ~REQ_CONNECT); +#endif return; } m_waitflags = 0x40; - m_connected = TRUE; + m_connected = TRUE; OldOnNotify(EVT_CONNECT); +#ifndef __WXGTK__ DestroyCallbacks(); +#endif return; } wxSocketBase::OnRequest(evt); @@ -1274,6 +1553,64 @@ static int win_initialized = 0; // -------------------------------------------------------------- // --------- wxSocketHandler CONSTRUCTOR ------------------------ // -------------------------------------------------------------- +#ifdef __WXMAC__ + +extern "C" int updatestatus(int s) ; + +void wxMacSocketOnRequestProc( void *refcon , short event ) +{ + if ( refcon ) + { + wxSocketBase *sock = (wxSocketBase *) refcon ; + + wxSocketBase::wxRequestEvent sk_req; + + int canRead ; + int canWrite ; + int exception ; + + switch (event) { + case FD_READ: + sk_req = wxSocketBase::EVT_READ; + sock->OnRequest(sk_req); + break; + case FD_WRITE: + sk_req = wxSocketBase::EVT_WRITE; + sock->OnRequest(sk_req); + break; + case FD_CLOSE: + sk_req = wxSocketBase::EVT_LOST; + sock->OnRequest(sk_req); + break; + case FD_ACCEPT: + sk_req = wxSocketBase::EVT_ACCEPT; + sock->OnRequest(sk_req); + break; + case FD_CONNECT: + sk_req = wxSocketBase::EVT_CONNECT; + sock->OnRequest(sk_req); + break; + case FD_READY : + break ; + } + updatestatus ( sock->m_fd ) ; + } +} + +void wxMacSocketHandlerProc( void *refcon , short event ) +{ + wxMacNetEventsReferences[wxMacNetEventsTop] = refcon ; + wxMacNetEventsEvents[wxMacNetEventsTop] = event ; + + // clumsy construct in order to never have a incorrect wxMacNetEventsTop (above limits) + + if ( wxMacNetEventsTop + 1 == kwxMacNetEventsMax ) + wxMacNetEventsTop = 0 ; + else + wxMacNetEventsTop++ ; +} + +#endif #ifdef __WINDOWS__ extern char wxPanelClassName[]; @@ -1281,6 +1618,11 @@ extern char wxPanelClassName[]; LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + if(message==WM_DESTROY) + { + ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc); + return DefWindowProc(hWnd, message, wParam, lParam); + } wxSocketHandler *h_sock = (wxSocketHandler *)GetWindowLong(hWnd, GWL_USERDATA); wxNode *node = h_sock->smsg_list->Find(message); wxSocketBase *sock; @@ -1308,7 +1650,12 @@ LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message, case FD_CONNECT: sk_req = wxSocketBase::EVT_CONNECT; break; + + default: + wxFAIL_MSG("invalid socket event"); + return (LRESULT)0; } + sock->OnRequest(sk_req); return (LRESULT)0; @@ -1321,7 +1668,8 @@ FARPROC wxSocketSubClassProc = NULL; wxSocketHandler::wxSocketHandler() { #if defined(__WINDOWS__) - if (!win_initialized) { + if (!win_initialized) + { WSADATA wsaData; WSAStartup((1 << 8) | 1, &wsaData); @@ -1329,8 +1677,8 @@ wxSocketHandler::wxSocketHandler() } internal = new wxSockHandlerInternal; internal->sockWin = ::CreateWindow(wxPanelClassName, NULL, 0, - 0, 0, 0, 0, NULL, (HMENU) NULL, - wxhInstance, 0); + 0, 0, 0, 0, NULL, (HMENU) NULL, + wxhInstance, 0); // Subclass the window if (!wxSocketSubClassProc) @@ -1356,7 +1704,8 @@ wxSocketHandler::~wxSocketHandler() { wxNode *next_node, *node = socks->First(); - while (node) { + while (node) + { wxSocketBase* sock = (wxSocketBase*)node->Data(); delete sock; @@ -1381,18 +1730,21 @@ wxSocketHandler::~wxSocketHandler() // -------------------------------------------------------------- // --------- wxSocketHandler registering functions -------------- // -------------------------------------------------------------- + void wxSocketHandler::Register(wxSocketBase* sock) { wxNode *node; - for (node = socks->First(); node != NULL; node = node->Next()) { + for (node = socks->First(); node != NULL; node = node->Next()) + { wxSocketBase* s = (wxSocketBase*)node->Data(); if (s == sock) return; } - if (sock) { + if (sock) + { socks->Append(sock); sock->SetHandler(this); sock->SetupCallbacks(); @@ -1403,10 +1755,12 @@ void wxSocketHandler::UnRegister(wxSocketBase* sock) { wxNode *node; - for (node = socks->First(); node; node = node->Next()) { + for (node = socks->First(); node; node = node->Next()) + { wxSocketBase* s = (wxSocketBase*)node->Data(); - - if (s == sock) { + + if (s == sock) + { delete node; sock->DestroyCallbacks(); sock->SetHandler(NULL); @@ -1424,8 +1778,8 @@ unsigned long wxSocketHandler::Count() const // --------- wxSocketHandler "big" wait functions --------------- // -------------------------------------------------------------- void handler_cbk(wxSocketBase& sock, - wxSocketBase::wxRequestEvent WXUNUSED(flags), - char *cdata) + wxSocketBase::wxRequestEvent WXUNUSED(flags), + char *cdata) { int *a_wait = (int *)cdata; @@ -1440,7 +1794,8 @@ int wxSocketHandler::Wait(long seconds, long microseconds) wxSockWakeUp s_wake(NULL, &on_wait, -2); wxNode *node; - for (node = socks->First(), i=0; node; node = node->Next(), i++) { + for (node = socks->First(), i=0; node; node = node->Next(), i++) + { wxSocketBase *sock = (wxSocketBase *)node->Data(); sock->SaveState(); @@ -1457,7 +1812,8 @@ int wxSocketHandler::Wait(long seconds, long microseconds) while (!on_wait) PROCESS_EVENTS(); - for (node = socks->First(), i=0; node; node = node->Next(), i++) { + for (node = socks->First(), i=0; node; node = node->Next(), i++) + { wxSocketBase *sock = (wxSocketBase *)node->Data(); sock->RestoreState(); @@ -1473,7 +1829,8 @@ void wxSocketHandler::YieldSock() { wxNode *node; - for (node = socks->First(); node; node = node->Next() ) { + for (node = socks->First(); node; node = node->Next() ) + { wxSocketBase *sock = (wxSocketBase *)node->Data(); sock->SaveState(); @@ -1491,7 +1848,7 @@ void wxSocketHandler::YieldSock() // --------- wxSocketHandler: create and register the socket ---- // -------------------------------------------------------------- wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr, - wxSocketBase::wxSockFlags flags) + wxSocketBase::wxSockFlags flags) { wxSocketServer *serv = new wxSocketServer(addr, flags); @@ -1511,6 +1868,7 @@ wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags) // -------------------------------------------------------------- // --------- wxSocketHandler: Windows specific methods ---------- // -------------------------------------------------------------- + UINT wxSocketHandler::NewMessage(wxSocketBase *sock) { internal->firstAvailableMsg++; @@ -1530,3 +1888,42 @@ HWND wxSocketHandler::GetHWND() const } #endif + +bool wxSocketModule::OnInit() +{ + wxSocketHandler::master = new wxSocketHandler(); + return TRUE; +} + +void wxSocketModule::OnExit() +{ + delete wxSocketHandler::master; + wxSocketHandler::master = NULL; +} + +#ifdef __WXMAC__ +void wxMacProcessSocketEvents() ; +void wxMacProcessEvents() +{ + wxMacProcessSocketEvents() ; + (*GUSISpin)(SP_MISC, 0) ; +} + +void wxMacProcessSocketEvents() +{ + while ( wxMacNetEventsTop != wxMacNetEventsBottom ) + { + // consume event at wxMacNetEventsBottom + wxMacSocketOnRequestProc(wxMacNetEventsReferences[wxMacNetEventsBottom] , wxMacNetEventsEvents[wxMacNetEventsBottom] ) ; + wxMacNetEventsBottom++ ; + if ( wxMacNetEventsBottom == kwxMacNetEventsMax ) + wxMacNetEventsBottom = 0 ; + } +} +#endif + +#endif + // __WXSTUBS__ + +#endif + // wxUSE_SOCKETS