X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e5e41feafa1e1fe338ccc3fca63894b920f0ce96..d1af991f497a5e95d8f8ab15a4e4a4a4c375928f:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 67113941b3..052078b3b4 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -35,6 +35,11 @@ typedef int socklen_t ; #include #include +// IRIX requires bstring.h be included to use select() +#ifdef sgi + #include +#endif // IRIX + // Not enough OS behaviour defined for wxStubs #ifndef __WXSTUBS__ @@ -209,8 +214,6 @@ wxSocketBase::~wxSocketBase() // First, close the file descriptor. Close(); - m_internal->FinalizeSocket(); - if (m_unread) free(m_unread); // Unregister from the handler database. @@ -228,8 +231,8 @@ bool wxSocketBase::Close() { if (m_fd != INVALID_SOCKET) { - // Pause all running socket thread. - m_internal->PauseSocket(); + if (m_notify_state == TRUE) + Notify(FALSE); // Shutdown the connection. shutdown(m_fd, 2); @@ -262,6 +265,65 @@ wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) return *this; } +wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) +{ + unsigned long len, len2, sig; + struct { + char sig[4]; + char len[4]; + } msg; + + // sig should be an explicit 32-bit unsigned integer; I've seen + // compilers in which size_t was actually a 16-bit unsigned integer + + Read((char *)&msg, sizeof(msg)); + if (m_lcount != sizeof(msg)) + return *this; + + sig = msg.sig[0] & 0xff; + sig |= (size_t)(msg.sig[1] & 0xff) << 8; + sig |= (size_t)(msg.sig[2] & 0xff) << 16; + sig |= (size_t)(msg.sig[3] & 0xff) << 24; + + if (sig != 0xfeeddead) + return *this; + len = msg.len[0] & 0xff; + len |= (size_t)(msg.len[1] & 0xff) << 8; + len |= (size_t)(msg.len[2] & 0xff) << 16; + len |= (size_t)(msg.len[3] & 0xff) << 24; + + // len2 is incorrectly computed in the original; this sequence is + // the fix + if (len > nbytes) { + len2 = len - nbytes; + len = nbytes; + } + else + len2 = 0; + + // the "len &&" in the following statement is necessary so that + // we don't attempt to read (and possibly hang the system) + // if the message was zero bytes long + if (len && Read(buffer, len).LastCount() != len) + return *this; + if (len2 && (Read(NULL, len2).LastCount() != len2)) + return *this; + if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg)) + return *this; + + sig = msg.sig[0] & 0xff; + sig |= (size_t)(msg.sig[1] & 0xff) << 8; + sig |= (size_t)(msg.sig[2] & 0xff) << 16; + sig |= (size_t)(msg.sig[3] & 0xff) << 24; +// ERROR +// we return *this either way, so a smart optimizer will +// optimize the following sequence out; I'm leaving it in anyway + if (sig != 0xdeadfeed) + return *this; + + return *this; +} + wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) { m_lcount = GetPushback(buffer, nbytes, TRUE); @@ -284,9 +346,54 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes) return *this; } +wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) +{ + struct { + char sig[4]; + char len[4]; + } 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; + 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; + + 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) { - CreatePushbackAfter(buffer, nbytes); + m_lcount = 0; + if (nbytes != 0) { + CreatePushbackAfter(buffer, nbytes); + m_lcount = nbytes; + } return *this; } @@ -306,7 +413,7 @@ bool wxSocketBase::IsData() const tv.tv_usec = 0; FD_ZERO(&sock_set); FD_SET(m_fd, &sock_set); - select(FD_SETSIZE, &sock_set, NULL, NULL, &tv); + select(m_fd+1, &sock_set, NULL, NULL, &tv); m_internal->ReleaseFD(); @@ -426,7 +533,9 @@ void wxSocketBase::RestoreState() state = (SocketState *)node->Data(); SetFlags(state->socket_flags); + m_internal->AcquireData(); m_neededreq = state->evt_notify_state; + m_internal->ReleaseData(); m_cbk = state->c_callback; m_cdata = state->c_callback_data; Notify(state->notify_state); @@ -545,20 +654,25 @@ void wxSocketBase::SetNotify(wxRequestNotify flags) if (m_type != SOCK_SERVER) flags &= ~REQ_ACCEPT; + m_internal->AcquireData(); m_neededreq = flags; + m_internal->ReleaseData(); if (m_neededreq == 0) - m_internal->DisableWaiter(); + m_internal->StopWaiter(); else Notify(m_notify_state); } void wxSocketBase::Notify(bool notify) { + m_notify_state = notify; + if (m_fd == INVALID_SOCKET) + return; + if (notify) - m_internal->EnableWaiter(); + m_internal->ResumeWaiter(); else - m_internal->DisableWaiter(); - m_notify_state = notify; + m_internal->StopWaiter(); } void wxSocketBase::OnRequest(wxRequestEvent req_evt) @@ -574,7 +688,7 @@ void wxSocketBase::OnRequest(wxRequestEvent req_evt) // OldOnNotify(req_evt); // We disable the event reporting. - SetNotify(m_neededreq & ~notify); + m_neededreq &= ~notify; } } @@ -586,14 +700,14 @@ wxSocketEvent::wxSocketEvent(int id) SetEventType(type); } -wxObject *wxSocketEvent::Clone() const +void wxSocketEvent::CopyObject(wxObject& obj_d) const { - wxSocketEvent *event = (wxSocketEvent *)wxEvent::Clone(); + wxSocketEvent *event = (wxSocketEvent *)&obj_d; + + wxEvent::CopyObject(obj_d); event->m_skevt = m_skevt; event->m_socket = m_socket; - - return event; } void wxSocketBase::OldOnNotify(wxRequestEvent evt) @@ -679,7 +793,6 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, SockRequest *buf = new SockRequest; SaveState(); - m_internal->DisableWaiter(); buf->buffer = buffer; buf->size = nbytes; buf->done = FALSE; @@ -690,10 +803,10 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, buf->timeout = 1000; buf_timed_out = FALSE; - if (m_flags & SPEED) + if ((m_flags & SPEED) != 0) m_internal->QueueRequest(buf, FALSE); else - if (m_flags & NOWAIT) + if ((m_flags & NOWAIT) != 0) m_internal->QueueRequest(buf, TRUE); else m_internal->QueueRequest(buf, TRUE); @@ -735,7 +848,9 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man, return; } - m_internal->InitializeSocket(); + m_internal->SetFD(m_fd); + + Notify(TRUE); } // -------------------------------------------------------------- @@ -746,8 +861,12 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock) { int fd2; - if ((fd2 = accept(m_fd, 0, 0)) < 0) + m_internal->AcquireFD(); + if ((fd2 = accept(m_fd, 0, 0)) < 0) { + m_internal->ReleaseFD(); return FALSE; + } + m_internal->ReleaseFD(); struct linger linger; linger.l_onoff = 0; @@ -762,7 +881,9 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock) sock.m_fd = fd2; sock.m_connected = TRUE; - sock.m_internal->InitializeSocket(); + sock.m_internal->SetFD(fd2); + + sock.m_internal->ResumeWaiter(); return TRUE; } @@ -844,9 +965,7 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) ) if (connect(m_fd, remote, len) != 0) return FALSE; - // Initializes the background threads ... - // -------------------------------------- - m_internal->InitializeSocket(); + m_internal->SetFD(m_fd); // Enables bg events. // ------------------ @@ -872,11 +991,10 @@ void wxSocketClient::OnRequest(wxRequestEvent evt) { if (m_connected) { - SetNotify(m_neededreq & ~REQ_CONNECT); + m_neededreq &= ~REQ_CONNECT; return; } m_connected = TRUE; - OldOnNotify(EVT_CONNECT); return; } wxSocketBase::OnRequest(evt);