Updated wxSocket documentation

Renamed GSOCK_TIMEOUT to GSOCK_TIMEDOUT
Added wxURL::ConvertFromURI
Use wxUSE_LIBGIF in imaggif.cpp and samples/html/test/test.cpp
Full implementation of "timeout"s in gsocket.c
Non-blocking WaitConnection()/Connect() are supported now.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3566 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
1999-09-05 10:23:22 +00:00
parent de3131e784
commit aa6d970619
18 changed files with 374 additions and 177 deletions

View File

@@ -50,25 +50,6 @@ Default destructor.
Delete all informations about the address. Delete all informations about the address.
%
% Build
%
\membersection{wxSockAddress::Build}
\func{void}{Build}{\param{struct sockaddr *\&}{ addr}, \param{size\_t\&}{ len}}
Build a coded socket address.
%
% Disassemble
%
\membersection{wxSockAddress::Disassemble}
\func{void}{Disassemble}{\param{struct sockaddr *}{addr}, \param{size\_t}{ len}}
Decode a socket address. {\bf Actually, you don't have to use this
function: only wxSocketBase use it.}
% %
% SockAddrLen % SockAddrLen
% %

View File

@@ -8,9 +8,31 @@
<wx/socket.h> <wx/socket.h>
\wxheading{See also} \wxheading{wxSocket errors}{wxsocketerrs}
GSocket for wxWindows \twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf wxSOCKET\_NOERROR}}{No error happened.}
\twocolitem{{\bf wxSOCKET\_INVOP}}{Invalid operation.}
\twocolitem{{\bf wxSOCKET\_IOERR}}{Input/Output error.}
\twocolitem{{\bf wxSOCKET\_INVADDR}}{Invalid address passed to wxSocket.}
\twocolitem{{\bf wxSOCKET\_INVSOCK}}{Invalid socket (uninitialized).}
\twocolitem{{\bf wxSOCKET\_NOHOST}}{No corresponding host.}
\twocolitem{{\bf wxSOCKET\_INVPORT}}{Invalid port.}
\twocolitem{{\bf wxSOCKET\_TRYAGAIN}}{The IO call has a timeout or is in non-blocking mode.}
\twocolitem{{\bf wxSOCKET\_MEMERR}}{Memory exhausted.}
\end{twocollist}%
\wxheading{wxSocket events}{wxsocketevents}
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf wxSOCKET\_INPUT}}{Some data are ready to be got.}
\twocolitem{{\bf wxSOCKET\_OUTPUT}}{The socket is ready to be written to.}
\twocolitem{{\bf wxSOCKET\_CONNECTION}}{Someone want to connect our server.}
\twocolitem{{\bf wxSOCKET\_LOST}}{The connection has been broken.}
\twocolitem{{\bf wxSOCKET\_MAX\_EVENT}}{This should never happen but the compiler may complain about it.}
\end{twocollist}%
% --------------------------------------------------------------------------- % ---------------------------------------------------------------------------
% Event handling % Event handling
@@ -78,10 +100,35 @@ Destroys the wxSocketBase object.
% %
\membersection{wxSocketBase::SetNotify}\label{wxsocketbasesetnotify} \membersection{wxSocketBase::SetNotify}\label{wxsocketbasesetnotify}
\func{void}{SetNotify}{\param{GSocketEventFlags}{ event_flags}} \func{void}{SetNotify}{\param{wxSocketEventFlags}{ event_flags}}
SetNotify setups which socket events are to be sent to the event handler. SetNotify setups which socket events are to be sent to the event handler.
For more information on socket events see GSocket events. You specify in parameters a mask of wxSocket events. The flags is:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf wxSOCKET\_INPUT\_FLAG}}{to receive wxSOCKET_INPUT}
\twocolitem{{\bf wxSOCKET\_OUTPUT\_FLAG}}{to receive wxSOCKET_OUTPUT}
\twocolitem{{\bf wxSOCKET\_CONNECTION\_FLAG}}{to receive wxSOCKET_CONNECTION}
\twocolitem{{\bf wxSOCKET\_LOST\_FLAG}}{to receive wxSOCKET_LOST}
\end{twocollist}%
For example:
\begin{verbatim}
sock.SetNotify(wxSOCKET\_INPUT\_FLAG | wxSOCKET\_LOST\_FLAG);
\end{verbatim}
In this example, the user will be notified about incoming socket datas and
a broken connection.
For more information on socket events see \helpref{wxSocket events}{wxsocketevents}.
%
% SetTimeout
%
\membersection{wxSocketBase::SetTimeout}{wxsocketbasesettimeout}
\func{void}{SetTimeout}{\param{int }{seconds}}
This function sets the socket timeout in seconds.
% %
% Notify % Notify
@@ -136,15 +183,15 @@ Returns TRUE if the socket mustn't wait.
\membersection{wxSocketBase::LastCount}\label{wxsocketbaselastcount} \membersection{wxSocketBase::LastCount}\label{wxsocketbaselastcount}
\constfunc{size\_t}{LastCount}{\void} \constfunc{wxUint32}{LastCount}{\void}
Returns the number of bytes read or written by the last IO call. Returns the number of bytes read or written by the last IO call.
\membersection{wxSocketBase::LastError}\label{wxsocketbaselasterror} \membersection{wxSocketBase::LastError}\label{wxsocketbaselasterror}
\constfunc{GSocketError}{LastError}{\void} \constfunc{wxSocketError}{LastError}{\void}
Returns an error in the GSocket format. See GSocket errors. Returns the last occured wxSocket error. See \helpref{wxSocket errors}{wxsocketerrs}.
% --------------------------------------------------------------------------- % ---------------------------------------------------------------------------
% IO calls % IO calls
@@ -154,7 +201,7 @@ Returns an error in the GSocket format. See GSocket errors.
% %
\membersection{wxSocketBase::Peek}\label{wxsocketbasepeek} \membersection{wxSocketBase::Peek}\label{wxsocketbasepeek}
\func{wxSocketBase\&}{Peek}{\param{char *}{ buffer}, \param{size\_t}{ nbytes}} \func{wxSocketBase\&}{Peek}{\param{char *}{ buffer}, \param{wxUint32}{ nbytes}}
This function peeks a buffer of {\it nbytes} bytes from the socket. Peeking a buffer This function peeks a buffer of {\it nbytes} bytes from the socket. Peeking a buffer
doesn't delete it from the system socket in-queue. doesn't delete it from the system socket in-queue.
@@ -180,7 +227,7 @@ Returns a reference to the current object.
% %
\membersection{wxSocketBase::Read}\label{wxsocketbaseread} \membersection{wxSocketBase::Read}\label{wxsocketbaseread}
\func{wxSocketBase\&}{Read}{\param{char *}{ buffer}, \param{size\_t}{ nbytes}} \func{wxSocketBase\&}{Read}{\param{char *}{ buffer}, \param{wxUint32}{ nbytes}}
This function reads a buffer of {\it nbytes} bytes from the socket. This function reads a buffer of {\it nbytes} bytes from the socket.
@@ -219,7 +266,7 @@ This remark is also valid for all IO call.
% %
\membersection{wxSocketBase::Write}\label{wxsocketbasewrite} \membersection{wxSocketBase::Write}\label{wxsocketbasewrite}
\func{wxSocketBase\&}{Write}{\param{const char *}{ buffer}, \param{size\_t}{ nbytes}} \func{wxSocketBase\&}{Write}{\param{const char *}{ buffer}, \param{wxUint32}{ nbytes}}
This function writes a buffer of {\it nbytes} bytes from the socket. This function writes a buffer of {\it nbytes} bytes from the socket.
@@ -256,7 +303,7 @@ Returns a reference to the current object.
% %
\membersection{wxSocketBase::WriteMsg}\label{wxsocketbasewritemsg} \membersection{wxSocketBase::WriteMsg}\label{wxsocketbasewritemsg}
\func{wxSocketBase\&}{WriteMsg}{\param{const char *}{ buffer}, \param{size\_t}{ nbytes}} \func{wxSocketBase\&}{WriteMsg}{\param{const char *}{ buffer}, \param{wxUint32}{ nbytes}}
This function writes a buffer of {\it nbytes} bytes from the socket. But it This function writes a buffer of {\it nbytes} bytes from the socket. But it
writes a short header before so that ReadMsg can alloc the right size for writes a short header before so that ReadMsg can alloc the right size for
@@ -284,7 +331,7 @@ Returns a reference to the current object.
% %
\membersection{wxSocketBase::ReadMsg}\label{wxsocketbasereadmsg} \membersection{wxSocketBase::ReadMsg}\label{wxsocketbasereadmsg}
\func{wxSocketBase\&}{ReadMsg}{\param{char *}{ buffer}, \param{size\_t}{ nbytes}} \func{wxSocketBase\&}{ReadMsg}{\param{char *}{ buffer}, \param{wxUint32}{ nbytes}}
This function reads a buffer sent by WriteMsg on a socket. If the buffer passed This function reads a buffer sent by WriteMsg on a socket. If the buffer passed
to the function isn't big enough, the function filled it and then discard the to the function isn't big enough, the function filled it and then discard the
@@ -312,7 +359,7 @@ Returns a reference to the current object.
% %
\membersection{wxSocketBase::Unread}\label{wxsocketbaseunread} \membersection{wxSocketBase::Unread}\label{wxsocketbaseunread}
\func{wxSocketBase\&}{Unread}{\param{const char *}{ buffer}, \param{size\_t}{ nbytes}} \func{wxSocketBase\&}{Unread}{\param{const char *}{ buffer}, \param{wxUint32}{ nbytes}}
This function unreads a buffer. It means that the buffer is put in the top This function unreads a buffer. It means that the buffer is put in the top
of the incoming queue. But, it is put also at the end of all unread buffers. of the incoming queue. But, it is put also at the end of all unread buffers.
@@ -349,7 +396,7 @@ doesn't wait.
% --------------------------------------------------------------------------- % ---------------------------------------------------------------------------
\membersection{wxSocketBase::Wait}\label{wxsocketbasewait} \membersection{wxSocketBase::Wait}\label{wxsocketbasewait}
\func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} \func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}}
This function waits for an event: it could be an incoming byte, the possibility This function waits for an event: it could be an incoming byte, the possibility
for the client to write, a lost connection, an incoming connection, an for the client to write, a lost connection, an incoming connection, an
@@ -359,7 +406,7 @@ established connection.
\docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.}
\docparam{microsecond}{Number of microseconds to wait.} \docparam{millisecond}{Number of milliseconds to wait.}
\wxheading{Return value} \wxheading{Return value}
@@ -376,7 +423,7 @@ Returns TRUE if an event occured, FALSE if the timeout was reached.
% %
\membersection{wxSocketBase::WaitForRead}\label{wxsocketbasewaitforread} \membersection{wxSocketBase::WaitForRead}\label{wxsocketbasewaitforread}
\func{bool}{WaitForRead}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} \func{bool}{WaitForRead}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}}
This function waits for a read event. This function waits for a read event.
@@ -384,7 +431,7 @@ This function waits for a read event.
\docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.}
\docparam{microsecond}{Number of microseconds to wait.} \docparam{millisecond}{Number of milliseconds to wait.}
\wxheading{Return value} \wxheading{Return value}
@@ -401,7 +448,7 @@ Returns TRUE if a byte arrived, FALSE if the timeout was reached.
% %
\membersection{wxSocketBase::WaitForWrite}\label{wxsocketbasewaitforwrite} \membersection{wxSocketBase::WaitForWrite}\label{wxsocketbasewaitforwrite}
\func{bool}{WaitForWrite}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} \func{bool}{WaitForWrite}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}}
This function waits for a write event. This function waits for a write event.
@@ -409,7 +456,7 @@ This function waits for a write event.
\docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.}
\docparam{microsecond}{Number of microseconds to wait.} \docparam{millisecond}{Number of milliseconds to wait.}
\wxheading{Return value} \wxheading{Return value}
@@ -426,7 +473,7 @@ Returns TRUE if a write event occured, FALSE if the timeout was reached.
% %
\membersection{wxSocketBase::WaitForLost}\label{wxsocketbasewaitforlost} \membersection{wxSocketBase::WaitForLost}\label{wxsocketbasewaitforlost}
\func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} \func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}}
This function waits for a "lost" event. For instance, the peer may have closed This function waits for a "lost" event. For instance, the peer may have closed
the connection, or the connection may have been broken. the connection, or the connection may have been broken.
@@ -435,7 +482,7 @@ the connection, or the connection may have been broken.
\docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.}
\docparam{microsecond}{Number of microseconds to wait.} \docparam{millisecond}{Number of milliseconds to wait.}
\wxheading{Return value} \wxheading{Return value}
@@ -475,7 +522,49 @@ actually it saves all flags and the state of the asynchronous callbacks.
\wxheading{See also} \wxheading{See also}
%
% SaveState
%
\helpref{wxSocketBase::RestoreState}{wxsocketbaserestorestate} \helpref{wxSocketBase::RestoreState}{wxsocketbaserestorestate}
\membersection{wxSocketBase::RestoreState}\label{wxsocketbaserestorestate}
\func{void}{RestoreState}{\void}
This function restores the previous state of the socket (include flags,
notify flags, notify state, C callback function and data).
\wxheading{See also}
\helpref{wxSocketBase::SaveState}{wxsocketbasesavestate}
%
% GetLocal
%
\membersection{wxSocketBase::GetLocal}{wxsocketbasegetlocal}
\constfunc{bool}{GetLocal}{\param{wxSockAddress\& }{addr_man}}
This function returns the local address field of the socket. The local
address field contains the complete local address of the socket (local
address, local port, ...).
\wxheading{Return value}
It returns TRUE if no errors happened, FALSE otherwise.
%
% GetPeer
%
\membersection{wxSocketBase::GetPeer}{wxsocketbasegetlocal}
\constfunc{bool}{GetPeer}{\param{wxSockAddress\& }{addr_man}}
This function returns the peer address field of the socket. The peer
address field contains the complete peer host address of the socket
(address, port, ...).
\wxheading{Return value}
It returns TRUE if no errors happened, FALSE otherwise.
% --------------------------------------------------------------------------- % ---------------------------------------------------------------------------
% Socket callbacks % Socket callbacks
@@ -494,7 +583,43 @@ Sets an event handler to be called when a socket event occured.
\wxheading{See also} \wxheading{See also}
\helpref{wxSocketBase::SetNotify}{wxsocketbasesetnotify}
\helpref{wxSocketBase::Notify}{wxsocketbasenotify}
\helpref{wxSocketEvent}{wxsocketevent} \helpref{wxSocketEvent}{wxsocketevent}
\helpref{wxEvtHandler}{wxevthandler}
\membersection{wxSocketBase::Callback}\label{wxsocketbasecallback}
\func{wxSocketBase::wxSockCbk}{Callback}{\param{wxSocketBase::wxSockCbk}{ callback}}
wxSocket event handler can call C callback. This function allows you to set it.
The format of the callback is as followed:
\begin{verbatim}
void SocketCallback(wxSocketBase& sock,wxSocketNotify evt,char *cdata);
\end{verbatim}
The first parameter reminds you of the caller socket. The second parameter
informs you about the current event (See \helpref{wxSocket events}{wxsocketevents}).
The third parameters is the client data you specified using \helpref{CallbackData}{wxsocketcallbackdata}.
\wxheading{Return value}
It returns the previous callback.
\wxheading{See also}
\helpref{wxSocketBase::SetNotify}{wxsocketbasesetnotify}
\helpref{wxSocketBase::Notify}{wxsocketbasenotify}
\membersection{wxSocketBase::CallbackData}\label{wxsocketcallbackdata}
\func{char *}{CallbackData}{\param{char *}{cdata}}
This function sets the the client data which will be passed to a \helpref{C callback}{wxsocketcallback}.
\wxheading{Return value}
This function returns the old value of the client data pointer.
% --------------------------------------------------------------------------- % ---------------------------------------------------------------------------
% CLASS wxSocketClient % CLASS wxSocketClient
@@ -563,7 +688,7 @@ Returns TRUE if the connection is established and no error occurs.
% %
\membersection{wxSocketClient::WaitOnConnect}\label{wxsocketclientwaitonconnect} \membersection{wxSocketClient::WaitOnConnect}\label{wxsocketclientwaitonconnect}
\func{bool}{WaitOnConnect}{\param{long}{ seconds = -1}, \param{long}{ microseconds = 0}} \func{bool}{WaitOnConnect}{\param{long}{ seconds = -1}, \param{long}{ milliseconds = 0}}
Wait for a "connect" event. Wait for a "connect" event.
@@ -612,7 +737,7 @@ Constructor.
\membersection{wxSocketEvent::SocketEvent}\label{wxsocketeventsocketevent} \membersection{wxSocketEvent::SocketEvent}\label{wxsocketeventsocketevent}
\constfunc{GSocketEvent}{SocketEvent}{\void} \constfunc{wxSocketNotify}{SocketEvent}{\void}
Returns the socket event type. Returns the socket event type.

