X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ee4c6942b49d6ea13258437466c5735b1ba3ec6a..c71c744a5764596f392f6912eb32221109f11c60:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 9b7fbe2ecd..d3268834b2 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -11,8 +11,6 @@ //////////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation "socket.h" -// #pragma interface -// #pragma implementation "socket.cpp" #endif #ifdef __MWERKS__ @@ -26,6 +24,8 @@ typedef int socklen_t ; #pragma hdrstop #endif +#if wxUSE_SOCKETS + ///////////////////////////////////////////////////////////////////////////// // wxWindows headers ///////////////////////////////////////////////////////////////////////////// @@ -73,23 +73,24 @@ 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__ @@ -97,31 +98,32 @@ void wxMacProcessEvents() ; #include #include -#ifdef _MSC_VER -#include +#ifdef __VISUALC__ + #include #endif #if defined(__WXMOTIF__) || defined(__WXXT__) -#include - -///////////////////////////// -// Needs internal variables -///////////////////////////// -#ifdef __WXXT__ -#define Uses_XtIntrinsic -#endif + #include -#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" @@ -157,7 +159,7 @@ void wxMacProcessEvents() ; // 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; @@ -174,17 +176,21 @@ int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) #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 // -------------------------------------------------------------- @@ -201,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 @@ -353,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; } @@ -435,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; @@ -458,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) @@ -507,23 +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*. -// -// 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 defined(__LINUX__) -// #if 0 -#define wxSOCKET_INT socklen_t -#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 @@ -532,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; @@ -547,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); @@ -661,6 +678,20 @@ 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, @@ -688,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; } @@ -1099,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); @@ -1114,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; } @@ -1132,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; } @@ -1599,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; @@ -1868,3 +1917,6 @@ void wxMacProcessSocketEvents() #endif // __WXSTUBS__ + +#endif + // wxUSE_SOCKETS