X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8c14576d36a95b1572d26347111fa91871556d6e..6c41a418df66b66711eba536526a3085f690782e:/src/common/socket.cpp?ds=inline diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 82f44c03c5..d3268834b2 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -11,8 +11,10 @@ //////////////////////////////////////////////////////////////////////////////// #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". @@ -22,6 +24,8 @@ #pragma hdrstop #endif +#if wxUSE_SOCKETS + ///////////////////////////////////////////////////////////////////////////// // wxWindows headers ///////////////////////////////////////////////////////////////////////////// @@ -41,24 +45,52 @@ ///////////////////////////////////////////////////////////////////////////// // 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 + #include #endif // __WINDOWS__ #if defined(__UNIX__) #ifdef VMS -#include -#else -#include -#endif + #include +#else // !VMS + #include +#endif // VMS/!VMS + #include #include #include #ifdef sun -#include + #include #endif #endif // __UNIX__ @@ -66,31 +98,32 @@ #include #include -#ifdef _MSC_VER -#include +#ifdef __VISUALC__ + #include #endif #if defined(__WXMOTIF__) || defined(__WXXT__) -#include + #include -///////////////////////////// -// Needs internal variables -///////////////////////////// -#ifdef __WXXT__ -#define Uses_XtIntrinsic -#endif - -#endif + ///////////////////////////// + // Needs internal variables + ///////////////////////////// + #ifdef __WXXT__ + #define Uses_XtIntrinsic + #endif +#endif // Motif or Xt #if defined(__WXGTK__) -#include + #include #endif ///////////////////////////////////////////////////////////////////////////// // wxSocket headers ///////////////////////////////////////////////////////////////////////////// #include "wx/module.h" + #define WXSOCK_INTERNAL + #include "wx/sckaddr.h" #include "wx/socket.h" @@ -126,34 +159,38 @@ // 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 #if defined(__WINDOWS__) -#define PROCESS_EVENTS() wxYield() + #define PROCESS_EVENTS() wxYield() #elif defined(__WXXT__) || defined(__WXMOTIF__) -#define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll) + #define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll) #elif defined(__WXGTK__) -#define PROCESS_EVENTS() gtk_main_iteration() + #define PROCESS_EVENTS() gtk_main_iteration() #endif ///////////////////////////////////////////////////////////////////////////// // Some patch ///// END ///////////////////////////////////////////////////////////////////////////// +#ifdef GetClassInfo +#undef GetClassInfo +#endif + // -------------------------------------------------------------- // Module // -------------------------------------------------------------- @@ -170,12 +207,12 @@ public: // ClassInfos // -------------------------------------------------------------- #if !USE_SHARED_LIBRARY -IMPLEMENT_CLASS(wxSocketBase, wxObject) -IMPLEMENT_CLASS(wxSocketServer, wxSocketBase) -IMPLEMENT_CLASS(wxSocketClient, wxSocketBase) -IMPLEMENT_CLASS(wxSocketHandler, wxObject) -IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent) -IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule) + IMPLEMENT_CLASS(wxSocketBase, wxObject) + 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 @@ -218,7 +255,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), @@ -322,30 +359,42 @@ bool wxSocketBase::Close() 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) + count = GetPushback(buffer, nbytes, TRUE); + if (nbytes-count == 0) { - m_lcount = nbytes_old; + m_lcount = nbytes; return *this; } + buffer += count; + nbytes -= count; + m_lcount = 0; WantBuffer(buffer, nbytes, EVT_PEEK); + m_lcount += count; return *this; } @@ -404,6 +453,11 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) { SockMsg msg; + // 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; @@ -427,6 +481,10 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) Write((char *)&msg, sizeof(msg)); return *this; + +#ifdef __VISUALC__ + #pragma warning(default: 4310) +#endif // __VISUALC__ } wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes) @@ -476,14 +534,14 @@ 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*. -#if 0 -#define wxSOCKET_INT unsigned int -#else -#define wxSOCKET_INT int -#endif +// this is normally defined by configure, but if it wasn't try to do it here +#ifndef SOCKLEN_T + #if wxHAVE_GLIBC2 + typedef socklen_t SOCKLEN_T; + #else + typedef int SOCKLEN_T; + #endif +#endif // SOCKLEN_T // -------------------------------------------------------------- // wxSocketBase socket info functions @@ -492,7 +550,7 @@ void wxSocketBase::Discard() bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const { struct sockaddr my_addr; - wxSOCKET_INT len_addr = sizeof(my_addr); + SOCKLEN_T len_addr = (SOCKLEN_T)sizeof(my_addr); if (m_fd < 0) return FALSE; @@ -507,13 +565,12 @@ bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const { struct sockaddr my_addr; - wxSOCKET_INT len_addr = sizeof(my_addr); + SOCKLEN_T len_addr = (SOCKLEN_T)sizeof(my_addr); if (m_fd < 0) return FALSE; if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) - return FALSE; addr_man.Disassemble(&my_addr, len_addr); @@ -621,10 +678,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, @@ -648,6 +719,15 @@ static void wx_socket_read(gpointer client, gint fd, { 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; } @@ -668,10 +748,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; @@ -795,7 +875,6 @@ void wxSocketBase::SetupCallbacks() if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED)) return; - #if defined(__WXMOTIF__) || defined(__WXXT__) if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) { @@ -804,6 +883,7 @@ void wxSocketBase::SetupCallbacks() m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, (XtPointer *) XtInputReadMask, (XtInputCallbackProc) wx_socket_read, + (XtPointer) this); } } else @@ -894,6 +974,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; @@ -925,6 +1023,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) @@ -1027,7 +1139,10 @@ 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); @@ -1042,9 +1157,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; } @@ -1060,7 +1176,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; } @@ -1173,7 +1289,7 @@ void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes, } void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, - wxRequestEvent evt) + wxRequestEvent evt) { bool buf_timed_out; @@ -1230,7 +1346,7 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, // -------------------------------------------------------------- wxSocketServer::wxSocketServer(wxSockAddress& addr_man, - wxSockFlags flags) : + wxSockFlags flags) : wxSocketBase(flags, SOCK_SERVER) { m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0); @@ -1321,7 +1437,7 @@ void wxSocketServer::OnRequest(wxRequestEvent evt) // --------- wxSocketClient CONSTRUCTOR ------------------------- // -------------------------------------------------------------- wxSocketClient::wxSocketClient(wxSockFlags _flags) : - wxSocketBase(_flags, SOCK_CLIENT) + wxSocketBase(_flags, SOCK_CLIENT) { } @@ -1430,6 +1546,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[]; @@ -1439,8 +1613,8 @@ LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message, { if(message==WM_DESTROY) { - ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc); - return DefWindowProc(hWnd, message, wParam, lParam); + ::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); @@ -1469,7 +1643,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; @@ -1491,8 +1670,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) @@ -1592,8 +1771,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; @@ -1662,7 +1841,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); @@ -1715,5 +1894,29 @@ void wxSocketModule::OnExit() 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