View File

@@ -51,7 +51,7 @@ typedef enum {
GSOCK_NOHOST, GSOCK_NOHOST,
GSOCK_INVPORT, GSOCK_INVPORT,
GSOCK_WOULDBLOCK, GSOCK_WOULDBLOCK,
GSOCK_TIMEOUT, GSOCK_TIMEDOUT,
GSOCK_MEMERR GSOCK_MEMERR
} GSocketError; } GSocketError;

View File

@@ -159,6 +159,8 @@ public:
// wxGIFHandler // wxGIFHandler
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if wxUSE_LIBGIF
class WXDLLEXPORT wxGIFHandler : public wxImageHandler class WXDLLEXPORT wxGIFHandler : public wxImageHandler
{ {
DECLARE_DYNAMIC_CLASS(wxGIFHandler) DECLARE_DYNAMIC_CLASS(wxGIFHandler)
@@ -180,6 +182,8 @@ public:
#endif #endif
}; };
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxPNMHandler // wxPNMHandler
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -61,6 +61,10 @@
* Use libjpeg * Use libjpeg
*/ */
#define wxUSE_LIBJPEG 0 #define wxUSE_LIBJPEG 0
/*
* Use gif
*/
#define wxUSE_LIBGIF 0
/* /*
* Use iODBC * Use iODBC
*/ */

