From 5c9eff305505d6e3a63026c542004d518d997d2a Mon Sep 17 00:00:00 2001 From: Guillermo Rodriguez Garcia Date: Thu, 16 Mar 2000 21:57:20 +0000 Subject: [PATCH] Removed bool params and retvalues in GSocket interface to avoid mismatch between C-compiled bools in gsocket and C++ real bools as passed by wxSocket git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6776 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gsocket.h | 17 +------ include/wx/msw/gsockmsw.h | 12 +++++ include/wx/socket.h | 22 +++++++-- include/wx/unix/gsockunx.h | 12 +++++ src/common/socket.cpp | 94 ++++++++++++++++++++------------------ src/msw/gsocket.c | 2 +- src/msw/gsockmsw.c | 2 +- src/unix/gsocket.c | 9 ++-- 8 files changed, 100 insertions(+), 70 deletions(-) diff --git a/include/wx/gsocket.h b/include/wx/gsocket.h index 2e3f86d256..7ec123fd4d 100644 --- a/include/wx/gsocket.h +++ b/include/wx/gsocket.h @@ -20,19 +20,6 @@ #include #include -#if !defined(__cplusplus) -typedef unsigned int bool; -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - - #ifdef __cplusplus extern "C" { #endif @@ -91,7 +78,7 @@ typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event, /* Global initializers */ /* GSocket_Init() must be called at the beginning */ -bool GSocket_Init(void); +int GSocket_Init(void); /* GSocket_Cleanup() must be called at the end */ void GSocket_Cleanup(void); @@ -231,7 +218,7 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags); * Sets the socket to non-blocking mode. All IO calls will return * immediately. */ -void GSocket_SetNonBlocking(GSocket *socket, bool non_block); +void GSocket_SetNonBlocking(GSocket *socket, int non_block); /* GSocket_SetTimeout: * Sets the timeout for blocking calls. Time is expressed in diff --git a/include/wx/msw/gsockmsw.h b/include/wx/msw/gsockmsw.h index 91a126119e..d51271fc3f 100644 --- a/include/wx/msw/gsockmsw.h +++ b/include/wx/msw/gsockmsw.h @@ -28,6 +28,18 @@ extern "C" { #endif +#if !defined(__cplusplus) +typedef int bool; +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + /* Definition of GSocket */ struct _GSocket { diff --git a/include/wx/socket.h b/include/wx/socket.h index 7b8aef933d..0b955b128d 100644 --- a/include/wx/socket.h +++ b/include/wx/socket.h @@ -58,8 +58,9 @@ typedef GSocketEventFlags wxSocketEventFlags; enum wxSocketError { + // from GSocket wxSOCKET_NOERROR = GSOCK_NOERROR, - wxSOCKET_INPOP = GSOCK_INVOP, + wxSOCKET_INVOP = GSOCK_INVOP, wxSOCKET_IOERR = GSOCK_IOERR, wxSOCKET_INVADDR = GSOCK_INVADDR, wxSOCKET_INVSOCK = GSOCK_INVSOCK, @@ -67,7 +68,10 @@ enum wxSocketError wxSOCKET_INVPORT = GSOCK_INVPORT, wxSOCKET_WOULDBLOCK = GSOCK_WOULDBLOCK, wxSOCKET_TIMEDOUT = GSOCK_TIMEDOUT, - wxSOCKET_MEMERR = GSOCK_MEMERR + wxSOCKET_MEMERR = GSOCK_MEMERR, + + // wxSocket-specific (not yet implemented) + wxSOCKET_DUMMY }; enum @@ -191,7 +195,7 @@ public: // Implementation from now on // -------------------------- - // do not use, should be private + // do not use, should be private (called from GSocket) void OnRequest(wxSocketNotify notify); // do not use, not documented nor supported @@ -206,13 +210,14 @@ private: // low level IO wxUint32 _Read(void* buffer, wxUint32 nbytes); wxUint32 _Write(const void *buffer, wxUint32 nbytes); - bool _Wait(long seconds, long milliseconds, wxSocketEventFlags flags); + bool _Wait(long seconds, long milliseconds, wxSocketEventFlags flags); // pushback buffer - void Pushback(const void *buffer, wxUint32 size); + void Pushback(const void *buffer, wxUint32 size); wxUint32 GetPushback(void *buffer, wxUint32 size, bool peek); private: + // socket GSocket *m_socket; // GSocket wxSocketType m_type; // wxSocket type @@ -223,6 +228,7 @@ private: bool m_reading; // busy reading? bool m_writing; // busy writing? bool m_error; // did last IO call fail? + wxSocketError m_lasterror; // last error (not cleared on success) wxUint32 m_lcount; // last IO transaction size unsigned long m_timeout; // IO timeout value wxList m_states; // stack of states @@ -304,6 +310,10 @@ public: wxDatagramSocket& SendTo( wxSockAddress& addr, const void* buf, wxUint32 nBytes ); + +/* TODO: + bool Connect(wxSockAddress& addr); +*/ }; @@ -323,8 +333,10 @@ public: void *GetClientData() const { return m_clientData; } // backwards compatibility +#if WXWIN_COMPATIBILITY_2 wxSocketNotify SocketEvent() const { return m_event; } wxSocketBase *Socket() const { return (wxSocketBase *) GetEventObject(); } +#endif // WXWIN_COMPATIBILITY_2 void CopyObject(wxObject& object_dest) const; diff --git a/include/wx/unix/gsockunx.h b/include/wx/unix/gsockunx.h index 741b27327c..e44fef0eb3 100644 --- a/include/wx/unix/gsockunx.h +++ b/include/wx/unix/gsockunx.h @@ -26,6 +26,18 @@ extern "C" { #endif /* __cplusplus */ +#if !defined(__cplusplus) +typedef int bool; +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + /* Definition of GSocket */ struct _GSocket diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 5036742c4d..a3eec9aae2 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -255,26 +255,27 @@ wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes) // Possible combinations (they are checked in this order) // wxSOCKET_NOWAIT - // wxSOCKET_WAITALL | wxSOCKET_BLOCK - // wxSOCKET_WAITALL + // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK) // wxSOCKET_BLOCK // wxSOCKET_NONE // if (m_flags & wxSOCKET_NOWAIT) { - GSocket_SetNonBlocking(m_socket, TRUE); + GSocket_SetNonBlocking(m_socket, 1); ret = GSocket_Read(m_socket, (char *)buffer, nbytes); - GSocket_SetNonBlocking(m_socket, FALSE); + GSocket_SetNonBlocking(m_socket, 0); if (ret > 0) total += ret; } - else if (m_flags & wxSOCKET_WAITALL) + else { - while (ret > 0 && nbytes > 0) + bool more = TRUE; + + while (more) { - if (!(m_flags & wxSOCKET_BLOCK) && !WaitForRead()) - break; + if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() ) + break; ret = GSocket_Read(m_socket, (char *)buffer, nbytes); @@ -284,16 +285,12 @@ wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes) nbytes -= ret; buffer = (char *)buffer + ret; } - } - } - else - { - if ((m_flags & wxSOCKET_BLOCK) || WaitForRead()) - { - ret = GSocket_Read(m_socket, (char *)buffer, nbytes); - if (ret > 0) - total += ret; + // If we got here and wxSOCKET_WAITALL is not set, we can leave + // now. Otherwise, wait until we recv all the data or until there + // is an error. + // + more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL)); } } @@ -329,7 +326,7 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes) if (sig != 0xfeeddead) { - wxLogWarning( _("wxSocket: invalid signature in ReadMsg.")); + wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); goto exit; } @@ -383,7 +380,7 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes) if (sig != 0xdeadfeed) { - wxLogWarning( _("wxSocket: invalid signature in ReadMsg.")); + wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); goto exit; } @@ -443,51 +440,60 @@ wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes) wxUint32 total = 0; int ret = 1; - // If the socket is invalid, return immediately - if (!m_socket) + // If the socket is invalid or parameters are ill, return immediately + if (!m_socket || !buffer || !nbytes) return 0; // Possible combinations (they are checked in this order) // wxSOCKET_NOWAIT - // wxSOCKET_WAITALL | wxSOCKET_BLOCK - // wxSOCKET_WAITALL + // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK) // wxSOCKET_BLOCK // wxSOCKET_NONE // if (m_flags & wxSOCKET_NOWAIT) { - GSocket_SetNonBlocking(m_socket, TRUE); + GSocket_SetNonBlocking(m_socket, 1); ret = GSocket_Write(m_socket, (const char *)buffer, nbytes); - GSocket_SetNonBlocking(m_socket, FALSE); + GSocket_SetNonBlocking(m_socket, 0); if (ret > 0) total = ret; } - else if (m_flags & wxSOCKET_WAITALL) + else { - while (ret > 0 && nbytes > 0) + bool more = TRUE; + + while (more) { - if (!(m_flags & wxSOCKET_BLOCK) && !WaitForWrite()) - break; + if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() ) + break; ret = GSocket_Write(m_socket, (const char *)buffer, nbytes); - + if (ret > 0) { total += ret; nbytes -= ret; buffer = (const char *)buffer + ret; } - } - } - else - { - if ((m_flags & wxSOCKET_BLOCK) || WaitForWrite()) - { - ret = GSocket_Write(m_socket, (const char *)buffer, nbytes); - if (ret > 0) - total = ret; + // Yes, this can happen even when the socket selects as writable! + // (probably due to a buggy kernel; Linux 2.0.36 seems to do this). + // Fake it so that we stay in the loop, but do it only for ret < 0, + // as ret == 0 means that the socket is closed. I'm not applying + // this hack for read calls as it seems unnecessary there. + // + if ((ret < 0) && (GSocket_GetError(m_socket) == GSOCK_WOULDBLOCK)) + { + wxLogDebug(_("wxSocket: working around select() bug in Write.")); + continue; + } + + // If we got here and wxSOCKET_WAITALL is not set, we can leave + // now. Otherwise, wait until we send all the data or until there + // is an error. + // + more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL)); } } @@ -906,7 +912,7 @@ void wxSocketBase::OnRequest(wxSocketNotify notification) case GSOCK_CONNECTION: flag = GSOCK_CONNECTION_FLAG; break; case GSOCK_LOST: flag = GSOCK_LOST_FLAG; break; default: - wxLogWarning( _("wxSocket: unknown event!.")); + wxLogWarning(_("wxSocket: unknown event!.")); return; } @@ -1047,12 +1053,12 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait) // again. if (!wait) - GSocket_SetNonBlocking(m_socket, TRUE); + GSocket_SetNonBlocking(m_socket, 1); child_socket = GSocket_WaitConnection(m_socket); if (!wait) - GSocket_SetNonBlocking(m_socket, FALSE); + GSocket_SetNonBlocking(m_socket, 0); if (!child_socket) return FALSE; @@ -1135,13 +1141,13 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) // again. if (!wait) - GSocket_SetNonBlocking(m_socket, TRUE); + GSocket_SetNonBlocking(m_socket, 1); GSocket_SetPeer(m_socket, addr_man.GetAddress()); err = GSocket_Connect(m_socket, GSOCK_STREAMED); if (!wait) - GSocket_SetNonBlocking(m_socket, FALSE); + GSocket_SetNonBlocking(m_socket, 0); if (err != GSOCK_NOERROR) { diff --git a/src/msw/gsocket.c b/src/msw/gsocket.c index d789711c1d..47325c4320 100644 --- a/src/msw/gsocket.c +++ b/src/msw/gsocket.c @@ -768,7 +768,7 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) * Sets the socket to non-blocking mode. All IO calls will return * immediately. */ -void GSocket_SetNonBlocking(GSocket *socket, bool non_block) +void GSocket_SetNonBlocking(GSocket *socket, int non_block) { assert(socket != NULL); diff --git a/src/msw/gsockmsw.c b/src/msw/gsockmsw.c index e853b8b1bd..d8ea3ae3c5 100644 --- a/src/msw/gsockmsw.c +++ b/src/msw/gsockmsw.c @@ -82,7 +82,7 @@ static int firstAvailable; /* Global initializers */ -bool GSocket_Init(void) +int GSocket_Init(void) { WSADATA wsaData; WNDCLASS winClass; diff --git a/src/unix/gsocket.c b/src/unix/gsocket.c index 81d56e818f..9fa98f1f47 100644 --- a/src/unix/gsocket.c +++ b/src/unix/gsocket.c @@ -25,7 +25,8 @@ #ifdef __VMS__ #include -struct sockaddr_un { +struct sockaddr_un +{ u_char sun_len; /* sockaddr len including null */ u_char sun_family; /* AF_UNIX */ char sun_path[108]; /* path name (gag) */ @@ -122,9 +123,9 @@ struct sockaddr_un { /* Global initialisers */ -bool GSocket_Init(void) +int GSocket_Init(void) { - return TRUE; + return 1; } void GSocket_Cleanup(void) @@ -895,7 +896,7 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) * Sets the socket to non-blocking mode. All IO calls will return * immediately. */ -void GSocket_SetNonBlocking(GSocket *socket, bool non_block) +void GSocket_SetNonBlocking(GSocket *socket, int non_block) { assert(socket != NULL); -- 2.45.2