#include "wx/private/fd.h"
#include "wx/private/socket.h"
#include "wx/unix/private/sockunix.h"
-#include "wx/private/gsocketiohandler.h"
#if defined(__VISAGECPP__)
#define BSD_SELECT /* use Berkeley Sockets select */
# define SOCKET_DEBUG(args)
#endif /* __GSOCKET_DEBUG__ */
-/* Constructors / Destructors for wxSocketImplUnix */
-
-wxSocketImplUnix::wxSocketImplUnix(wxSocketBase& wxsocket)
- : wxSocketImpl(wxsocket)
+/* static */
+wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
{
- m_fds[0] =
- m_fds[1] = -1;
-
- m_use_events = false;
+ return new wxSocketImplUnix(wxsocket);
}
+
/*
* Disallow further read/write operations on this socket, close
* the fd and disable all callbacks.
}
/* Wait for a connection (with timeout) */
- if (Input_Timeout() == wxSOCKET_TIMEDOUT)
+ if ( !BlockForInputWithTimeout() )
{
delete connection;
- /* m_error set by Input_Timeout */
return NULL;
}
#else
ioctl(connection->m_fd, FIONBIO, &arg);
#endif
- if (m_use_events)
- connection->Notify(true);
return connection;
}
-void wxSocketImplUnix::Notify(bool flag)
-{
- if (flag == m_use_events)
- return;
- m_use_events = flag;
- DoEnableEvents(flag);
-}
-
void wxSocketImplUnix::DoEnableEvents(bool flag)
{
wxSocketManager * const manager = wxSocketManager::Get();
*/
if ((err == EINPROGRESS) && (!m_non_blocking))
{
- if (Output_Timeout() == wxSOCKET_TIMEDOUT)
+ if ( !BlockForOutputWithTimeout() )
{
Close();
- /* m_error is set in Output_Timeout */
return wxSOCKET_TIMEDOUT;
}
- else
- {
- int error;
- SOCKOPTLEN_T len = sizeof(error);
- getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
- EnableEvents();
+ int error;
+ SOCKOPTLEN_T len = sizeof(error);
- if (!error)
- return wxSOCKET_NOERROR;
- }
+ getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
+ EnableEvents();
+
+ if (!error)
+ return wxSOCKET_NOERROR;
}
/* If connect failed with EINPROGRESS and the wxSocketImplUnix object
/* Generic IO */
/* Like recv(), send(), ... */
-int wxSocketImplUnix::Read(char *buffer, int size)
+int wxSocketImplUnix::Read(void *buffer, int size)
{
int ret;
DisableEvent(wxSOCKET_INPUT);
/* If the socket is blocking, wait for data (with a timeout) */
- if (Input_Timeout() == wxSOCKET_TIMEDOUT) {
+ if ( !BlockForInputWithTimeout() )
+ {
m_error = wxSOCKET_TIMEDOUT;
/* Don't return here immediately, otherwise socket events would not be
* re-enabled! */
if ((ret == 0) && m_stream)
{
/* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
- if (m_use_events)
- {
- m_detected = wxSOCKET_LOST_FLAG;
- Detected_Read();
- return 0;
- }
+ m_detected = wxSOCKET_LOST_FLAG;
+ OnReadWaiting();
+ return 0;
}
else if (ret == -1)
{
return ret;
}
-int wxSocketImplUnix::Write(const char *buffer, int size)
+int wxSocketImplUnix::Write(const void *buffer, int size)
{
int ret;
SOCKET_DEBUG(( "Write #2, size %d\n", size ));
/* If the socket is blocking, wait for writability (with a timeout) */
- if (Output_Timeout() == wxSOCKET_TIMEDOUT)
+ if ( !BlockForOutputWithTimeout() )
return -1;
SOCKET_DEBUG(( "Write #3, size %d\n", size ));
void wxSocketImplUnix::EnableEvent(wxSocketNotify event)
{
- if (m_use_events)
- {
- m_detected &= ~(1 << event);
- wxSocketManager::Get()->Install_Callback(this, event);
- }
+ m_detected &= ~(1 << event);
+ wxSocketManager::Get()->Install_Callback(this, event);
}
void wxSocketImplUnix::DisableEvent(wxSocketNotify event)
{
- if (m_use_events)
- {
- m_detected |= (1 << event);
- wxSocketManager::Get()->Uninstall_Callback(this, event);
- }
+ m_detected |= (1 << event);
+ wxSocketManager::Get()->Uninstall_Callback(this, event);
}
-/*
- * For blocking sockets, wait until data is available or
- * until timeout ellapses.
- */
-wxSocketError wxSocketImplUnix::Input_Timeout()
-{
- fd_set readfds;
- int ret;
-
- // Linux select() will overwrite the struct on return so make a copy
- struct timeval tv = m_timeout;
-
- if (!m_non_blocking)
- {
- wxFD_ZERO(&readfds);
- wxFD_SET(m_fd, &readfds);
- ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
- if (ret == 0)
- {
- SOCKET_DEBUG(( "Input_Timeout, select returned 0\n" ));
- m_error = wxSOCKET_TIMEDOUT;
- return wxSOCKET_TIMEDOUT;
- }
-
- if (ret == -1)
- {
- SOCKET_DEBUG(( "Input_Timeout, select returned -1\n" ));
- if (errno == EBADF) { SOCKET_DEBUG(( "Invalid file descriptor\n" )); }
- if (errno == EINTR) { SOCKET_DEBUG(( "A non blocked signal was caught\n" )); }
- if (errno == EINVAL) { SOCKET_DEBUG(( "The highest number descriptor is negative\n" )); }
- if (errno == ENOMEM) { SOCKET_DEBUG(( "Not enough memory\n" )); }
- m_error = wxSOCKET_TIMEDOUT;
- return wxSOCKET_TIMEDOUT;
- }
- }
-
- return wxSOCKET_NOERROR;
-}
-
-/*
- * For blocking sockets, wait until data can be sent without
- * blocking or until timeout ellapses.
- */
-wxSocketError wxSocketImplUnix::Output_Timeout()
-{
- fd_set writefds;
- int ret;
-
- // Linux select() will overwrite the struct on return so make a copy
- struct timeval tv = m_timeout;
-
- SOCKET_DEBUG( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
-
- if (!m_non_blocking)
- {
- wxFD_ZERO(&writefds);
- wxFD_SET(m_fd, &writefds);
- ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
- if (ret == 0)
- {
- SOCKET_DEBUG(( "Output_Timeout, select returned 0\n" ));
- m_error = wxSOCKET_TIMEDOUT;
- return wxSOCKET_TIMEDOUT;
- }
-
- if (ret == -1)
- {
- SOCKET_DEBUG(( "Output_Timeout, select returned -1\n" ));
- if (errno == EBADF) { SOCKET_DEBUG(( "Invalid file descriptor\n" )); }
- if (errno == EINTR) { SOCKET_DEBUG(( "A non blocked signal was caught\n" )); }
- if (errno == EINVAL) { SOCKET_DEBUG(( "The highest number descriptor is negative\n" )); }
- if (errno == ENOMEM) { SOCKET_DEBUG(( "Not enough memory\n" )); }
- m_error = wxSOCKET_TIMEDOUT;
- return wxSOCKET_TIMEDOUT;
- }
-
- if ( ! wxFD_ISSET(m_fd, &writefds) )
- {
- SOCKET_DEBUG(( "Output_Timeout is buggy!\n" ));
- }
- else
- {
- SOCKET_DEBUG(( "Output_Timeout seems correct\n" ));
- }
- }
- else
- {
- SOCKET_DEBUG(( "Output_Timeout, didn't try select!\n" ));
- }
-
- return wxSOCKET_NOERROR;
-}
-
-int wxSocketImplUnix::Recv_Stream(char *buffer, int size)
+int wxSocketImplUnix::Recv_Stream(void *buffer, int size)
{
int ret;
do
return ret;
}
-int wxSocketImplUnix::Recv_Dgram(char *buffer, int size)
+int wxSocketImplUnix::Recv_Dgram(void *buffer, int size)
{
wxSockAddr from;
WX_SOCKLEN_T fromlen = sizeof(from);
return ret;
}
-int wxSocketImplUnix::Send_Stream(const char *buffer, int size)
+int wxSocketImplUnix::Send_Stream(const void *buffer, int size)
{
int ret;
do
{
- ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
+ ret = send(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
}
while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
return ret;
}
-int wxSocketImplUnix::Send_Dgram(const char *buffer, int size)
+int wxSocketImplUnix::Send_Dgram(const void *buffer, int size)
{
struct sockaddr *addr;
int len, ret;
do
{
- ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
+ ret = sendto(m_fd, buffer, size, 0, addr, len);
}
while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
Shutdown();
}
-void wxSocketImplUnix::Detected_Read()
+void wxSocketImplUnix::OnReadWaiting()
{
char c;
- /* Safeguard against straggling call to Detected_Read */
if (m_fd == INVALID_SOCKET)
{
return;
}
}
-void wxSocketImplUnix::Detected_Write()
+void wxSocketImplUnix::OnWriteWaiting()
{
/* If we have already detected a LOST event, then don't try
* to do any further processing.
}
}
+void wxSocketImplUnix::OnExceptionWaiting()
+{
+ wxFAIL_MSG( "not supposed to be called" );
+}
+
/*
* -------------------------------------------------------------------------
* GAddress
return wxSOCKET_NOERROR;
}
#endif /* !defined(__VISAGECPP__) */
+
#endif /* wxUSE_SOCKETS */