View File

@@ -190,6 +190,8 @@
// Use PNG bitmap code // Use PNG bitmap code
#define wxUSE_LIBJPEG 0 #define wxUSE_LIBJPEG 0
// Use JPEG bitmap code // Use JPEG bitmap code
#define wxUSE_LIBGIF 0
// Use GIF bitmap code
#define wxUSE_SERIAL 0 #define wxUSE_SERIAL 0
// Use serialization (requires utils/serialize) // Use serialization (requires utils/serialize)
#define wxUSE_DYNLIB_CLASS 0 #define wxUSE_DYNLIB_CLASS 0

View File

@@ -60,9 +60,6 @@ public:
wxString Hostname(); wxString Hostname();
unsigned short Service(); unsigned short Service();
void Build(struct sockaddr*& addr, size_t& len);
void Disassemble(struct sockaddr *addr, size_t len);
inline int Type() { return wxSockAddress::IPV4; } inline int Type() { return wxSockAddress::IPV4; }
}; };

View File

@@ -62,7 +62,7 @@ typedef enum {
wxSOCKET_NOHOST = GSOCK_NOHOST, wxSOCKET_NOHOST = GSOCK_NOHOST,
wxSOCKET_INVPORT = GSOCK_INVPORT, wxSOCKET_INVPORT = GSOCK_INVPORT,
wxSOCKET_WOULDBLOCK = GSOCK_WOULDBLOCK, wxSOCKET_WOULDBLOCK = GSOCK_WOULDBLOCK,
wxSOCKET_TIMEOUT = GSOCK_TIMEOUT, wxSOCKET_TIMEDOUT = GSOCK_TIMEDOUT,
wxSOCKET_MEMERR = GSOCK_MEMERR wxSOCKET_MEMERR = GSOCK_MEMERR
} wxSocketError; } wxSocketError;
@@ -89,12 +89,12 @@ protected:
wxSockFlags m_flags; // wxSocket flags wxSockFlags m_flags; // wxSocket flags
wxSockType m_type; // wxSocket type wxSockType m_type; // wxSocket type
wxSocketEventFlags m_neededreq; // Specify which requet signals we need wxSocketEventFlags m_neededreq; // Specify which requet signals we need
size_t m_lcount; // Last IO request size wxUint32 m_lcount; // Last IO request size
unsigned long m_timeout; // IO timeout value unsigned long m_timeout; // IO timeout value
char *m_unread; // Pushback buffer char *m_unread; // Pushback buffer
size_t m_unrd_size; // Pushback buffer size wxUint32 m_unrd_size; // Pushback buffer size
size_t m_unrd_cur; // Pushback pointer wxUint32 m_unrd_cur; // Pushback pointer
wxSockCbk m_cbk; // C callback wxSockCbk m_cbk; // C callback
char *m_cdata; // C callback data char *m_cdata; // C callback data
@@ -108,7 +108,7 @@ protected:
DEFER_READ, DEFER_WRITE, NO_DEFER DEFER_READ, DEFER_WRITE, NO_DEFER
} m_defering; // Defering state } m_defering; // Defering state
char *m_defer_buffer; // Defering target buffer char *m_defer_buffer; // Defering target buffer
size_t m_defer_nbytes; // Defering buffer size wxUint32 m_defer_nbytes; // Defering buffer size
wxTimer *m_defer_timer; // Timer for defering mode wxTimer *m_defer_timer; // Timer for defering mode
wxList m_states; // Stack of states wxList m_states; // Stack of states
@@ -119,17 +119,17 @@ public:
virtual bool Close(); virtual bool Close();
// Base IO // Base IO
wxSocketBase& Peek(char* buffer, size_t nbytes); wxSocketBase& Peek(char* buffer, wxUint32 nbytes);
wxSocketBase& Read(char* buffer, size_t nbytes); wxSocketBase& Read(char* buffer, wxUint32 nbytes);
wxSocketBase& Write(const char *buffer, size_t nbytes); wxSocketBase& Write(const char *buffer, wxUint32 nbytes);
wxSocketBase& Unread(const char *buffer, size_t nbytes); wxSocketBase& Unread(const char *buffer, wxUint32 nbytes);
wxSocketBase& ReadMsg(char *buffer, size_t nbytes); wxSocketBase& ReadMsg(char *buffer, wxUint32 nbytes);
wxSocketBase& WriteMsg(const char *buffer, size_t nbytes); wxSocketBase& WriteMsg(const char *buffer, wxUint32 nbytes);
void Discard(); void Discard();
// Try not to use this two methods (they sould be protected) // Try not to use this two methods (they sould be protected)
void CreatePushbackAfter(const char *buffer, size_t size); void CreatePushbackAfter(const char *buffer, wxUint32 size);
void CreatePushbackBefore(const char *buffer, size_t size); void CreatePushbackBefore(const char *buffer, wxUint32 size);
// Status // Status
inline bool Ok() const { return (m_socket != NULL); }; inline bool Ok() const { return (m_socket != NULL); };
@@ -139,21 +139,21 @@ public:
inline bool IsDisconnected() const { return !IsConnected(); }; inline bool IsDisconnected() const { return !IsConnected(); };
inline bool IsNoWait() const { return ((m_flags & NOWAIT) != 0); }; inline bool IsNoWait() const { return ((m_flags & NOWAIT) != 0); };
bool IsData() const; bool IsData() const;
inline size_t LastCount() const { return m_lcount; } inline wxUint32 LastCount() const { return m_lcount; }
inline wxSocketError LastError() const { return (wxSocketError)GSocket_GetError(m_socket); } inline wxSocketError LastError() const { return (wxSocketError)GSocket_GetError(m_socket); }
inline wxSockType GetType() const { return m_type; } inline wxSockType GetType() const { return m_type; }
void SetFlags(wxSockFlags _flags); void SetFlags(wxSockFlags _flags);
wxSockFlags GetFlags() const; wxSockFlags GetFlags() const;
inline void SetTimeout(unsigned long sec) { m_timeout = sec; } void SetTimeout(unsigned long sec);
// seconds = -1 means infinite wait // seconds = -1 means infinite wait
// seconds = 0 means no wait // seconds = 0 means no wait
// seconds > 0 means specified wait // seconds > 0 means specified wait
bool Wait(long seconds = -1, long microseconds = 0); bool Wait(long seconds = -1, long milliseconds = 0);
bool WaitForRead(long seconds = -1, long microseconds = 0); bool WaitForRead(long seconds = -1, long milliseconds = 0);
bool WaitForWrite(long seconds = -1, long microseconds = 0); bool WaitForWrite(long seconds = -1, long milliseconds = 0);
bool WaitForLost(long seconds = -1, long microseconds = 0); bool WaitForLost(long seconds = -1, long milliseconds = 0);
// Save the current state of Socket // Save the current state of Socket
void SaveState(); void SaveState();
@@ -200,14 +200,14 @@ public:
protected: protected:
#endif #endif
bool _Wait(long seconds, long microseconds, int type); bool _Wait(long seconds, long milliseconds, int type);
int DeferRead(char *buffer, size_t nbytes); int DeferRead(char *buffer, wxUint32 nbytes);
int DeferWrite(const char *buffer, size_t nbytes); int DeferWrite(const char *buffer, wxUint32 nbytes);
void DoDefer(wxSocketNotify evt); void DoDefer(wxSocketNotify evt);
// Pushback library // Pushback library
size_t GetPushback(char *buffer, size_t size, bool peek); wxUint32 GetPushback(char *buffer, wxUint32 size, bool peek);
}; };
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -237,7 +237,7 @@ public:
virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE); virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE);
bool WaitOnConnect(long seconds = -1, long microseconds = 0); bool WaitOnConnect(long seconds = -1, long milliseconds = 0);
virtual void OnRequest(wxSocketNotify flags); virtual void OnRequest(wxSocketNotify flags);
}; };

View File

@@ -120,6 +120,10 @@
// Use zlib for compression in streams and PNG code // Use zlib for compression in streams and PNG code
#define wxUSE_LIBPNG 1 #define wxUSE_LIBPNG 1
// Use PNG bitmap code // Use PNG bitmap code
#define wxUSE_LIBPNG 0
// Use JPEG bitmap code
#define wxUSE_LIBGIF 0
// Use GIF bitmap code
#define wxUSE_STD_IOSTREAM 1 #define wxUSE_STD_IOSTREAM 1
// Use standard C++ streams if 1. If 0, use wxWin // Use standard C++ streams if 1. If 0, use wxWin
// streams implementation. // streams implementation.

View File

@@ -82,6 +82,7 @@ public:
#endif #endif
static wxString ConvertToValidURI(const wxString& uri); static wxString ConvertToValidURI(const wxString& uri);
static wxString ConvertFromURI(const wxString& uri);
}; };
#endif #endif

View File

@@ -114,6 +114,9 @@
#if wxUSE_LIBJPEG #if wxUSE_LIBJPEG
wxImage::AddHandler(new wxJPEGHandler); wxImage::AddHandler(new wxJPEGHandler);
#endif #endif
#if wxUSE_LIBGIF
wxImage::AddHandler(new wxGIFHandler);
#endif
// Create the main application window // Create the main application window
MyFrame *frame = new MyFrame("wxHtmlWindow testing application", MyFrame *frame = new MyFrame("wxHtmlWindow testing application",
wxPoint(50, 50), wxSize(640, 480)); wxPoint(50, 50), wxSize(640, 480));

View File

@@ -340,7 +340,7 @@ wxInputStream *wxFTP::GetInputStream(const wxString& path)
return NULL; return NULL;
} }
tmp_str = _T("RETR ") + path; tmp_str = _T("RETR ") + wxURL::ConvertFromURI(path);
if (!SendCommand(tmp_str, '1')) if (!SendCommand(tmp_str, '1'))
return NULL; return NULL;

View File

@@ -289,7 +289,7 @@ size_t wxHTTPStream::OnSysRead(void *buffer, size_t bufsize)
bool wxHTTP::Abort(void) bool wxHTTP::Abort(void)
{ {
bool ret, connected; bool ret;
ret = wxSocketClient::Close(); ret = wxSocketClient::Close();

View File

@@ -23,7 +23,7 @@
# include "wx/defs.h" # include "wx/defs.h"
#endif #endif
#if 1 // change this to #if wxUSE_GIF #if wxUSE_LIBGIF
#include "wx/image.h" #include "wx/image.h"
#include "wx/gifdecod.h" #include "wx/gifdecod.h"

View File

@@ -139,7 +139,7 @@ class _wxSocketInternalTimer: public wxTimer {
} }
}; };
int wxSocketBase::DeferRead(char *buffer, size_t nbytes) int wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
{ {
wxSocketEventFlags old_event_flags; wxSocketEventFlags old_event_flags;
bool old_notify_state; bool old_notify_state;
@@ -187,7 +187,7 @@ int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
return nbytes-m_defer_nbytes; return nbytes-m_defer_nbytes;
} }
wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
{ {
int ret = 1; int ret = 1;
@@ -232,7 +232,7 @@ wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
return *this; return *this;
} }
wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
{ {
unsigned long len, len2, sig; unsigned long len, len2, sig;
struct { struct {
@@ -241,23 +241,23 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
} msg; } msg;
// sig should be an explicit 32-bit unsigned integer; I've seen // sig should be an explicit 32-bit unsigned integer; I've seen
// compilers in which size_t was actually a 16-bit unsigned integer // compilers in which wxUint32 was actually a 16-bit unsigned integer
Read((char *)&msg, sizeof(msg)); Read((char *)&msg, sizeof(msg));
if (m_lcount != sizeof(msg)) if (m_lcount != sizeof(msg))
return *this; return *this;
sig = msg.sig[0] & 0xff; sig = msg.sig[0] & 0xff;
sig |= (size_t)(msg.sig[1] & 0xff) << 8; sig |= (wxUint32)(msg.sig[1] & 0xff) << 8;
sig |= (size_t)(msg.sig[2] & 0xff) << 16; sig |= (wxUint32)(msg.sig[2] & 0xff) << 16;
sig |= (size_t)(msg.sig[3] & 0xff) << 24; sig |= (wxUint32)(msg.sig[3] & 0xff) << 24;
if (sig != 0xfeeddead) if (sig != 0xfeeddead)
return *this; return *this;
len = msg.len[0] & 0xff; len = msg.len[0] & 0xff;
len |= (size_t)(msg.len[1] & 0xff) << 8; len |= (wxUint32)(msg.len[1] & 0xff) << 8;
len |= (size_t)(msg.len[2] & 0xff) << 16; len |= (wxUint32)(msg.len[2] & 0xff) << 16;
len |= (size_t)(msg.len[3] & 0xff) << 24; len |= (wxUint32)(msg.len[3] & 0xff) << 24;
// len2 is incorrectly computed in the original; this sequence is // len2 is incorrectly computed in the original; this sequence is
// the fix // the fix
@@ -279,9 +279,9 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
return *this; return *this;
sig = msg.sig[0] & 0xff; sig = msg.sig[0] & 0xff;
sig |= (size_t)(msg.sig[1] & 0xff) << 8; sig |= (wxUint32)(msg.sig[1] & 0xff) << 8;
sig |= (size_t)(msg.sig[2] & 0xff) << 16; sig |= (wxUint32)(msg.sig[2] & 0xff) << 16;
sig |= (size_t)(msg.sig[3] & 0xff) << 24; sig |= (wxUint32)(msg.sig[3] & 0xff) << 24;
// ERROR // ERROR
if (sig != 0xdeadfeed) if (sig != 0xdeadfeed)
@@ -290,7 +290,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
return *this; return *this;
} }
wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
{ {
Read(buffer, nbytes); Read(buffer, nbytes);
CreatePushbackAfter(buffer, nbytes); CreatePushbackAfter(buffer, nbytes);
@@ -298,7 +298,7 @@ wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
return *this; return *this;
} }
int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes) int wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
{ {
wxSocketEventFlags old_event_flags; wxSocketEventFlags old_event_flags;
bool old_notify_state; bool old_notify_state;
@@ -343,7 +343,7 @@ int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
return nbytes-m_defer_nbytes; return nbytes-m_defer_nbytes;
} }
wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes) wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
{ {
int ret; int ret;
@@ -358,7 +358,7 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
return *this; return *this;
} }
wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
{ {
struct { struct {
char sig[4]; char sig[4];
@@ -399,7 +399,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
#endif // __VISUALC__ #endif // __VISUALC__
} }
wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes) wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes)
{ {
m_lcount = 0; m_lcount = 0;
if (nbytes != 0) { if (nbytes != 0) {
@@ -461,7 +461,7 @@ void wxSocketBase::Discard()
{ {
#define MAX_BUFSIZE (10*1024) #define MAX_BUFSIZE (10*1024)
char *my_data = new char[MAX_BUFSIZE]; char *my_data = new char[MAX_BUFSIZE];
size_t recv_size = MAX_BUFSIZE; wxUint32 recv_size = MAX_BUFSIZE;
SaveState(); SaveState();
SetFlags(NOWAIT | SPEED); SetFlags(NOWAIT | SPEED);
@@ -742,7 +742,7 @@ void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
// --------- wxSocketBase pushback library ---------------------- // --------- wxSocketBase pushback library ----------------------
// -------------------------------------------------------------- // --------------------------------------------------------------
void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) void wxSocketBase::CreatePushbackAfter(const char *buffer, wxUint32 size)
{ {
char *curr_pos; char *curr_pos;
@@ -757,7 +757,7 @@ void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
m_unrd_size += size; m_unrd_size += size;
} }
void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size) void wxSocketBase::CreatePushbackBefore(const char *buffer, wxUint32 size)
{ {
if (m_unread == NULL) if (m_unread == NULL)
m_unread = (char *)malloc(size); m_unread = (char *)malloc(size);
@@ -776,7 +776,7 @@ void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
memcpy(m_unread, buffer, size); memcpy(m_unread, buffer, size);
} }
size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek) wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 size, bool peek)
{ {
if (!m_unrd_size) if (!m_unrd_size)
return 0; return 0;

View File

@@ -385,3 +385,33 @@ wxString wxURL::ConvertToValidURI(const wxString& uri)
return out_str; return out_str;
} }
wxString wxURL::ConvertFromURI(const wxString& uri)
{
int code;
int i;
wxString new_uri;
new_uri.Empty();
i = 0;
while (i<uri.Len()) {
if (uri[i] == _T('%')) {
i++;
if (uri[i] >= _T('A') && uri[i] <= _T('F'))
code = (uri[i] - _T('A') + 10) * 16;
else
code = (uri[i] - _T('0')) * 16;
i++;
if (uri[i] >= _T('A') && uri[i] <= _T('F'))
code += (uri[i] - _T('A')) + 10;
else
code += (uri[i] - _T('0'));
i++;
new_uri += (wxChar)code;
continue;
}
new_uri += uri[i];
i++;
}
return new_uri;
}

View File

@@ -57,13 +57,34 @@
#endif #endif
#if !defined(__LINUX__) && !defined(__FREEBSD__) #define MASK_SIGNAL() \
# define CAN_USE_TIMEOUT { \
#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) void (*old_handler)(int); \
# if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1) \
# define CAN_USE_TIMEOUT old_handler = signal(SIGPIPE, SIG_IGN);
# endif
#endif #define UNMASK_SIGNAL() \
signal(SIGPIPE, old_handler); \
}
#define ENABLE_TIMEOUT(socket) \
{ \
struct itimerval old_ival, new_ival; \
void (*old_timer_sig)(int); \
\
old_timer_sig = signal(SIGALRM, SIG_DFL); \
siginterrupt(SIGALRM, 1); \
new_ival.it_value.tv_sec = socket->m_timeout / 1000; \
new_ival.it_value.tv_usec = (socket->m_timeout % 1000) * 1000; \
new_ival.it_interval.tv_sec = 0; \
new_ival.it_interval.tv_usec = 0; \
setitimer(ITIMER_REAL, &new_ival, &old_ival);
#define DISABLE_TIMEOUT(socket) \
signal(SIGALRM, old_timer_sig); \
siginterrupt(SIGALRM, 0); \
setitimer(ITIMER_REAL, &old_ival, NULL); \
}
/* Global initialisers */ /* Global initialisers */
@@ -102,6 +123,7 @@ GSocket *GSocket_new()
socket->m_non_blocking = FALSE; socket->m_non_blocking = FALSE;
socket->m_timeout = 10*60*1000; socket->m_timeout = 10*60*1000;
/* 10 minutes * 60 sec * 1000 millisec */ /* 10 minutes * 60 sec * 1000 millisec */
socket->m_establishing = FALSE;
/* We initialize the GUI specific entries here */ /* We initialize the GUI specific entries here */
_GSocket_GUI_Init(socket); _GSocket_GUI_Init(socket);
@@ -197,6 +219,7 @@ GAddress *GSocket_GetLocal(GSocket *socket)
GAddress *address; GAddress *address;
struct sockaddr addr; struct sockaddr addr;
SOCKLEN_T size; SOCKLEN_T size;
GSocketError err;
assert(socket != NULL); assert(socket != NULL);
@@ -220,7 +243,8 @@ GAddress *GSocket_GetLocal(GSocket *socket)
socket->m_error = GSOCK_MEMERR; socket->m_error = GSOCK_MEMERR;
return NULL; return NULL;
} }
if (_GAddress_translate_from(address, &addr, size) != GSOCK_NOERROR) { socket->m_error = _GAddress_translate_from(address, &addr, size);
if (socket->m_error != GSOCK_NOERROR) {
GAddress_destroy(address); GAddress_destroy(address);
return NULL; return NULL;
} }
@@ -317,12 +341,29 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
/* Create a GSocket object for the new connection */ /* Create a GSocket object for the new connection */
connection = GSocket_new(); connection = GSocket_new();
if (!connection) {
connection->m_error = GSOCK_MEMERR;
return NULL;
}
/* Accept the incoming connection */ /* Accept the incoming connection */
ENABLE_TIMEOUT(connection);
connection->m_fd = accept(socket->m_fd, NULL, NULL); connection->m_fd = accept(socket->m_fd, NULL, NULL);
DISABLE_TIMEOUT(connection);
if (connection->m_fd == -1) { if (connection->m_fd == -1) {
GSocket_destroy(connection); GSocket_destroy(connection);
socket->m_error = GSOCK_IOERR; switch(errno) {
case EINTR:
case ETIMEDOUT:
connection->m_error = GSOCK_TIMEDOUT;
break;
case EWOULDBLOCK:
connection->m_error = GSOCK_WOULDBLOCK;
break;
default:
connection->m_error = GSOCK_IOERR;
break;
}
return NULL; return NULL;
} }
@@ -357,6 +398,11 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
/* Create the socket */ /* Create the socket */
sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0); sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
if (sck->m_fd < 0) {
sck->m_error = GSOCK_IOERR;
return GSOCK_IOERR;
}
/* Bind it to the LOCAL address */ /* Bind it to the LOCAL address */
if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) { if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
close(sck->m_fd); close(sck->m_fd);
@@ -380,7 +426,7 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
*/ */
GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
{ {
int type; int type, err;
assert(sck != NULL); assert(sck != NULL);
@@ -411,22 +457,34 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
return GSOCK_IOERR; return GSOCK_IOERR;
} }
GSocket_SetNonBlocking(sck, sck->m_non_blocking);
GSocket_SetTimeout(sck, sck->m_timeout);
/* Connect it to the PEER address */ /* Connect it to the PEER address */
if (connect(sck->m_fd, sck->m_peer->m_addr, ENABLE_TIMEOUT(sck);
sck->m_peer->m_len) != 0) { err = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
DISABLE_TIMEOUT(sck);
if (err != 0 && errno != EINPROGRESS) {
close(sck->m_fd); close(sck->m_fd);
sck->m_fd = -1; sck->m_fd = -1;
switch (errno) {
case EINTR:
case ETIMEDOUT:
sck->m_error = GSOCK_TIMEDOUT;
break;
default:
sck->m_error = GSOCK_IOERR; sck->m_error = GSOCK_IOERR;
break;
}
return GSOCK_IOERR; return GSOCK_IOERR;
} }
/* It is not a server */ /* It is not a server */
sck->m_server = FALSE; sck->m_server = FALSE;
sck->m_establishing = (errno == EINPROGRESS);
GSocket_SetNonBlocking(sck, sck->m_non_blocking); return (sck->m_establishing) ? GSOCK_WOULDBLOCK : GSOCK_NOERROR;
GSocket_SetTimeout(sck, sck->m_timeout);
return GSOCK_NOERROR;
} }
/* Generic IO */ /* Generic IO */
@@ -516,25 +574,6 @@ void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
assert(socket != NULL); assert(socket != NULL);
socket->m_timeout = millisec; socket->m_timeout = millisec;
/* Neither GLIBC 2.0 nor the kernel 2.0.36 define SO_SNDTIMEO or
SO_RCVTIMEO. The man pages, that these flags should exist but
are read only. RR. */
/* OK, restrict this to GLIBC 2.1. GL. */
/* Anyway, they seem to pose problems: I need to know the socket level and
it varies (may be SOL_TCP, SOL_UDP, ...). I disables this and use the
other solution. GL. */
#if 0
#ifdef CAN_USE_TIMEOUT
if (socket->m_fd != -1) {
struct timeval tval;
tval.tv_sec = millisec / 1000;
tval.tv_usec = (millisec % 1000) * 1000;
setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
}
#endif
#endif
} }
/* /*
@@ -605,7 +644,7 @@ void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
} }
} }
#define CALL_FALLBACK(socket, event) \ #define CALL_CALLBACK(socket, event) \
if (socket->m_iocalls[event] && \ if (socket->m_iocalls[event] && \
socket->m_cbacks[event]) {\ socket->m_cbacks[event]) {\
_GSocket_Disable(socket, event); \ _GSocket_Disable(socket, event); \
@@ -613,35 +652,6 @@ if (socket->m_iocalls[event] && \
socket->m_data[event]); \ socket->m_data[event]); \
} }
#define MASK_SIGNAL() \
{ \
void (*old_handler)(int); \
\
old_handler = signal(SIGPIPE, SIG_IGN);
#define UNMASK_SIGNAL() \
signal(SIGPIPE, old_handler); \
}
#define ENABLE_TIMEOUT(socket) \
{ \
struct itimerval old_ival, new_ival; \
void (*old_timer_sig)(int); \
\
old_timer_sig = signal(SIGALRM, SIG_DFL); \
siginterrupt(SIGALRM, 1); \
new_ival.it_value.tv_sec = socket->m_timeout / 1000; \
new_ival.it_value.tv_usec = (socket->m_timeout % 1000) * 1000; \
new_ival.it_interval.tv_sec = 0; \
new_ival.it_interval.tv_usec = 0; \
setitimer(ITIMER_REAL, &new_ival, &old_ival);
#define DISABLE_TIMEOUT(socket) \
signal(SIGALRM, old_timer_sig); \
siginterrupt(SIGALRM, 0); \
setitimer(ITIMER_REAL, &old_ival, NULL); \
}
void _GSocket_Enable(GSocket *socket, GSocketEvent event) void _GSocket_Enable(GSocket *socket, GSocketEvent event)
{ {
socket->m_iocalls[event] = TRUE; socket->m_iocalls[event] = TRUE;
@@ -666,7 +676,8 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
DISABLE_TIMEOUT(socket); DISABLE_TIMEOUT(socket);
UNMASK_SIGNAL(); UNMASK_SIGNAL();
if (ret == -1 && errno != EWOULDBLOCK) { if (ret == -1 &&
errno != ETIMEDOUT && errno != EWOULDBLOCK && errno != EINTR) {
socket->m_error = GSOCK_IOERR; socket->m_error = GSOCK_IOERR;
return -1; return -1;
} }
@@ -674,6 +685,10 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
socket->m_error = GSOCK_WOULDBLOCK; socket->m_error = GSOCK_WOULDBLOCK;
return -1; return -1;
} }
if (errno == ETIMEDOUT || errno == EINTR) {
socket->m_error = GSOCK_TIMEDOUT;
return -1;
}
return ret; return ret;
} }
@@ -682,6 +697,7 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
struct sockaddr from; struct sockaddr from;
SOCKLEN_T fromlen; SOCKLEN_T fromlen;
int ret; int ret;
GSocketError err;
fromlen = sizeof(from); fromlen = sizeof(from);
@@ -690,7 +706,7 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen); ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
DISABLE_TIMEOUT(socket); DISABLE_TIMEOUT(socket);
UNMASK_SIGNAL(); UNMASK_SIGNAL();
if (ret == -1 && errno != EWOULDBLOCK) { if (ret == -1 && errno != EWOULDBLOCK && errno != EINTR && errno != ETIMEDOUT) {
socket->m_error = GSOCK_IOERR; socket->m_error = GSOCK_IOERR;
return -1; return -1;
} }
@@ -698,6 +714,10 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
socket->m_error = GSOCK_WOULDBLOCK; socket->m_error = GSOCK_WOULDBLOCK;
return -1; return -1;
} }
if (errno == ETIMEDOUT || errno == EINTR) {
socket->m_error = GSOCK_TIMEDOUT;
return -1;
}
/* Translate a system address into a GSocket address */ /* Translate a system address into a GSocket address */
if (!socket->m_peer) { if (!socket->m_peer) {
@@ -707,8 +727,13 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
return -1; return -1;
} }
} }
if (_GAddress_translate_from(socket->m_peer, &from, fromlen) != GSOCK_NOERROR) err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
if (err != GSOCK_NOERROR) {
GAddress_destroy(socket->m_peer);
socket->m_peer = NULL;
socket->m_error = err;
return -1; return -1;
}
return ret; return ret;
} }
@@ -716,13 +741,14 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size) int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
{ {
int ret; int ret;
GSocketError err;
MASK_SIGNAL(); MASK_SIGNAL();
ENABLE_TIMEOUT(socket); ENABLE_TIMEOUT(socket);
ret = send(socket->m_fd, buffer, size, 0); ret = send(socket->m_fd, buffer, size, 0);
DISABLE_TIMEOUT(socket); DISABLE_TIMEOUT(socket);
UNMASK_SIGNAL(); UNMASK_SIGNAL();
if (ret == -1 && errno != EWOULDBLOCK) { if (ret == -1 && errno != EWOULDBLOCK && errno != ETIMEDOUT && errno != EINTR) {
socket->m_error = GSOCK_IOERR; socket->m_error = GSOCK_IOERR;
return -1; return -1;
} }
@@ -730,6 +756,10 @@ int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
socket->m_error = GSOCK_WOULDBLOCK; socket->m_error = GSOCK_WOULDBLOCK;
return -1; return -1;
} }
if (errno == ETIMEDOUT || errno == EINTR) {
socket->m_error = GSOCK_TIMEDOUT;
return -1;
}
return ret; return ret;
} }
@@ -737,13 +767,16 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
{ {
struct sockaddr *addr; struct sockaddr *addr;
int len, ret; int len, ret;
GSocketError err;
if (!socket->m_peer) { if (!socket->m_peer) {
socket->m_error = GSOCK_INVADDR; socket->m_error = GSOCK_INVADDR;
return -1; return -1;
} }
if (_GAddress_translate_to(socket->m_peer, &addr, &len) != GSOCK_NOERROR) { err = _GAddress_translate_to(socket->m_peer, &addr, &len);
if (err != GSOCK_NOERROR) {
socket->m_error = err;
return -1; return -1;
} }
@@ -777,26 +810,38 @@ void _GSocket_Detected_Read(GSocket *socket)
ret = recv(socket->m_fd, &c, 1, MSG_PEEK); ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
if (ret < 0 && socket->m_server) { if (ret < 0 && socket->m_server) {
CALL_FALLBACK(socket, GSOCK_CONNECTION); CALL_CALLBACK(socket, GSOCK_CONNECTION);
return; return;
} }
if (ret > 0) { if (ret > 0) {
CALL_FALLBACK(socket, GSOCK_INPUT); CALL_CALLBACK(socket, GSOCK_INPUT);
} else { } else {
CALL_FALLBACK(socket, GSOCK_LOST); CALL_CALLBACK(socket, GSOCK_LOST);
} }
} }
} }
void _GSocket_Detected_Write(GSocket *socket) void _GSocket_Detected_Write(GSocket *socket)
{ {
CALL_FALLBACK(socket, GSOCK_OUTPUT); if (socket->m_establishing) {
} int error, len;
#undef CALL_FALLBACK len = sizeof(error);
#undef MASK_SIGNAL
#undef UNMASK_SIGNAL socket->m_establishing = FALSE;
getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len);
if (error) {
socket->m_error = GSOCK_IOERR;
GSocket_Shutdown(socket);
} else
socket->m_error = GSOCK_NOERROR;
CALL_CALLBACK(socket, GSOCK_CONNECTION);
} else
CALL_CALLBACK(socket, GSOCK_OUTPUT);
}
/* /*
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------

View File

@@ -26,6 +26,7 @@ struct _GSocket {
GSocketError m_error; GSocketError m_error;
bool m_non_blocking, m_server, m_stream, m_oriented; bool m_non_blocking, m_server, m_stream, m_oriented;
bool m_establishing;
unsigned long m_timeout; unsigned long m_timeout;
/* Callbacks */ /* Callbacks */