--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket)
+ * Name: gsocket.h
+ * Purpose: GSocket include file (system independent)
+ * CVSID: $Id$
+ * Log: $Log$
+ * Log: Revision 1.1 1999/07/22 17:51:47 GL
+ * Log: Added GSocket for Unix (only GTK for the moment)
+ * Log: Updated wxSocket to use GSocket API
+ * Log: Added a progress bar to client.cpp
+ * Log: Added CopyTo to wxMemoryOutputStream to copy the internal buffer to a specified buffer.
+ * Log: Various changes/fixes to the high-level protocols FTP/HTTP
+ * Log: Various Unicode fixes
+ * Log: Removed sckint.*
+ * Log:
+ * Log: Revision 1.2 1999/07/18 15:54:28 guilhem
+ * Log: Copyright, etc.
+ * Log:
+ * -------------------------------------------------------------------------
+ */
+#ifndef __GSOCKET_H
+#define __GSOCKET_H
+
+#include <sys/types.h>
+
+#if !defined(__cplusplus)
+
+typedef int bool;
+
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef struct _GSocket GSocket;
+typedef struct _GAddress GAddress;
+
+typedef enum {
+ GSOCK_NOFAMILY = 0,
+ GSOCK_INET,
+ GSOCK_INET6,
+ GSOCK_UNIX
+} GAddressType;
+
+typedef enum {
+ GSOCK_STREAMED,
+ GSOCK_UNSTREAMED
+} GSocketStream;
+
+typedef enum {
+ GSOCK_NOERROR = 0,
+ GSOCK_INVOP,
+ GSOCK_IOERR,
+ GSOCK_INVADDR,
+ GSOCK_INVSOCK,
+ GSOCK_NOHOST,
+ GSOCK_INVPORT
+} GSocketError;
+
+typedef enum {
+ GSOCK_INPUT = 0,
+ GSOCK_OUTPUT = 1,
+ GSOCK_CONNECTION = 2,
+ GSOCK_LOST = 3,
+ GSOCK_MAX_EVENT = 4
+} GSocketEvent;
+
+enum {
+ GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT,
+ GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT,
+ GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION,
+ GSOCK_LOST_FLAG = 1 << GSOCK_LOST,
+};
+
+typedef int GSocketEventFlags;
+
+typedef void (*GSocketFallback)(GSocket *socket, GSocketEvent event,
+ char *cdata);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Constructors / Destructors */
+
+GSocket *GSocket_new();
+void GSocket_destroy(GSocket *socket);
+
+/* This will disable all IO calls to this socket but errors are still available */
+void GSocket_Shutdown(GSocket *socket);
+
+/* Address handling */
+
+GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address);
+GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address);
+GAddress *GSocket_GetLocal(GSocket *socket);
+GAddress *GSocket_GetPeer(GSocket *socket);
+
+/* Non-oriented connections handlers */
+
+GSocketError GSocket_SetNonOriented(GSocket *socket);
+
+/* Server specific parts */
+
+/*
+ GSocket_SetServer() setup the socket as a server. It uses the "Local" field
+ of GSocket. "Local" must be set by GSocket_SetLocal() before
+ GSocket_SetServer() is called. In the other case, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_SetServer(GSocket *socket);
+
+/*
+ GSocket_WaitConnection() waits for an incoming client connection.
+*/
+GSocket *GSocket_WaitConnection(GSocket *socket);
+
+/* Client specific parts */
+
+/*
+ GSocket_Connect() establishes a client connection to a server using the "Peer"
+ field of GSocket. "Peer" must be set by GSocket_SetPeer() before
+ GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_Connect(GSocket *socket, GSocketStream stream);
+
+/* Generic IO */
+
+/* Like recv(), send(), ... */
+/*
+ NOTE: In case we read from a non-oriented connection, the incoming (outgoing)
+ connection address is stored in the "Local" ("Peer") field.
+*/
+int GSocket_Read(GSocket *socket, char *buffer, int size);
+int GSocket_Write(GSocket *socket, const char *buffer,
+ int size);
+bool GSocket_DataAvailable(GSocket *socket);
+
+/* Flags */
+
+/*
+ GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
+ if we don't want to wait.
+*/
+void GSocket_SetBlocking(GSocket *socket, bool block);
+
+/*
+ GSocket_GetError() returns the last error occured on the socket stream.
+*/
+
+GSocketError GSocket_GetError(GSocket *socket);
+
+/* Callbacks */
+
+/*
+ Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION, LOST)
+ INPUT: The function is called when there is at least a byte in the
+ input buffer
+ OUTPUT: The function is called when the system is sure the next write call
+ will not block
+ CONNECTION: Two cases is possible:
+ Client socket -> the connection is established
+ Server socket -> a client request a connection
+ LOST: the connection is lost
+
+ SetFallback accepts a combination of these flags so a same callback can
+ receive different events.
+
+ An event is generated only once and its state is reseted when the relative
+ IO call is requested.
+ For example: INPUT -> GSocket_Read()
+ CONNECTION -> GSocket_Accept()
+*/
+void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
+ GSocketFallback fallback, char *cdata);
+
+/*
+ UnsetFallback will disables all fallbacks specified by "event".
+ NOTE: event may be a combination of flags
+*/
+void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event);
+
+/* GAddress */
+
+GAddress *GAddress_new();
+GAddress *GAddress_copy(GAddress *address);
+void GAddress_destroy(GAddress *address);
+
+void GAddress_SetFamily(GAddress *address, GAddressType type);
+GAddressType GAddress_GetFamily(GAddress *address);
+
+/*
+ The use of any of the next functions will set the address family to the adapted
+ one. For example if you use GAddress_INET_SetHostName, address family will be AF_INET
+ implicitely
+*/
+
+GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
+GSocketError GAddress_INET_SetHostAddress(GAddress *address,
+ unsigned long hostaddr);
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port);
+GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
+
+GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
+ size_t sbuf);
+unsigned long GAddress_INET_GetHostAddress(GAddress *address);
+unsigned short GAddress_INET_GetPort(GAddress *address);
+
+/* TODO: Define specific parts (INET6, UNIX) */
+
+GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
+GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
+
+/*
+ * System specific functions
+ */
+
+/* On systems needing an event id */
+void GSocket_SetEventID(GSocket *socket, unsigned long evt_id);
+
+/* On systems which don't have background refresh */
+void GSocket_DoEvent(unsigned long evt_id);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+ /* __GSOCKET_H */
wxStreamBuffer *OutputStreamBuffer() const { return m_o_streambuf; }
+ size_t CopyTo(char *buffer, size_t len) const;
+
protected:
wxStreamBuffer *m_o_streambuf;
#if wxUSE_SOCKETS
-#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
-#include <winsock.h>
-
-#elif defined(__UNIX__) && defined(WXSOCK_INTERNAL)
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
#include "wx/string.h"
+#include "gsocket.h"
+
class WXDLLEXPORT wxSockAddress : public wxObject {
DECLARE_ABSTRACT_CLASS(wxSockAddress)
public:
typedef enum { IPV4=1, IPV6=2, UNIX=3 } Addr;
- wxSockAddress() {};
- virtual ~wxSockAddress() {};
+ wxSockAddress();
+ virtual ~wxSockAddress();
+
+ virtual void Clear();
+ virtual int Type() = 0;
- virtual void Clear() = 0;
+ GAddress *GetAddress() const { return m_address; }
+ void SetAddress(GAddress *address);
+ const wxSockAddress& operator =(const wxSockAddress& addr);
- virtual void Build(struct sockaddr*& addr, size_t& len) = 0;
- virtual void Disassemble(struct sockaddr *addr, size_t len) = 0;
- virtual int SockAddrLen() = 0;
+ void CopyObject(wxObject& dest) const;
- virtual int GetFamily() = 0;
- virtual int Type() = 0;
+protected:
+ GAddress *m_address;
};
class WXDLLEXPORT wxIPV4address : public wxSockAddress {
DECLARE_DYNAMIC_CLASS(wxIPV4address)
-private:
- struct sockaddr_in *m_addr;
public:
wxIPV4address();
virtual ~wxIPV4address();
- virtual void Clear();
-// const wxSockAddress& operator =(const wxSockAddress& addr);
-
- virtual bool Hostname(const wxString& name);
- virtual bool Hostname(unsigned long addr);
- virtual bool Service(const wxString& name);
- virtual bool Service(unsigned short port);
- virtual bool LocalHost();
+ bool Hostname(const wxString& name);
+ bool Hostname(unsigned long addr);
+ bool Service(const wxString& name);
+ bool Service(unsigned short port);
+ bool LocalHost();
wxString Hostname();
unsigned short Service();
void Build(struct sockaddr*& addr, size_t& len);
void Disassemble(struct sockaddr *addr, size_t len);
- inline int SockAddrLen();
- inline int GetFamily();
inline int Type() { return wxSockAddress::IPV4; }
};
wxIPV6address();
~wxIPV6address();
- void Clear();
-// const wxSockAddress& operator =(const wxSockAddress& addr);
-
bool Hostname(const wxString& name);
bool Hostname(unsigned char addr[16]);
bool Service(const wxString& name);
wxString Hostname() const;
unsigned short Service() const;
- void Build(struct sockaddr*& addr, size_t& len);
- void Disassemble(struct sockaddr *addr, size_t len);
-
- inline int SockAddrLen();
- inline int GetFamily();
inline int Type() { return wxSockAddress::IPV6; }
};
#endif
wxUNIXaddress();
~wxUNIXaddress();
- void Clear();
-// const wxSockAddress& operator =(const wxSockAddress& addr);
-
void Filename(const wxString& name);
wxString Filename();
- void Build(struct sockaddr*& addr, size_t& len);
- void Disassemble(struct sockaddr *addr, size_t len);
-
- inline int SockAddrLen();
- inline int GetFamily();
inline int Type() { return wxSockAddress::UNIX; }
};
#endif
+++ /dev/null
-/////////////////////////////////////////////////////////////////////////////
-// Name: sckint.h
-// Purpose: Socket internal classes
-// Author: Guilhem Lavaux
-// Modified by:
-// Created: April 1999
-// RCS-ID: $Id$
-// Copyright: (c) Guilhem Lavaux
-// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-#ifndef _WX_NETWORK_SOCKET_INT_H
-#define _WX_NETWORK_SOCKET_INT_H
-
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include "wx/defs.h"
-
-#if wxUSE_SOCKETS
-
-#include "wx/object.h"
-#include "wx/list.h"
-#include "wx/socket.h"
-#include "wx/thread.h"
-
-// Socket state
-class SocketState
-{
- public:
- // TRUE if the background notifyier is on.
- bool notify_state;
- // Specifies which events we want to be notified.
- wxSocketBase::wxRequestNotify evt_notify_state;
- // Socket flags.
- wxSocketBase::wxSockFlags socket_flags;
- // Pointer to the C callback function.
- wxSocketBase::wxSockCbk c_callback;
- char *c_callback_data;
-};
-
-// Socket request
-class SockRequest
-{
- public:
- // Buffer where to get/put data.
- char *buffer;
- // Size of the buffer.
- size_t size;
- // Number of bytes really read/written.
- size_t io_nbytes;
- // Error.
- unsigned int error;
- // Type of the request.
- wxSocketBase::wxRequestNotify type;
- // Timeout (in milliseconds).
- unsigned int timeout;
- // TRUE if the buffer has been processed.
- bool done;
- // TRUE if we must wait for the request completion, in the other case an
- // event will be sent to the main thread when the request is finished.
- bool wait;
-};
-
-class wxSocketInternal;
-
-#if wxUSE_THREADS
-class SocketWaiter: public wxThread {
- public:
- SocketWaiter(wxSocketBase *socket, wxSocketInternal *internal);
- ~SocketWaiter();
-
- // Thread Entry point
- // ---
- virtual void *Entry();
-
- protected:
- void ProcessReadEvent();
- void ProcessWriteEvent();
-
- public:
- wxSocketBase *m_socket;
- wxSocketInternal *m_internal;
- int m_fd;
-};
-#endif
-
-class SocketRequester
-#if wxUSE_THREADS
- : public wxThread
-#endif
- {
- public:
- SocketRequester(wxSocketBase *socket, wxSocketInternal *internal);
- ~SocketRequester();
-
- void ProcessWaitEvent(SockRequest *req);
- void ProcessReadEvent(SockRequest *req);
- void ProcessWriteEvent(SockRequest *req);
-
- bool WaitFor(wxSocketBase::wxRequestNotify req, int millisec);
-
-#if wxUSE_THREADS
- // Thread Entry point
- // ---
- virtual void *Entry();
-#endif
-
- public:
- wxSocketBase *m_socket;
- wxSocketInternal *m_internal;
- int m_fd;
-};
-
-class wxSocketInternal {
- public:
- wxSocketInternal(wxSocketBase *socket);
- ~wxSocketInternal();
-
- // wxSocket thread manager
- // -----------------------
- void AcquireData();
- void ReleaseData();
- void AcquireFD();
- void ReleaseFD();
-
- int GetFD() { return m_fd; }
- void SetFD(int fd) { m_fd = fd; }
-
- void ResumeWaiter();
- void StopWaiter();
- void ResumeRequester();
- void StopRequester();
-
- void QueueRequest(SockRequest *request, bool async);
- void WaitForEnd(SockRequest *request);
-
- // Used by SocketRequester
- SockRequest *WaitForReq();
- void EndRequest(SockRequest *req);
- public:
- wxSocketBase *m_socket;
-#if wxUSE_THREADS
- wxMutex m_socket_locker, m_fd_locker, m_request_locker, m_end_requester;
- wxCondition m_socket_cond;
- SocketWaiter *m_thread_waiter;
-#endif
- SocketRequester *m_thread_requester;
- wxList m_requests;
- int m_fd;
- bool m_invalid_requester;
-};
-
-#endif
- // wxUSE_SOCKETS
-
-#endif
- // _WX_NETWORK_SOCKET_INT_H
friend class wxTCPServer;
friend class wxTCPClient;
friend void Client_OnRequest(wxSocketBase&,
- wxSocketBase::wxRequestEvent, char *);
+ GSocketEvent, char *);
friend void Server_OnRequest(wxSocketServer&,
- wxSocketBase::wxRequestEvent, char *);
+ GSocketEvent, char *);
public:
wxTCPConnection(char *buffer, int size);
wxSocketOutputStream(wxSocketBase& s);
~wxSocketOutputStream();
- wxOutputStream& Write(const void *buffer, size_t size);
off_t SeekO( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) )
{ return -1; }
off_t TellO()
wxSocketInputStream(wxSocketBase& s);
~wxSocketInputStream();
- wxInputStream& Read(void *buffer, size_t size);
off_t SeekI( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) )
{ return -1; }
off_t TellI()
// wxUSE_SOCKETS && wxUSE_STREAMS
#endif
- // __SCK_STREAM_H__
\ No newline at end of file
+ // __SCK_STREAM_H__
#if wxUSE_SOCKETS
-// ---------------------------------------------------------------------------
-// Windows(tm) specific
-// ---------------------------------------------------------------------------
-#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
-#include <winsock.h>
-#include <wx/msw/private.h>
-#endif // defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
-
-// ---------------------------------------------------------------------------
-// Unix specific
-// ---------------------------------------------------------------------------
-#if defined(__UNIX__) && defined(WXSOCK_INTERNAL)
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif // defined(__UNIX__) && defined(WXSOCK_INTERNAL)
-
// ---------------------------------------------------------------------------
// wxSocket headers (generic)
// ---------------------------------------------------------------------------
#endif
#include "wx/sckaddr.h"
+#include "gsocket.h"
class WXDLLEXPORT wxSocketEvent;
-class WXDLLEXPORT wxSocketHandler;
-class wxSocketInternal;
class WXDLLEXPORT wxSocketBase : public wxEvtHandler
{
DECLARE_CLASS(wxSocketBase)
-#ifdef __WXMAC__
- friend void wxMacSocketOnRequestProc(void *refcon , short event) ;
-#endif
public:
enum wxSockFlags { NONE=0, NOWAIT=1, WAITALL=2, SPEED=4 };
// Type of request
- enum { REQ_READ=0x1, REQ_PEEK=0x2, REQ_WRITE=0x4, REQ_LOST=0x8,
- REQ_ACCEPT=0x10, REQ_CONNECT=0x20, REQ_WAIT=0x40};
- enum { EVT_READ=0, EVT_PEEK=1, EVT_WRITE=2, EVT_LOST=3, EVT_ACCEPT=4,
- EVT_CONNECT=5 };
- typedef int wxRequestNotify;
- typedef int wxRequestEvent;
enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT };
- typedef void (*wxSockCbk)(wxSocketBase& sock,wxRequestEvent evt,char *cdata);
+ typedef void (*wxSockCbk)(wxSocketBase& sock,GSocketEvent evt,char *cdata);
protected:
- wxSockFlags m_flags;
+ GSocket *m_socket; // wxSocket socket
+ wxSockFlags m_flags; // wxSocket flags
wxSockType m_type; // wxSocket type
- bool m_connected, m_connecting; // State of the socket
- int m_fd; // Socket file descriptors
- wxList m_states; // States list
- int m_id; // Socket id (for event handler)
- wxSocketHandler *m_handler; // the current socket handler
- wxRequestNotify m_neededreq; // Specify which requet signals we need
- unsigned long m_timeout;
+ GSocketEventFlags m_neededreq; // Specify which requet signals we need
size_t m_lcount; // Last IO request size
- int m_error; // Last IO error
- wxSocketInternal *m_internal;
+ unsigned long m_timeout; // IO timeout value
+
char *m_unread; // Pushback buffer
size_t m_unrd_size; // Pushback buffer size
- wxSockCbk m_cbk;
- char *m_cdata;
- bool m_notify_state;
+ size_t m_unrd_cur; // Pushback pointer
+
+ wxSockCbk m_cbk; // C callback
+ char *m_cdata; // C callback data
+
+ bool m_connected; // Connected ?
+ bool m_notify_state; // Notify state
+ int m_id; // Socket id (for event handler)
+
+ enum {
+ DEFER_READ, DEFER_WRITE, NO_DEFER
+ } m_defering; // Defering state
+ char *m_defer_buffer; // Defering target buffer
+ size_t m_defer_nbytes; // Defering buffer size
+
+ wxList m_states; // Stack of states
public:
wxSocketBase();
void CreatePushbackBefore(const char *buffer, size_t size);
// Status
- inline bool Ok() const { return (m_fd < 0 ? 0 : 1); };
- inline bool Error() const { return (m_error != 0); };
+ inline bool Ok() const { return (m_socket != NULL); };
+ inline bool Error() const
+ { return (GSocket_GetError(m_socket) != GSOCK_NOERROR); };
inline bool IsConnected() const { return m_connected; };
inline bool IsDisconnected() const { return !IsConnected(); };
- inline bool IsNoWait() const { return m_flags & NOWAIT; };
+ inline bool IsNoWait() const { return ((m_flags & NOWAIT) != 0); };
bool IsData() const;
inline size_t LastCount() const { return m_lcount; }
- inline int LastError() const { return m_error; }
+ inline GSocketError LastError() const { return GSocket_GetError(m_socket); }
inline wxSockType GetType() const { return m_type; }
void SetFlags(wxSockFlags _flags);
void SetEventHandler(wxEvtHandler& evt_hdlr, int id = -1);
// Method called when it happens something on the socket
- void SetNotify(wxRequestNotify flags);
- virtual void OnRequest(wxRequestEvent req_evt);
+ void SetNotify(GSocketEventFlags flags);
+ virtual void OnRequest(GSocketEvent req_evt);
// Public internal callback
- virtual void OldOnNotify(wxRequestEvent WXUNUSED(evt));
+ virtual void OldOnNotify(GSocketEvent WXUNUSED(evt));
// Some info on the socket...
virtual bool GetPeer(wxSockAddress& addr_man) const;
void Notify(bool notify);
// So you can know what the socket driver is looking for ...
- inline wxRequestNotify NeededReq() const { return m_neededreq; }
+ inline GSocketEventFlags NeededReq() const { return m_neededreq; }
- static wxRequestNotify EventToNotify(wxRequestEvent evt);
+ static GSocketEventFlags EventToNotify(GSocketEvent evt);
protected:
friend class wxSocketServer;
#endif
bool _Wait(long seconds, long microseconds, int type);
-
- // Set "my" handler
- inline virtual void SetHandler(wxSocketHandler *handler)
- { m_handler = handler; }
+ int DeferRead(char *buffer, size_t nbytes);
+ int DeferWrite(const char *buffer, size_t nbytes);
+ void DoDefer(GSocketEvent evt);
+
// Pushback library
size_t GetPushback(char *buffer, size_t size, bool peek);
-
- // To prevent many read or write on the same socket at the same time
- // ==> cause strange things :-)
- void WantSpeedBuffer(char *buffer, size_t size, wxRequestEvent req);
- void WantBuffer(char *buffer, size_t size, wxRequestEvent req);
};
////////////////////////////////////////////////////////////////////////
bool WaitOnConnect(long seconds = -1, long microseconds = 0);
- virtual void OnRequest(wxRequestEvent flags);
-};
-
-////////////////////////////////////////////////////////////////////////
-
-class WXDLLEXPORT wxSocketHandler : public wxObject
-{
- DECLARE_CLASS(wxSocketHandler)
-protected:
- wxList *socks;
-
-public:
- enum SockStatus { SOCK_NONE, SOCK_DATA, SOCK_CONNECT, SOCK_DISCONNECT,
- SOCK_ERROR };
- static wxSocketHandler *master;
-
- wxSocketHandler();
- virtual ~wxSocketHandler();
-
- void Register(wxSocketBase* sock);
- void UnRegister(wxSocketBase* sock);
-
- unsigned long Count() const;
-
- // seconds = -1 means indefinite wait
- // seconds = 0 means no wait
- // seconds > 0 means specified wait
-
- int Wait(long seconds = -1, long microseconds = 0);
- void YieldSock();
-
- wxSocketServer *CreateServer
- (wxSockAddress& addr,
- wxSocketBase::wxSockFlags flags = wxSocketBase::NONE);
- wxSocketClient *CreateClient
- (wxSocketBase::wxSockFlags flags = wxSocketBase::NONE);
-
- // Create or reuse a socket handler
- static wxSocketHandler& Master() { return *master; }
+ virtual void OnRequest(GSocketEvent flags);
};
class WXDLLEXPORT wxSocketEvent : public wxEvent {
public:
wxSocketEvent(int id = 0);
- wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; }
+ GSocketEvent SocketEvent() const { return m_skevt; }
wxSocketBase *Socket() const { return m_socket; }
void CopyObject(wxObject& obj_d) const;
public:
- wxSocketBase::wxRequestEvent m_skevt;
+ GSocketEvent m_skevt;
wxSocketBase *m_socket;
};
wxTextCtrl& operator<<(long i);
wxTextCtrl& operator<<(float f);
wxTextCtrl& operator<<(double d);
- wxTextCtrl& operator<<(const char c);
+ wxTextCtrl& operator<<(const wxChar c);
// obsolete functions
#if WXWIN_COMPATIBILITY
#include "wx/url.h"
#include "wx/protocol/http.h"
#include "wx/thread.h"
+#include "wx/progdlg.h"
#if defined(__WXMOTIF__) || defined(__WXGTK__)
#include "mondrian.xpm"
void OnExecCloseConnection(wxCommandEvent& evt);
void UpdateStatus();
+ void Download(wxInputStream *input);
+
DECLARE_EVENT_TABLE()
};
public:
MyFrame *frame;
- void OnNotify(wxRequestNotify WXUNUSED(flags)) { frame->UpdateStatus(); }
+ void OnNotify(GSocketEventFlags WXUNUSED(flags)) { frame->UpdateStatus(); }
};
// ID for the menu quit command
wxFrame(NULL, -1, "wxSocket client demo",
wxDefaultPosition, wxSize(300, 200), wxDEFAULT_FRAME_STYLE)
{
- // Init all
- wxSocketHandler::Master();
-
sock = new MyClient();
sock->SetFlags((wxSocketBase::wxSockFlags) (wxSocketBase::WAITALL | wxSocketBase::SPEED));
- wxSocketHandler::Master().Register(sock);
sock->frame = this;
- sock->SetNotify(wxSocketBase::REQ_LOST);
+ sock->SetNotify(GSOCK_LOST_FLAG);
CreateStatusBar(2);
UpdateStatus();
}
addr.Service(3000);
sock->SetNotify(0);
sock->Connect(addr, TRUE);
+ sock->SetFlags(wxSocketBase::NONE);
if (!sock->IsConnected())
wxMessageBox("Can't connect to the specified host", "Alert !");
void MyFrame::OnExecCloseConnection(wxCommandEvent& WXUNUSED(evt))
{
- if (sock)
- sock->Close();
+ sock->Close();
UpdateStatus();
}
delete dlgbox;
}
+
+void MyFrame::Download(wxInputStream *input)
+{
+ wxProgressDialog progress("Downloading ...", "0% downloaded");
+ wxBufferedInputStream buf_in(*input);
+ wxFileOutputStream f_out("test.url");
+
+ size_t file_size = input->StreamSize();
+ size_t downloaded;
+ int BUFSIZE = (file_size > 100) ? (file_size / 100) : file_size;
+ int bytes_read = BUFSIZE;
+ wxString message;
+ int percents;
+
+ char *buf;
+
+// TODO: Support for streams which don't support StreamSize
+
+ buf = new char[BUFSIZE];
+
+ downloaded = 0;
+ bytes_read = BUFSIZE;
+ while (downloaded < file_size && bytes_read != 0) {
+ bytes_read = buf_in.Read(buf, BUFSIZE).LastRead();
+ f_out.Write(buf, bytes_read);
+ downloaded += bytes_read;
+
+ percents = downloaded * 100 / file_size;
+
+ message = _T("");
+ message << percents << _T("% downloaded");
+ progress.Update(percents, message);
+ }
+
+ delete[] buf;
+}
+
void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
{
wxString urlname = wxGetTextFromUser("Enter an URL to get",
error.Printf(_T("Error in getting data from the URL. (error = %d)"), url.GetError());
wxMessageBox(error, "Alert !");
} else {
- wxFileOutputStream *str_out = new wxFileOutputStream("test.url");
- str_out->Write(*datas);
+ Download(datas);
- wxMessageBox(_T("Success !! Click on OK to see the text."), "OK");
delete datas;
- delete str_out;
}
}
printf("OnSockRequest OK\n");
printf("OnSockRequest (event = %d)\n",evt.SocketEvent());
switch (evt.SocketEvent()) {
- case wxSocketBase::EVT_READ:
+ case GSOCK_INPUT:
unsigned char c;
sock->Read((char *)&c, 1);
ExecTest1(sock);
break;
- case wxSocketBase::EVT_LOST:
+ case GSOCK_LOST:
printf("Destroying socket\n");
wxPendingDelete.Append(sock);
UpdateStatus(-1);
break;
}
printf("OnSockRequest Exiting\n");
- sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
}
void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
return;
UpdateStatus(1);
- sock2->SetFlags(wxSocketBase::SPEED);
+ sock2->SetFlags(wxSocketBase::NONE);
sock2->Notify(TRUE);
sock2->SetEventHandler(*this, SKDEMO_SOCKET);
- server->SetNotify(wxSocketBase::REQ_ACCEPT);
+ sock2->SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
}
// My frame Constructor
addr.Service(3000);
// Init all
- wxSocketHandler::Master();
sock = new wxSocketServer(addr);
- wxSocketHandler::Master().Register(sock);
- sock->SetNotify(wxSocketBase::REQ_ACCEPT);
+ sock->SetNotify(GSOCK_CONNECTION_FLAG);
sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
sock->SetFlags(wxSocketBase::SPEED);
sock->Notify(TRUE);
{
wxASSERT_MSG( !m_fp, _T("should close or detach the old file first") );
+#if wxUSE_UNICODE
+ char *tmp_fname;
+ size_t fname_len;
+
+ fname_len = wxStrlen(filename)+1;
+ tmp_fname = new char[fname_len];
+ wxWX2MB(tmp_fname, filename, fname_len);
+
+ m_fp = fopen(tmp_fname, mode);
+
+ delete tmp_fname;
+#else
m_fp = fopen(filename, mode);
+#endif
+
if ( !m_fp )
{
m_passwd += wxGetHostName();
SetNotify(0);
+ SetFlags(NONE);
}
wxFTP::~wxFTP()
////////////////////////////////////////////////////////////////
bool wxFTP::Connect(wxSockAddress& addr, bool WXUNUSED(wait))
{
- if (!m_handler) {
- m_lastError = wxPROTO_NOHNDLR;
- return FALSE;
- }
-
if (!wxProtocol::Connect(addr)) {
m_lastError = wxPROTO_NETERR;
return FALSE;
size_t StreamSize() const { return m_ftpsize; }
virtual ~wxInputFTPStream(void)
{
- if (LastError() != wxStream_NOERROR)
+ if (LastError() == wxStream_NOERROR)
m_ftp->GetResult('2');
else
m_ftp->Abort();
{
wxIPV4address addr;
wxSocketClient *client;
- struct sockaddr sin;
int a[6];
wxString straddr;
int addr_pos;
+ wxUint16 port;
+ wxUint32 hostaddr;
if (!SendCommand(_T("PASV"), '2'))
return NULL;
- sin.sa_family = AF_INET;
addr_pos = m_lastResult.Find(_T('('));
if (addr_pos == -1) {
m_lastError = wxPROTO_PROTERR;
}
straddr = m_lastResult(addr_pos+1, m_lastResult.Length());
wxSscanf((const wxChar *)straddr,_T("%d,%d,%d,%d,%d,%d"),&a[2],&a[3],&a[4],&a[5],&a[0],&a[1]);
- sin.sa_data[2] = (char)a[2];
- sin.sa_data[3] = (char)a[3];
- sin.sa_data[4] = (char)a[4];
- sin.sa_data[5] = (char)a[5];
- sin.sa_data[0] = (char)a[0];
- sin.sa_data[1] = (char)a[1];
- addr.Disassemble(&sin, sizeof(sin));
+ hostaddr = (wxUint16)a[5] << 24 | (wxUint16)a[4] << 16 |
+ (wxUint16)a[3] << 8 | a[2];
+ addr.Hostname(hostaddr);
+
+ port = (wxUint16)a[0] << 8 | a[1];
+ addr.Service(port);
- client = m_handler->CreateClient();
+ client = new wxSocketClient();
if (!client->Connect(addr)) {
delete client;
return NULL;
m_addr = NULL;
m_read = FALSE;
- SetNotify(REQ_LOST);
+ SetNotify(GSOCK_LOST_FLAG);
}
wxHTTP::~wxHTTP()
m_read = TRUE;
while (1) {
- m_error = GetLine(this, line);
- if (m_error != wxPROTO_NOERR)
+ m_perr = GetLine(this, line);
+ if (m_perr != wxPROTO_NOERR)
return FALSE;
if (line.Length() == 0)
if (!addr->Hostname(host)) {
delete m_addr;
m_addr = NULL;
- m_error = wxPROTO_NETERR;
+ m_perr = wxPROTO_NETERR;
return FALSE;
}
bool wxHTTP::Connect(wxSockAddress& addr, bool WXUNUSED(wait))
{
- struct sockaddr *raw_addr;
- size_t len;
-
- m_addr = (wxSockAddress *)(addr.GetClassInfo()->CreateObject());
-
- addr.Build(raw_addr, len);
- m_addr->Disassemble(raw_addr, len);
+ if (m_addr) {
+ delete m_addr;
+ m_addr = NULL;
+ Close();
+ }
+ m_addr = (wxSockAddress *) addr.Clone();
return TRUE;
}
bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
{
wxChar *tmp_buf;
- wxChar buf[200];
- wxWX2MBbuf pathbuf(200);
+ wxChar buf[200]; // 200 is arbitrary.
+#if wxUNICODE
+ wxWX2MBbuf pathbuf((size_t)200);
+#else
+ const wxWX2MBbuf pathbuf;
+#endif
wxString tmp_str;
switch (req) {
Notify(FALSE);
tmp_str = wxURL::ConvertToValidURI(path);
- wxSprintf(buf, _T("%s %s\n\r"), tmp_buf, tmp_str.GetData());
+ wxSprintf(buf, _T("%s %s HTTP/1.0\n\r"), tmp_buf, tmp_str.GetData());
pathbuf = wxConvLibc.cWX2MB(buf);
- Write(pathbuf, strlen(pathbuf));
+ Write(pathbuf, strlen(MBSTRINGCAST pathbuf));
SendHeaders();
Write("\n\r", 2);
- m_error = GetLine(this, tmp_str);
- if (m_error != wxPROTO_NOERR) {
+ m_perr = GetLine(this, tmp_str);
+ if (m_perr != wxPROTO_NOERR) {
RestoreState();
return FALSE;
}
case 200:
break;
default:
- m_error = wxPROTO_NOFILE;
+ m_perr = wxPROTO_NOFILE;
RestoreState();
return FALSE;
}
public:
wxHTTP *m_http;
size_t m_httpsize;
+ unsigned long m_read_bytes;
wxHTTPStream(wxHTTP *http) : wxSocketInputStream(*http), m_http(http) {}
size_t StreamSize() const { return m_httpsize; }
virtual ~wxHTTPStream(void) { m_http->Abort(); }
+
+protected:
+ size_t OnSysRead(void *buffer, size_t bufsize);
};
+size_t wxHTTPStream::OnSysRead(void *buffer, size_t bufsize)
+{
+ size_t ret;
+
+ if (m_httpsize > 0 && m_read_bytes >= m_httpsize)
+ return 0;
+
+ ret = wxSocketInputStream::OnSysRead(buffer, bufsize);
+ m_read_bytes += ret;
+
+ return ret;
+}
+
bool wxHTTP::Abort(void)
{
return wxSocketClient::Close();
wxHTTPStream *inp_stream = new wxHTTPStream(this);
if (!m_addr || m_connected) {
- m_error = wxPROTO_CONNERR;
+ m_perr = wxPROTO_CONNERR;
return NULL;
}
if (!BuildRequest(path, wxHTTP_GET))
return NULL;
- wxPrintf(_T("Len = %s\n"), WXSTRINGCAST GetHeader(_T("Content-Length")));
if (!GetHeader(_T("Content-Length")).IsEmpty())
inp_stream->m_httpsize = wxAtoi(WXSTRINGCAST GetHeader(_T("Content-Length")));
+ else
+ inp_stream->m_httpsize = (size_t)-1;
+
+ inp_stream->m_read_bytes = 0;
+
+ Notify(FALSE);
- SetFlags(WAITALL);
return inp_stream;
}
#include "wx/file.h"
#include "wx/textfile.h"
#include "wx/utils.h"
+#include "wx/wxchar.h"
#include "wx/log.h"
// other standard headers
wxChar buf[256];
time_t timeNow;
(void)time(&timeNow);
- wxStrftime(buf, WXSIZEOF(buf), ms_timestamp, localtime(&timeNow));
+// wxStrftime(buf, WXSIZEOF(buf), ms_timestamp, localtime(&timeNow));
str->Empty();
*str << buf << _T(": ");
bool wxLog::ms_doLog = TRUE;
bool wxLog::ms_bAutoCreate = TRUE;
-const wxChar *wxLog::ms_timestamp = "%X"; // time only, no date
+const wxChar *wxLog::ms_timestamp = _T("%X"); // time only, no date
wxTraceMask wxLog::ms_ulTraceMask = (wxTraceMask)0;
wxArrayString wxLog::ms_aTraceMasks;
return m_o_streambuf->Tell();
}
+size_t wxMemoryOutputStream::CopyTo(char *buffer, size_t len) const
+{
+ if (!buffer)
+ return 0;
+
+ if (len > StreamSize())
+ len = StreamSize();
+
+ memcpy(buffer, m_o_streambuf->GetBufferStart(), len);
+ return len;
+}
#endif
#if wxUSE_SOCKETS
-#ifndef WX_PRECOMP
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <memory.h>
#endif
-#include "wx/defs.h"
-#include "wx/object.h"
-
-#if defined(__WXMAC__)
-#include "/wx/mac/macsock.h"
-#endif
-
-#if defined(__WINDOWS__)
-#include <winsock.h>
-#endif // __WINDOWS__
-
-#if defined(__UNIX__)
-#ifdef VMS
-#include <socket.h>
-#include <in.h>
-#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-#include <unistd.h>
-#include <netdb.h>
-
-#ifdef __SUN__
-extern "C"
-{
- struct hostent *gethostbyname(const char *name);
- int gethostname(char *name, int namelen);
-};
-#endif
-
-#endif // __UNIX__
-
-#include "wx/sckaddr.h"
-
-#define CHECK_ADDRTYPE(var, type)
+#include <wx/defs.h>
+#include <wx/object.h>
+#include <wx/gsocket.h>
+#include <wx/sckaddr.h>
#if !USE_SHARED_LIBRARY
IMPLEMENT_ABSTRACT_CLASS(wxSockAddress, wxObject)
#endif
#endif
-wxIPV4address::wxIPV4address()
+// ---------------------------------------------------------------------------
+// wxIPV4address
+// ---------------------------------------------------------------------------
+
+wxSockAddress::wxSockAddress()
{
- m_addr = new sockaddr_in;
- Clear();
+ m_address = GAddress_new();
}
-wxIPV4address::~wxIPV4address()
+wxSockAddress::~wxSockAddress()
{
+ GAddress_destroy(m_address);
}
-int wxIPV4address::SockAddrLen()
+void wxSockAddress::SetAddress(GAddress *address)
{
- return sizeof(*m_addr);
+ GAddress_destroy(m_address);
+ m_address = GAddress_copy(address);
}
-int wxIPV4address::GetFamily()
+const wxSockAddress& wxSockAddress::operator=(const wxSockAddress& addr)
{
- return AF_INET;
+ SetAddress(addr.GetAddress());
+ return *this;
}
-void wxIPV4address::Clear()
+void wxSockAddress::CopyObject(wxObject& dest) const
{
- memset(m_addr, 0, sizeof(*m_addr));
- m_addr->sin_family = AF_INET;
- m_addr->sin_addr.s_addr = INADDR_ANY;
+ wxSockAddress *addr = (wxSockAddress *)&dest;
+
+ wxObject::CopyObject(dest);
+ addr->SetAddress(GetAddress());
}
-/*
-const wxSockAddress& wxIPV4address::operator =(const wxSockAddress& addr)
-{
- wxIPV4address *ip_addr = (wxIPV4address *)&addr;
- CHECK_ADDRTYPE(addr, wxIPV4address);
- m_addr = ip_addr->m_addr;
- return *this;
+void wxSockAddress::Clear()
+{
+ GAddress_destroy(m_address);
+ m_address = GAddress_new();
}
-*/
-bool wxIPV4address::Hostname(const wxString& name)
+// ---------------------------------------------------------------------------
+// wxIPV4address
+// ---------------------------------------------------------------------------
+
+wxIPV4address::wxIPV4address()
+ : wxSockAddress()
{
- struct hostent *theHostent;
- struct in_addr *addr;
-
- if (name.IsNull())
- return FALSE;
-
- if (!name.IsNumber()) {
- if ((theHostent = gethostbyname(name.fn_str())) == 0) {
- return FALSE;
- }
- } else {
-#ifdef __WXMAC__
- long len_addr = inet_addr(name.fn_str()).s_addr ;
-#else
- long len_addr = inet_addr(name.fn_str());
-#endif
- if (len_addr == -1)
- return FALSE;
- m_addr->sin_addr.s_addr = len_addr;
- return TRUE;
- }
+}
- addr = (struct in_addr *) *(theHostent->h_addr_list);
+wxIPV4address::~wxIPV4address()
+{
+}
- m_addr->sin_addr.s_addr = addr[0].s_addr;
- return TRUE;
+bool wxIPV4address::Hostname(const wxString& name)
+{
+ return (GAddress_INET_SetHostName(m_address, name.fn_str()) == GSOCK_NOERROR);
}
bool wxIPV4address::Hostname(unsigned long addr)
{
- m_addr->sin_addr.s_addr = htonl(addr);
- return TRUE;
+ /* Need API */
+ return TRUE;
}
bool wxIPV4address::Service(const wxString& name)
{
- struct servent *theServent;
-
- if (name.IsNull())
- return FALSE;
-
- if (!name.IsNumber()) {
- if ((theServent = getservbyname(name.fn_str(), "tcp")) == 0)
- return FALSE;
- } else {
- if ((theServent = getservbyport(wxAtoi(name), "tcp")) == 0) {
- m_addr->sin_port = htons(wxAtoi(name));
- return TRUE;
- }
- }
-
- m_addr->sin_port = theServent->s_port;
- return TRUE;
+ return (GAddress_INET_SetPortName(m_address, name.fn_str()) == GSOCK_NOERROR);
}
bool wxIPV4address::Service(unsigned short port)
{
- m_addr->sin_port = htons(port);
- return TRUE;
+ return (GAddress_INET_SetPort(m_address, port) == GSOCK_NOERROR);
}
bool wxIPV4address::LocalHost()
{
- static char buf[256];
-
- if (gethostname(buf, sizeof(buf)) < 0)
- return Hostname("localhost");
- else
- return Hostname(buf);
+ return (GAddress_INET_SetHostName(m_address, "localhost") == GSOCK_NOERROR);
}
wxString wxIPV4address::Hostname()
{
- struct hostent *h_ent;
-
- h_ent = gethostbyaddr((char *)&(m_addr->sin_addr), sizeof(m_addr->sin_addr),
- GetFamily());
-
- if (!h_ent)
- return wxString("");
- else
- return wxString(h_ent->h_name);
-}
-
-unsigned short wxIPV4address::Service()
-{
- return ntohs(m_addr->sin_port);
-}
+ char hostname[1024];
-void wxIPV4address::Build(struct sockaddr *&addr, size_t& len)
-{
- addr = (struct sockaddr *)m_addr;
- len = sizeof(*m_addr);
+ hostname[0] = 0;
+ GAddress_INET_GetHostName(m_address, hostname, 1024);
+ return wxString(hostname);
}
-void wxIPV4address::Disassemble(struct sockaddr *addr, size_t len)
+unsigned short wxIPV4address::Service()
{
- if (len != sizeof(*m_addr))
- return;
- *m_addr = *(struct sockaddr_in *)addr;
+ return GAddress_INET_GetPort(m_address);
}
#ifdef IPV6_ENABLE
+// ---------------------------------------------------------------------------
+// wxIPV6address
+// ---------------------------------------------------------------------------
wxIPV6address::wxIPV6address()
+ : wxSockAddress()
{
- m_addr = new sockaddr_in6;
- Clear();
}
wxIPV6address::~wxIPV6address()
{
}
-int wxIPV6address::SockAddrLen()
-{
- return sizeof(*m_addr);
-}
-
-int wxIPV6address::GetFamily()
-{
- return AF_INET6;
-}
-
-void wxIPV6address::Clear()
-{
- memset(m_addr, 0, sizeof(*m_addr));
- m_addr->sin6_family = AF_INET6;
- m_addr->sin6_addr.s_addr = INADDR_ANY;
-}
-
-/*
-const wxSockAddress& wxIPV6address::operator =(const wxSockAddress& addr)
-{
- wxIPV6address *ip_addr = (wxIPV6address *)&addr;
-
- CHECK_ADDRTYPE(addr, wxIPV6address);
- m_addr = ip_addr->m_addr;
- return *this;
-}
-*/
-
bool wxIPV6address::Hostname(const wxString& name)
{
- struct hostent *theHostent;
- struct in_addr *addr;
-
- if (name.IsNull())
- return FALSE;
-
- if (!name.IsNumber()) {
- hostent = gethostbyname2((char*) name, AF_INET6);
- if (!theHostent)
- return FALSE;
- } else {
- // Don't how to do
- return FALSE;
- }
-
- addr = (struct in6_addr *) *(theHostent->h_addr_list);
-
- m_addr->sin6_addr.s6_addr = addr[0].s6_addr;
- return TRUE;
+ return (GAddress_INET_SetHostName(m_address, name.fn_str()) == GSOCK_NOERROR);
}
bool wxIPV6address::Hostname(unsigned char addr[16])
{
- m_addr->sin6_addr.s6_addr = addr;
return TRUE;
}
bool wxIPV6address::Service(const char *name)
{
- struct servent *theServent;
-
- if (!name || !strlen(name))
- return FALSE;
-
- if (!isdigit(*name)) {
- if ((theServent = getservbyname((char*) name, "tcp")) == 0)
- return FALSE;
- } else {
- if ((theServent = getservbyport(atoi(name), "tcp")) == 0) {
- m_addr->sin_port = htons(atoi(name));
- return TRUE;
- }
- }
-
- m_addr->sin_port = theServent->s_port;
- return TRUE;
+ return (GAddress_INET_SetPortName(m_address, name.fn_str()) == GSOCK_NOERROR);
}
bool wxIPV6address::Service(unsigned short port)
{
- m_addr->sin_port = htons(port);
- return TRUE;
+ return (GAddress_INET_SetPort(m_address, port) == GSOCK_NOERROR);
}
bool wxIPV6address::LocalHost()
{
- static char buf[256];
-
- if (gethostname(buf, sizeof(buf)) < 0)
- return Hostname("localhost");
- else
- return Hostname(buf);
+ return (GAddress_INET_SetHostName(m_address, "localhost") == GSOCK_NOERROR);
}
const wxString& wxIPV6address::Hostname()
{
- struct hostent *h_ent;
-
- h_ent = gethostbyaddr((char *)&(m_addr->sin_addr), sizeof(m_addr->sin_addr),
- GetFamily());
- return wxString(h_ent->h_name);
+ return wxString(GAddress_INET_GetHostName(m_address));
}
unsigned short wxIPV6address::Service()
{
- return ntohs(m_addr->sin_port);
-}
-
-void wxIPV6address::Build(struct sockaddr& *addr, size_t& len)
-{
- len = sizeof(*m_addr);
- addr = m_addr;
-}
-
-void wxIPV6address::Disassemble(struct sockaddr& *addr, size_t len)
-{
- if (len != sizeof(*m_addr))
- return;
- *m_addr = *(struct sockaddr_in6 *)addr;
+ return GAddress_INET_GetPort(m_address);
}
#endif
#ifdef __UNIX__
-#include <sys/un.h>
+// ---------------------------------------------------------------------------
+// wxUNIXaddress
+// ---------------------------------------------------------------------------
wxUNIXaddress::wxUNIXaddress()
+ : wxSockAddress()
{
- m_addr = new sockaddr_un;
- Clear();
}
wxUNIXaddress::~wxUNIXaddress()
{
}
-int wxUNIXaddress::SockAddrLen()
-{
- return sizeof(*m_addr);
-}
-
-int wxUNIXaddress::GetFamily()
-{
- return AF_UNIX;
-}
-
-void wxUNIXaddress::Clear()
-{
- memset(m_addr, 0, sizeof(m_addr));
- m_addr->sun_family = AF_UNIX;
-}
-
-/*
-const wxSockAddress& wxUNIXaddress::operator =(const wxSockAddress& addr)
-{
- wxUNIXaddress *unx_addr = (wxUNIXaddress *)&addr;
- CHECK_ADDRTYPE(addr, wxUNIXaddress);
- m_addr = unx_addr->m_addr;
- return *this;
-}
-*/
-
void wxUNIXaddress::Filename(const wxString& fname)
{
- sprintf(m_addr->sun_path, "%s", MBSTRINGCAST fname.mb_str());
+ GAddress_UNIX_SetPath(m_address, fname.fn_str());
}
wxString wxUNIXaddress::Filename()
{
- return wxString(m_addr->sun_path);
-}
+ char path[1024];
-void wxUNIXaddress::Build(struct sockaddr*& addr, size_t& len)
-{
- addr = (struct sockaddr *)m_addr;
- len = sizeof(*m_addr);
+ path[0] = 0;
+ GAddress_UNIX_GetPath(m_address, path, 1024);
+ return wxString(path);
}
-void wxUNIXaddress::Disassemble(struct sockaddr *addr, size_t len)
-{
- if (len != sizeof(*m_addr))
- return;
- *m_addr = *(struct sockaddr_un *)addr;
-}
#endif
#endif
+++ /dev/null
-///////////////////////////////////////////////////////////////////////////////
-// Name: sckint.cpp
-// Purpose: Socket internal classes
-// Authors: Guilhem Lavaux
-// Created: April 1999
-// Updated:
-// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
-// RCS_ID: $Id$
-// License: see wxWindows license
-///////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "sckint.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#if wxUSE_SOCKETS
-
-#define WXSOCK_INTERNAL
-#include "wx/object.h"
-#include "wx/list.h"
-#include "wx/socket.h"
-#include "wx/thread.h"
-#include "wx/sckint.h"
-#include "wx/sckint.h"
-#include "wx/utils.h"
-
-// IRIX requires bstring.h be included to use select()
-#ifdef sgi
- #include <bstring.h>
-#endif // IRIX
-
-#ifndef __WXSTUBS__
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-// -----------------------
-// System specific headers
-// -----------------------
-
-#ifdef __WXMAC__
-// in order to avoid problems with our c library and double definitions
-#define close closesocket
-#define ioctl ioctlsocket
-
-#include <wx/mac/macsock.h>
-#endif
-
-#if defined(__WINDOWS__)
-#include <winsock.h>
-#endif // __WINDOWS__
-
-#if defined(__UNIX__)
-
-#ifdef VMS
-#include <socket.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <sys/time.h>
-#include <unistd.h>
-
-#ifdef sun
-#include <sys/filio.h>
-#endif
-
-#endif // __UNIX__
-
-#include <signal.h>
-#include <errno.h>
-
-#ifdef __VISUALC__
-#include <io.h>
-#endif
-
-// Constants
-#define READ_MASK wxSocketBase::REQ_READ | wxSocketBase::REQ_ACCEPT | wxSocketBase::REQ_LOST
-#define WRITE_MASK wxSocketBase::REQ_WRITE | wxSocketBase::REQ_CONNECT
-
-// --------------------------------------------------------------
-// --------- SocketWaiter ---------------------------------------
-// --------------------------------------------------------------
-
-#if wxUSE_THREADS
-SocketWaiter::SocketWaiter(wxSocketBase *socket,
- wxSocketInternal *internal)
- : wxThread(),
- m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
-{
-}
-
-SocketWaiter::~SocketWaiter()
-{
-}
-
-void SocketWaiter::ProcessReadEvent()
-{
- int ret;
- char c;
-
- m_internal->AcquireFD();
- ret = recv(m_fd, &c, 1, MSG_PEEK);
- m_internal->ReleaseFD();
-
- // We are a server => emit a EVT_ACCEPT event.
- if (ret == -1 && m_socket->GetType() == wxSocketBase::SOCK_SERVER) {
- m_socket->OnRequest(wxSocketBase::EVT_ACCEPT);
- return;
- }
-
- // Else, no error => there is something to be read else
- // we've lost the connection.
- if (ret > 0) {
- m_socket->OnRequest(wxSocketBase::EVT_READ);
- } else {
- m_socket->OnRequest(wxSocketBase::EVT_LOST);
- m_internal->ReleaseData(); // In that case, we mustn't forget to unlock the mutex.
- Exit(NULL);
- }
-}
-
-void SocketWaiter::ProcessWriteEvent()
-{
- if (m_socket->IsConnected())
- m_socket->OnRequest(wxSocketBase::EVT_CONNECT);
- else
- m_socket->OnRequest(wxSocketBase::EVT_WRITE);
-}
-
-void *SocketWaiter::Entry()
-{
- struct timeval tv;
- fd_set sockrd_set, sockwr_set;
- wxSocketEvent event;
- int ret;
-
- while (1) {
- // We won't wait.
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- FD_ZERO(&sockrd_set);
- FD_ZERO(&sockwr_set);
-
- m_internal->AcquireData();
-
- if ((m_socket->NeededReq() & READ_MASK) != 0)
- FD_SET(m_fd, &sockrd_set);
- if ((m_socket->NeededReq() & WRITE_MASK) != 0)
- FD_SET(m_fd, &sockwr_set);
-
- m_internal->AcquireFD();
- ret = select(m_fd+1, &sockrd_set, &sockwr_set, NULL, &tv);
- m_internal->ReleaseFD();
-
- if (FD_ISSET(m_fd, &sockrd_set))
- ProcessReadEvent();
-
- if (FD_ISSET(m_fd, &sockwr_set))
- ProcessWriteEvent();
-
- m_internal->ReleaseData();
-
-#if wxUSE_THREADS
-#ifdef Yield
-#undef Yield
-#endif
-#endif
-
- // We wait for 100 ms to prevent the CPU from burning.
- wxUsleep(100);
-
- // Check whether we should exit.
- if (TestDestroy())
- return NULL;
- }
- return NULL;
-}
-
-#endif
-
-// --------------------------------------------------------------
-// --------- SocketRequester ------------------------------------
-// --------------------------------------------------------------
-
-SocketRequester::SocketRequester(wxSocketBase *socket,
- wxSocketInternal *internal)
- :
-#if wxUSE_THREADS
- wxThread(),
-#endif
- m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
-{
-}
-
-SocketRequester::~SocketRequester()
-{
-}
-
-bool SocketRequester::WaitFor(wxSocketBase::wxRequestNotify req, int millisec)
-{
- int ret;
- struct timeval tv;
- fd_set sockrd_set, sockwr_set;
-
- // We won't wait.
- tv.tv_sec = millisec / 1000;
- tv.tv_usec = (millisec % 1000) * 1000;
-
- FD_ZERO(&sockrd_set);
- FD_ZERO(&sockwr_set);
- if ((req & READ_MASK) != 0)
- FD_SET(m_fd, &sockrd_set);
- if ((req & WRITE_MASK) != 0)
- FD_SET(m_fd, &sockwr_set);
-
- m_internal->AcquireFD();
- ret = select(m_fd+1, &sockrd_set, &sockwr_set, NULL, &tv);
- m_internal->ReleaseFD();
-
- return (ret != 0);
-}
-
-void SocketRequester::ProcessReadEvent(SockRequest *req)
-{
- int ret;
- size_t len;
-
- // We'll wait for the first byte, in case a "timeout event" occurs it returns // immediately
- if (!WaitFor(wxSocketBase::REQ_READ, req->timeout)) {
- m_internal->EndRequest(req);
- return;
- }
-
- m_internal->AcquireFD();
- ret = recv(m_fd, req->buffer, req->size,
- (req->type == wxSocketBase::REQ_PEEK) ? MSG_PEEK : 0);
- m_internal->ReleaseFD();
-
- // An error occured, we exit.
- if (ret < 0) {
- req->error = errno;
- m_internal->EndRequest(req);
- return;
- }
- len = ret;
-
- // If the buffer isn't full (and we want it to be full), we don't unqueue it.
- if ((len < req->size) && (m_socket->GetFlags() & wxSocketBase::WAITALL)) {
- req->size -= len;
- req->io_nbytes += len;
- req->buffer += len;
-
- if (len == 0)
- m_internal->EndRequest(req);
- return;
- }
- // The End.
- req->io_nbytes += len;
- m_internal->EndRequest(req);
-}
-
-void SocketRequester::ProcessWriteEvent(SockRequest *req)
-{
- int ret;
- size_t len;
-
- if (!WaitFor(wxSocketBase::REQ_WRITE, req->timeout)) {
- m_internal->EndRequest(req);
- return;
- }
-
- m_internal->AcquireFD();
- ret = send(m_fd, req->buffer, req->size, 0);
- m_internal->ReleaseFD();
- if (ret < 0) {
- req->error = errno;
- m_internal->EndRequest(req);
- return;
- }
- len = ret;
- if ((len < req->size) && ((m_socket->GetFlags() & wxSocketBase::WAITALL) != 0)) {
- req->size -= len;
- req->io_nbytes += len;
- req->buffer += len;
- return;
- }
- req->io_nbytes += len;
- m_internal->EndRequest(req);
-}
-
-void SocketRequester::ProcessWaitEvent(SockRequest *req)
-{
- if (WaitFor(req->type, req->timeout))
- req->io_nbytes = 1; // We put 1 in the counter to tell the requester
- // there is no timeout.
- else
- req->io_nbytes = 0;
-
- m_internal->EndRequest(req);
-}
-
-
-#if wxUSE_THREADS
-void *SocketRequester::Entry()
-{
- SockRequest *req;
-
- m_internal->m_request_locker.Lock();
- while (1) {
- // Wait for a new request or a destroy message.
- req = m_internal->WaitForReq();
- m_internal->m_end_requester.Lock();
- if (req == NULL) {
- m_internal->m_invalid_requester = TRUE;
- m_internal->m_end_requester.Unlock();
- m_internal->m_request_locker.Unlock();
- return NULL;
- }
- m_internal->m_end_requester.Unlock();
-
- if ((req->type & wxSocketBase::REQ_WAIT) != 0) {
- ProcessWaitEvent(req);
- continue;
- }
-
- switch (req->type) {
- case wxSocketBase::REQ_READ:
- case wxSocketBase::REQ_PEEK:
- ProcessReadEvent(req);
- break;
- case wxSocketBase::REQ_WRITE:
- ProcessWriteEvent(req);
- break;
- }
- }
- return NULL;
-}
-#endif
-
-// --------------------------------------------------------------
-// --------- wxSocketInternal -----------------------------------
-// --------------------------------------------------------------
-
-wxSocketInternal::wxSocketInternal(wxSocketBase *socket)
-{
- m_socket = socket;
- m_thread_requester = NULL;
- m_thread_waiter = NULL;
- m_invalid_requester = TRUE;
-}
-
-wxSocketInternal::~wxSocketInternal()
-{
- StopRequester();
- wxASSERT(m_thread_requester == NULL);
- StopWaiter();
- wxASSERT(m_thread_waiter == NULL);
-}
-
-// ----------------------------------------------------------------------
-// WaitForReq: it is called by SocketRequester and should return the next
-// socket request if available
-// ----------------------------------------------------------------------
-SockRequest *wxSocketInternal::WaitForReq()
-{
-#if wxUSE_THREADS
- wxNode *node;
-
- // First try.
- node = m_requests.First();
- if (node == NULL) {
- m_socket_cond.Wait(m_request_locker, 10, 0);
-
- // Second try, if it is unsuccessul we give up.
- node = m_requests.First();
- if (node == NULL)
- return NULL;
- }
-
- return (SockRequest *)node->Data();
-#else
- return NULL;
-#endif
-}
-
-// ----------------------------------------------------------------------
-// EndRequest: Should be called to finalize a request
-// ----------------------------------------------------------------------
-void wxSocketInternal::EndRequest(SockRequest *req)
-{
- wxNode *node = NULL;
-
- req->done = TRUE;
-
- node = m_requests.Member((wxObject *)req);
- if (node != NULL)
- delete node;
-}
-
-void wxSocketInternal::AcquireData()
-{
-#if wxUSE_THREADS
- m_socket_locker.Lock();
-#endif
-}
-
-void wxSocketInternal::ReleaseData()
-{
-#if wxUSE_THREADS
- m_socket_locker.Unlock();
-#endif
-}
-
-void wxSocketInternal::AcquireFD()
-{
-#if wxUSE_THREADS
- m_fd_locker.Lock();
-#endif
-}
-
-void wxSocketInternal::ReleaseFD()
-{
-#if wxUSE_THREADS
- m_fd_locker.Unlock();
-#endif
-}
-
-void wxSocketInternal::ResumeRequester()
-{
-#if wxUSE_THREADS
- wxThreadError err;
-
- wxASSERT(m_invalid_requester);
-
- m_end_requester.Lock();
-
- if (m_thread_requester != NULL) {
- m_thread_requester->Delete(); // We must join it.
- delete m_thread_requester;
- }
-
- m_invalid_requester = FALSE;
-
- m_end_requester.Unlock();
-
- m_thread_requester = new SocketRequester(m_socket, this);
-
- err = m_thread_requester->Create();
- wxASSERT(err == wxTHREAD_NO_ERROR);
-
- err = m_thread_requester->Run();
- wxASSERT(err == wxTHREAD_NO_ERROR);
-#else
- if (!m_invalid_requester)
- return;
- m_thread_requester = new SocketRequester(m_socket, this);
- m_invalid_requester = FALSE;
-#endif
-}
-
-void wxSocketInternal::StopRequester()
-{
-#if wxUSE_THREADS
- m_end_requester.Lock();
- if (m_invalid_requester) {
- m_end_requester.Unlock();
- if (m_thread_requester) {
- m_thread_requester->Delete();
- delete m_thread_requester;
- m_thread_requester = NULL;
- }
- m_invalid_requester = TRUE;
- return;
- }
- m_end_requester.Unlock();
-
- wxASSERT(m_thread_requester != NULL);
-
- m_request_locker.Lock();
-
- // Send a signal to the requester.
- m_socket_cond.Signal();
-
- m_request_locker.Unlock();
-
- // Finish the destruction of the requester.
- m_thread_requester->Delete();
-
- delete m_thread_requester;
- m_thread_requester = NULL;
- m_invalid_requester = TRUE;
-#else
- delete m_thread_requester;
- m_thread_requester = NULL;
- m_invalid_requester = TRUE;
-#endif
-}
-
-void wxSocketInternal::ResumeWaiter()
-{
-#if wxUSE_THREADS
- wxThreadError err;
-
- if (m_thread_waiter != NULL)
- return;
-
- m_thread_waiter = new SocketWaiter(m_socket, this);
-
- m_thread_waiter->SetPriority(WXTHREAD_MIN_PRIORITY);
-
- err = m_thread_waiter->Create();
- wxASSERT(err == wxTHREAD_NO_ERROR);
-
- err = m_thread_waiter->Run();
- wxASSERT(err == wxTHREAD_NO_ERROR);
-#endif
-}
-
-void wxSocketInternal::StopWaiter()
-{
-#if wxUSE_THREADS
- if (m_thread_waiter == NULL)
- return;
-
- m_thread_waiter->Delete();
-
- delete m_thread_waiter;
- m_thread_waiter = NULL;
-#endif
-}
-
-// ----------------------------------------------------------------------
-// QueueRequest:
-// ----------------------------------------------------------------------
-void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
-{
- if (m_invalid_requester)
- ResumeRequester();
-
-#if wxUSE_THREADS
- if (async) {
-
- m_request_locker.Lock();
- request->done = FALSE;
- m_requests.Append((wxObject *)request);
- m_socket_cond.Signal();
- m_request_locker.Unlock();
-
- // Wake up
-
- if (request->wait) {
- if (wxThread::IsMain())
- while (!request->done) {
- wxYield();
- }
- else
- while (!request->done) {
- wxThread::Yield();
- }
- }
- } else {
- m_request_locker.Lock();
-#endif
-
- if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
- m_thread_requester->ProcessWaitEvent(request);
- } else {
-
- request->done = FALSE;
-
- switch (request->type) {
- case wxSocketBase::REQ_PEEK:
- case wxSocketBase::REQ_READ:
- m_thread_requester->ProcessReadEvent(request);
- break;
- case wxSocketBase::REQ_WRITE:
- m_thread_requester->ProcessWriteEvent(request);
- break;
- }
- }
- request->done = TRUE;
-#if wxUSE_THREADS
- m_request_locker.Unlock();
- }
-#endif
-}
-
-void wxSocketInternal::WaitForEnd(SockRequest *request)
-{
-#if wxUSE_THREADS
- // TODOTODO
-#endif
-}
-
-#endif
- // __WXSTUBS__
-
-#endif
- // wxUSE_SOCKETS
#endif
void Server_OnRequest(wxSocketServer& server,
- wxSocketBase::wxRequestEvent evt,
+ GSocketEvent evt,
char *cdata);
void Client_OnRequest(wxSocketBase& sock,
- wxSocketBase::wxRequestEvent evt,
+ GSocketEvent evt,
char *cdata);
// ---------------------------------------------------------------------------
const wxString& topic)
{
wxIPV4address addr;
- wxSocketHandler *hsock = &wxSocketHandler::Master();
- wxSocketClient *client = hsock->CreateClient();
+ wxSocketClient *client = new wxSocketClient();
wxSocketStream *stream = new wxSocketStream(*client);
wxDataInputStream data_is(*stream);
wxDataOutputStream data_os(*stream);
- client->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
+ client->SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
addr.Service(server_name);
addr.Hostname(host);
bool wxTCPServer::Create(const wxString& server_name)
{
wxIPV4address addr;
- wxSocketHandler *hsock = &wxSocketHandler::Master();
wxSocketServer *server;
addr.Service(server_name);
// Create a socket listening on specified port
- server = hsock->CreateServer(addr);
+ server = new wxSocketServer(addr);
server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest);
- server->SetNotify(wxSocketBase::REQ_ACCEPT);
+ server->SetNotify(GSOCK_CONNECTION_FLAG);
server->CallbackData((char *)this);
return TRUE;
}
-void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt,
+void Client_OnRequest(wxSocketBase& sock, GSocketEvent evt,
char *cdata)
{
int msg = 0;
wxString item;
// The socket handler signals us that we lost the connection: destroy all.
- if (evt == wxSocketBase::EVT_LOST) {
+ if (evt == GSOCK_LOST) {
sock.Close();
connection->OnDisconnect();
return;
}
void Server_OnRequest(wxSocketServer& server,
- wxSocketBase::wxRequestEvent evt, char *cdata)
+ GSocketEvent evt, char *cdata)
{
wxTCPServer *ipcserv = (wxTCPServer *)cdata;
wxSocketStream *stream;
wxDataInputStream *codeci;
wxDataOutputStream *codeco;
- if (evt != wxSocketBase::EVT_ACCEPT)
+ if (evt != GSOCK_CONNECTION)
return;
/* Accept the connection, getting a new socket */
wxSocketBase *sock = server.Accept();
sock->Notify(FALSE);
- sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
+ sock->SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
stream = new wxSocketStream(*sock);
codeci = new wxDataInputStream(*stream);
{
}
-wxOutputStream& wxSocketOutputStream::Write(const void *buffer, size_t size)
-{
- m_lastcount = m_o_socket->Write((const char *)buffer, size).LastCount();
- return *this;
-}
-
size_t wxSocketOutputStream::OnSysWrite(const void *buffer, size_t size)
{
- return m_o_socket->Write((const char *)buffer, size).LastCount();
+ size_t ret;
+
+ ret = m_o_socket->Write((const char *)buffer, size).LastCount();
+ switch (m_o_socket->LastError()) {
+ case GSOCK_NOERROR:
+ m_lasterror = wxStream_NOERROR;
+ break;
+ default:
+ m_lasterror = wxStream_READ_ERR;
+ break;
+ }
+ return ret;
+
}
// ---------------------------------------------------------------------------
{
}
-wxInputStream& wxSocketInputStream::Read(void *buffer, size_t size)
-{
- m_lastcount = m_i_socket->Read((char *)buffer, size).LastCount();
- return *this;
-}
-
size_t wxSocketInputStream::OnSysRead(void *buffer, size_t size)
{
- return m_i_socket->Read((char *)buffer, size).LastCount();
+ size_t ret;
+
+ ret = m_i_socket->Read((char *)buffer, size).LastCount();
+ switch (m_i_socket->LastError()) {
+ case GSOCK_NOERROR:
+ m_lasterror = wxStream_NOERROR;
+ break;
+ default:
+ m_lasterror = wxStream_WRITE_ERR;
+ break;
+ }
+ return ret;
}
// ---------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
// Name: socket.cpp
// Purpose: Socket handler classes
-// Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
-// Davidson(1995) in wxWeb)
+// Authors: Guilhem Lavaux
// Created: April 1997
-// Updated: April 1999
-// Copyright: (C) 1999 1998, 1997, Guilhem Lavaux
+// Updated: July 1999
+// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
// RCS_ID: $Id$
// License: see wxWindows license
////////////////////////////////////////////////////////////////////////////////
#pragma implementation "socket.h"
#endif
-#ifdef __MWERKS__
-typedef int socklen_t ;
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include <wx/string.h>
#include <wx/timer.h>
#include <wx/utils.h>
-
-// IRIX requires bstring.h be included to use select()
-#ifdef sgi
- #include <bstring.h>
-#endif // IRIX
-
-// Not enough OS behaviour defined for wxStubs
-#ifndef __WXSTUBS__
+#include <wx/log.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-/////////////////////////////////////////////////////////////////////////////
-// System specific headers
-/////////////////////////////////////////////////////////////////////////////
-#ifdef __WXMAC__
-// in order to avoid problems with our c library and double definitions
-#define close closesocket
-#define ioctl ioctlsocket
-
-#include <wx/mac/macsock.h>
-
-#endif
-
-#if defined(__WINDOWS__)
-#include <winsock.h>
-#endif // __WINDOWS__
-
-#if defined(__UNIX__)
-
-#ifdef VMS
-#include <socket.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <sys/time.h>
-#include <unistd.h>
-
-#ifdef sun
-#include <sys/filio.h>
-#endif
-
-#endif // __UNIX__
-
-#include <signal.h>
-#include <errno.h>
-
-#ifdef __VISUALC__
-#include <io.h>
-#endif
-
/////////////////////////////////////////////////////////////////////////////
// wxSocket headers
/////////////////////////////////////////////////////////////////////////////
#include <wx/module.h>
-#define WXSOCK_INTERNAL
#include <wx/sckaddr.h>
#include <wx/socket.h>
-#include <wx/sckint.h>
-
-// ----------------------
-// Some patch ----- BEGIN
-// ----------------------
-#ifdef __WINDOWS__
-#define close closesocket
-#define ioctl ioctlsocket
-#ifdef errno
-#undef errno
-#endif
-#define errno WSAGetLastError()
-#ifdef EWOULDBLOCK
-#undef EWOULDBLOCK
-#endif
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define ETIMEDOUT WSAETIMEDOUT
-#undef EINTR
-#define EINTR WSAEINTR
-#endif
-
-#ifndef __WINDOWS__
-#define INVALID_SOCKET -1
-#endif
-
-#ifdef __WINDOWS__
-// This is an MS TCP/IP routine and is not needed here. Some WinSock
-// 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( __VISUALC__ )
-int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
-{
- int i = set->fd_count;
-
- while (i--)
- {
- if (set->fd_array[i] == fd)
- return 1;
- }
-
- return 0;
-}
-#endif
-#endif
-
-// -------------------
-// Some patch ---- END
-// -------------------
-
-#ifdef GetClassInfo
-#undef GetClassInfo
-#endif
-
-// --------------------------------------------------------------
-// Module
-// --------------------------------------------------------------
-class wxSocketModule: public wxModule
-{
- DECLARE_DYNAMIC_CLASS(wxSocketModule)
-public:
- wxSocketModule() {}
- bool OnInit();
- void OnExit();
-};
// --------------------------------------------------------------
// ClassInfos
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 wxSocketState : public wxObject {
+public:
+ bool notify_state;
+ GSocketEventFlags evt_notify_state;
+ wxSocketBase::wxSockFlags socket_flags;
+ wxSocketBase::wxSockCbk c_callback;
+ char *c_callback_data;
+
+public:
+ wxSocketState() : wxObject() {}
+};
+
// --------------------------------------------------------------
// --------- wxSocketBase CONSTRUCTOR ---------------------------
// --------------------------------------------------------------
wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
wxSocketBase::wxSockType _type) :
wxEvtHandler(),
- m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
- m_fd(INVALID_SOCKET), m_id(-1),
- m_handler(0),
- m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
- m_timeout(3600),
- m_unread(NULL), m_unrd_size(0),
+ m_socket(NULL), m_flags(_flags), m_type(_type),
+ m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
+ m_lcount(0), m_timeout(3600),
+ m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
m_cbk(NULL), m_cdata(NULL),
- m_notify_state(FALSE)
+ m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
+ m_defering(NO_DEFER),
+ m_states()
{
- m_internal = new wxSocketInternal(this);
}
wxSocketBase::wxSocketBase() :
wxEvtHandler(),
- m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
- m_connecting(FALSE), m_fd(INVALID_SOCKET),
- m_id(-1), m_handler(0),
- m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
- m_timeout(3600),
- m_unread(NULL), m_unrd_size(0),
+ m_socket(NULL), m_flags((wxSockFlags)SPEED | WAITALL), m_type(SOCK_UNINIT),
+ m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
+ m_lcount(0), m_timeout(3600),
+ m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
m_cbk(NULL), m_cdata(NULL),
- m_notify_state(FALSE)
+ m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
+ m_defering(NO_DEFER),
+ m_states()
{
- m_internal = new wxSocketInternal(this);
}
// --------------------------------------------------------------
-// wxSocketBase
+// wxSocketBase destructor
// --------------------------------------------------------------
wxSocketBase::~wxSocketBase()
{
- // First, close the file descriptor.
- Close();
-
if (m_unread)
free(m_unread);
- // Unregister from the handler database.
- if (m_handler)
- m_handler->UnRegister(this);
- // Destroy all saved states.
- m_states.DeleteContents(TRUE);
+ // At last, close the file descriptor.
+ Close();
- // Destroy the socket manager.
- delete m_internal;
+ if (m_socket)
+ GSocket_destroy(m_socket);
}
bool wxSocketBase::Close()
{
- if (m_fd != INVALID_SOCKET)
+ if (m_socket)
{
if (m_notify_state == TRUE)
Notify(FALSE);
// Shutdown the connection.
- shutdown(m_fd, 2);
- close(m_fd);
- m_fd = INVALID_SOCKET;
+ GSocket_Shutdown(m_socket);
m_connected = FALSE;
}
// wxSocketBase base IO function
// --------------------------------------------------------------
+int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
+{
+ GSocketEventFlags old_event_flags;
+ bool old_notify_state;
+
+ wxASSERT(m_defering == NO_DEFER);
+
+ m_defering = DEFER_READ;
+
+ old_event_flags = NeededReq();
+ old_notify_state = m_notify_state;
+
+ SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
+ Notify(TRUE);
+
+ m_defer_buffer = buffer;
+ m_defer_nbytes = nbytes;
+ while (m_defer_buffer != NULL)
+ wxYield();
+
+ Notify(old_notify_state);
+ SetNotify(old_event_flags);
+
+ m_defering = NO_DEFER;
+
+ return nbytes-m_defer_nbytes;
+}
+
wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
{
+ int ret = 1;
+
m_lcount = GetPushback(buffer, nbytes, FALSE);
nbytes -= m_lcount;
buffer += m_lcount;
+ if (!m_connected)
+ return *this;
+
// 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)) ) {
return *this;
}
- WantBuffer(buffer, nbytes, EVT_READ);
+ if ((m_flags & SPEED) != 0) {
+
+ if ((m_flags & WAITALL) != 0) {
+ while (ret > 0 && nbytes > 0) {
+ ret = GSocket_Read(m_socket, buffer, nbytes);
+ m_lcount += ret;
+ buffer += ret;
+ nbytes -= ret;
+ }
+ // In case the last call was an error ...
+ if (ret < 0)
+ m_lcount ++;
+ } else {
+ ret = GSocket_Read(m_socket, buffer, nbytes);
+ if (ret > 0)
+ m_lcount += ret;
+ }
+
+ } else {
+ ret = DeferRead(buffer, nbytes);
+
+ if (ret > 0)
+ m_lcount += ret;
+ }
return *this;
}
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;
+ wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
return *this;
}
wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
{
- m_lcount = GetPushback(buffer, nbytes, TRUE);
- if (nbytes-m_lcount == 0)
- {
- return *this;
- }
- buffer += m_lcount;
- nbytes -= m_lcount;
-
- WantBuffer(buffer, nbytes, EVT_PEEK);
+ Read(buffer, nbytes);
+ CreatePushbackAfter(buffer, nbytes);
return *this;
}
+int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
+{
+ GSocketEventFlags old_event_flags;
+ bool old_notify_state;
+
+ wxASSERT(m_defering == NO_DEFER);
+
+ m_defering = DEFER_WRITE;
+
+ old_event_flags = NeededReq();
+ old_notify_state = m_notify_state;
+
+ SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
+ Notify(TRUE);
+
+ m_defer_buffer = (char *)buffer;
+ m_defer_nbytes = nbytes;
+ while (m_defer_buffer != NULL)
+ wxYield();
+
+ Notify(old_notify_state);
+ SetNotify(old_event_flags);
+
+ m_defering = NO_DEFER;
+
+ return nbytes-m_defer_nbytes;
+}
+
wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
{
- m_lcount = 0;
- WantBuffer((char *)buffer, nbytes, EVT_WRITE);
+ int ret;
+
+ if ((m_flags & SPEED) != 0)
+ ret = GSocket_Write(m_socket, buffer, nbytes);
+ else
+ ret = DeferWrite(buffer, nbytes);
+
+ if (ret != -1)
+ m_lcount += ret;
+
return *this;
}
bool wxSocketBase::IsData() const
{
- struct timeval tv;
- fd_set sock_set;
-
- if (m_fd < 0)
+ if (!m_socket)
return FALSE;
- if (m_unrd_size > 0)
- return TRUE;
- m_internal->AcquireFD();
+ return (GSocket_DataAvailable(m_socket));
+}
+
+void wxSocketBase::DoDefer(GSocketEvent req_evt)
+{
+ int ret;
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- FD_ZERO(&sock_set);
- FD_SET(m_fd, &sock_set);
- select(m_fd+1, &sock_set, NULL, NULL, &tv);
+ if (req_evt == GSOCK_LOST) {
+ Close();
+ m_defer_buffer = NULL;
+ return;
+ }
+ switch (m_defering) {
+ case DEFER_READ:
+ ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
+ break;
+ case DEFER_WRITE:
+ ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
+ break;
+ default:
+ ret = -1;
+ break;
+ }
- m_internal->ReleaseFD();
+ m_defer_nbytes -= ret;
- return (FD_ISSET(m_fd, &sock_set) != 0);
+ if (ret < 0)
+ m_defer_nbytes++;
+
+ if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) {
+ m_defer_buffer = NULL;
+ Notify(FALSE);
+ } else
+ m_defer_buffer += ret;
}
// ---------------------------------------------------------------------
#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 wxHAVE_GLIBC2
-# define wxSOCKET_INT socklen_t
-#else
-# define wxSOCKET_INT int
-#endif
-
// --------------------------------------------------------------
// wxSocketBase socket info functions
// --------------------------------------------------------------
bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
{
- struct sockaddr my_addr;
- wxSOCKET_INT len_addr = sizeof(my_addr);
+ GAddress *peer;
- if (m_fd < 0)
+ if (!m_socket)
return FALSE;
- m_internal->AcquireFD();
+ peer = GSocket_GetPeer(m_socket);
+ addr_man.SetAddress(peer);
+ GAddress_destroy(peer);
- if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) {
- m_internal->ReleaseFD();
- return FALSE;
- }
-
- m_internal->ReleaseFD();
- addr_man.Disassemble(&my_addr, len_addr);
return TRUE;
}
bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
{
- struct sockaddr my_addr;
- wxSOCKET_INT len_addr = sizeof(my_addr);
+ GAddress *local;
- if (m_fd < 0)
+ if (!m_socket)
return FALSE;
- m_internal->AcquireFD();
-
- if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) {
- m_internal->ReleaseFD();
- return FALSE;
- }
- m_internal->ReleaseFD();
+ local = GSocket_GetLocal(m_socket);
+ addr_man.SetAddress(local);
+ GAddress_destroy(local);
- addr_man.Disassemble(&my_addr, len_addr);
return TRUE;
}
void wxSocketBase::SaveState()
{
- SocketState *state = new SocketState;
+ wxSocketState *state;
+
+ state = new wxSocketState();
state->notify_state = m_notify_state;
state->evt_notify_state = m_neededreq;
state->c_callback = m_cbk;
state->c_callback_data = m_cdata;
- m_states.Append((wxObject *)state);
+ m_states.Append(state);
}
void wxSocketBase::RestoreState()
{
wxNode *node;
- SocketState *state;
+ wxSocketState *state;
node = m_states.Last();
if (!node)
return;
- state = (SocketState *)node->Data();
+ state = (wxSocketState *)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);
// --------- wxSocketBase wait functions ------------------------
// --------------------------------------------------------------
+class _wxSocketInternalTimer: public wxTimer {
+ public:
+ int *m_state;
+
+ void Notify()
+ {
+ *m_state = GSOCK_MAX_EVENT; // Just to say it's a timeout.
+ }
+};
+
+static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
+{
+ int *state = (int *)cdata;
+
+ *state = event;
+}
+
bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
{
- SockRequest *req;
+ bool old_notify_state = m_notify_state;
+ int state = 0;
+ _wxSocketInternalTimer timer;
- if ((!m_connected && !m_connecting) || m_fd < 0)
+ if (!m_connected || !m_socket)
return FALSE;
- req = new SockRequest;
+ timer.m_state = &state;
+
+ Notify(FALSE);
+
+ timer.Start(seconds * 1000 + milliseconds, TRUE);
+ GSocket_SetFallback(m_socket, type, wx_socket_wait, (char *)&state);
- req->type = REQ_WAIT | type;
- req->timeout = seconds * 1000 + milliseconds;
- req->done = FALSE;
- req->buffer = NULL;
- req->size = 0;
- req->error = 0;
- req->wait = TRUE;
- m_internal->QueueRequest(req, TRUE);
+ while (state == 0)
+ wxYield();
- return (req->io_nbytes != 0);
+ GSocket_UnsetFallback(m_socket, type);
+ timer.Stop();
+
+ Notify(old_notify_state);
+
+ return (state != GSOCK_MAX_EVENT);
}
bool wxSocketBase::Wait(long seconds, long milliseconds)
{
- return _Wait(seconds, milliseconds, REQ_ACCEPT | REQ_CONNECT |
- REQ_READ | REQ_WRITE | REQ_LOST);
+ return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
+ GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
}
bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
{
- return _Wait(seconds, milliseconds, REQ_READ | REQ_LOST);
+ return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
}
bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
{
- return _Wait(seconds, milliseconds, REQ_WRITE);
+ return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
}
bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
{
- return _Wait(seconds, milliseconds, REQ_LOST);
+ return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
}
// --------------------------------------------------------------
// --------- wxSocketBase callback management -------------------
// --------------------------------------------------------------
-wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
+GSocketEventFlags wxSocketBase::EventToNotify(GSocketEvent evt)
{
switch (evt)
{
- case EVT_READ:
- return REQ_READ;
- case EVT_PEEK:
- return REQ_PEEK;
- case EVT_WRITE:
- return REQ_WRITE;
- case EVT_LOST:
- return REQ_LOST;
- case EVT_ACCEPT:
- return REQ_ACCEPT;
- case EVT_CONNECT:
- return REQ_CONNECT;
+ case GSOCK_INPUT:
+ return GSOCK_INPUT_FLAG;
+ case GSOCK_OUTPUT:
+ return GSOCK_OUTPUT_FLAG;
+ case GSOCK_CONNECTION:
+ return GSOCK_CONNECTION_FLAG;
+ case GSOCK_LOST_FLAG:
+ return GSOCK_LOST_FLAG;
+ default:
+ return 0;
}
return 0;
}
void wxSocketBase::SetFlags(wxSockFlags _flags)
{
m_flags = _flags;
- if (_flags & SPEED) {
- // SPEED and WAITALL are antagonists.
- m_flags = (wxSockFlags)(m_flags & ~WAITALL);
- }
}
wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
return m_flags;
}
-void wxSocketBase::SetNotify(wxRequestNotify flags)
+void wxSocketBase::SetNotify(GSocketEventFlags flags)
{
/* Check if server */
if (m_type != SOCK_SERVER)
- flags &= ~REQ_ACCEPT;
+ flags &= ~GSOCK_CONNECTION_FLAG;
- m_internal->AcquireData();
m_neededreq = flags;
- m_internal->ReleaseData();
if (m_neededreq == 0)
- m_internal->StopWaiter();
+ Notify(FALSE);
else
Notify(m_notify_state);
}
+// --------------------------------------------------------------
+// Automatic notifier
+// --------------------------------------------------------------
+
+static void wx_socket_fallback(GSocket *socket, GSocketEvent event, char *cdata)
+{
+ wxSocketBase *sckobj = (wxSocketBase *)cdata;
+
+ sckobj->OnRequest(event);
+}
+
void wxSocketBase::Notify(bool notify)
{
m_notify_state = notify;
- if (m_fd == INVALID_SOCKET)
+ if (!m_socket)
return;
- if (notify)
- m_internal->ResumeWaiter();
- else
- m_internal->StopWaiter();
+ GSocket_UnsetFallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
+ GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
+ if (!notify)
+ return;
+
+ GSocket_SetFallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
}
-void wxSocketBase::OnRequest(wxRequestEvent req_evt)
+void wxSocketBase::OnRequest(GSocketEvent req_evt)
{
wxSocketEvent event(m_id);
- wxRequestNotify notify = EventToNotify(req_evt);
+ GSocketEventFlags notify = EventToNotify(req_evt);
+
+ if (m_defering != NO_DEFER) {
+ DoDefer(req_evt);
+ return;
+ }
if ((m_neededreq & notify) == notify) {
event.m_socket = this;
event.m_skevt = req_evt;
ProcessEvent(event);
- // TODOTODO
- // OldOnNotify(req_evt);
-
- // We disable the event reporting.
- m_neededreq &= ~notify;
+ OldOnNotify(req_evt);
}
-}
-
-wxSocketEvent::wxSocketEvent(int id)
- : wxEvent(id)
-{
- wxEventType type = (wxEventType)wxEVT_SOCKET;
-
- SetEventType(type);
-}
-
-void wxSocketEvent::CopyObject(wxObject& obj_d) const
-{
- wxSocketEvent *event = (wxSocketEvent *)&obj_d;
-
- wxEvent::CopyObject(obj_d);
- event->m_skevt = m_skevt;
- event->m_socket = m_socket;
+ if (req_evt == GSOCK_LOST)
+ Close();
}
-void wxSocketBase::OldOnNotify(wxRequestEvent evt)
+void wxSocketBase::OldOnNotify(GSocketEvent evt)
{
}
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);
void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
{
- char *curr_pos, *new_buf;
-
- new_buf = (char *) malloc(m_unrd_size+size);
- curr_pos = new_buf + size;
+ if (m_unread == NULL)
+ m_unread = (char *)malloc(size);
+ else {
+ char *tmp;
- memcpy(new_buf, buffer, size);
- if (m_unrd_size != 0) {
- memcpy(curr_pos, m_unread, m_unrd_size);
+ tmp = (char *)malloc(m_unrd_size + size);
+ memcpy(tmp+size, m_unread, m_unrd_size);
free(m_unread);
+
+ m_unread = tmp;
}
- m_unread = new_buf;
+
m_unrd_size += size;
+
+ memcpy(m_unread, buffer, size);
}
size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
if (!m_unrd_size)
return 0;
- if (size > m_unrd_size)
- size = m_unrd_size;
- memcpy(buffer, m_unread, size);
+ if (size > (m_unrd_size-m_unrd_cur))
+ size = m_unrd_size-m_unrd_cur;
+ memcpy(buffer, (m_unread+m_unrd_cur), size);
if (!peek) {
- m_unrd_size -= size;
- if (m_unrd_size == 0) {
+ m_unrd_cur += size;
+ if (m_unrd_size == m_unrd_cur) {
free(m_unread);
m_unread = NULL;
+ m_unrd_size = 0;
+ m_unrd_cur = 0;
}
}
return size;
}
-// --------------------------------------------------------------
-// --------- wxSocketBase buffer core requester -----------------
-// --------------------------------------------------------------
-
-void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
- wxRequestEvent evt)
-{
- bool buf_timed_out;
-
- if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
- return;
-
- SockRequest *buf = new SockRequest;
-
- SaveState();
- buf->buffer = buffer;
- buf->size = nbytes;
- buf->done = FALSE;
- buf->type = EventToNotify(evt);
- buf->io_nbytes = 0;
- buf->error = 0;
- buf->wait = TRUE;
- buf->timeout = 1000;
- buf_timed_out = FALSE;
-
- if ((m_flags & SPEED) != 0)
- m_internal->QueueRequest(buf, FALSE);
- else
- if ((m_flags & NOWAIT) != 0)
- m_internal->QueueRequest(buf, TRUE);
- else
- m_internal->QueueRequest(buf, TRUE);
- m_lcount += buf->io_nbytes;
- if (buf_timed_out)
- m_error = ETIMEDOUT;
- else
- m_error = buf->error;
-
- delete buf;
- RestoreState();
-}
-
// --------------------------------------------------------------
// wxSocketServer
// --------------------------------------------------------------
wxSockFlags flags) :
wxSocketBase(flags, SOCK_SERVER)
{
- m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
+ m_socket = GSocket_new();
- if (m_fd == INVALID_SOCKET)
+ if (!m_socket)
return;
- int flag = 1;
- setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
-
- struct sockaddr *myaddr;
- size_t len;
-
- addr_man.Build(myaddr, len);
- if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0)
- return;
-
- if (listen(m_fd, 5) < 0) {
- m_fd = INVALID_SOCKET;
+ GSocket_SetLocal(m_socket, addr_man.GetAddress());
+ if (GSocket_SetServer(m_socket) != GSOCK_NOERROR) {
+ GSocket_destroy(m_socket);
+ m_socket = NULL;
return;
}
- m_internal->SetFD(m_fd);
-
Notify(TRUE);
}
bool wxSocketServer::AcceptWith(wxSocketBase& sock)
{
- int fd2;
-
- m_internal->AcquireFD();
- if ((fd2 = accept(m_fd, 0, 0)) < 0) {
- m_internal->ReleaseFD();
- return FALSE;
- }
- m_internal->ReleaseFD();
+ GSocket *child_socket;
- struct linger linger;
- linger.l_onoff = 0;
- linger.l_linger = 1;
-
- setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
-
- int flag = 0;
- setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
+ child_socket = GSocket_WaitConnection(m_socket);
sock.m_type = SOCK_INTERNAL;
- sock.m_fd = fd2;
+ sock.m_socket = child_socket;
sock.m_connected = TRUE;
- sock.m_internal->SetFD(fd2);
-
- sock.m_internal->ResumeWaiter();
-
return TRUE;
}
if (!AcceptWith(*sock))
return NULL;
- if (m_handler)
- m_handler->Register(sock);
-
return sock;
}
// --------------------------------------------------------------
bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
{
- struct linger linger;
-
if (IsConnected())
Close();
+ // This should never happen.
+ if (m_socket)
+ GSocket_destroy(m_socket);
+
// Initializes all socket stuff ...
// --------------------------------
- m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
+ m_socket = GSocket_new();
- if (m_fd < 0)
+ if (!m_socket)
return FALSE;
m_connected = FALSE;
- linger.l_onoff = 1;
- linger.l_linger = 5;
- setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
-
- // Stay in touch with the state of things...
-
- unsigned long flag = 1;
- setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
-
- // Disable the nagle algorithm, which delays sends till the
- // buffer is full (or a certain time period has passed?)...
-
-#if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY))
- flag = 1;
- setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
-#endif
-
- struct sockaddr *remote;
- size_t len;
-
- addr_man.Build(remote, len);
-
- if (connect(m_fd, remote, len) != 0)
+ // Update the flags of m_socket.
+ SetFlags(m_flags);
+ GSocket_SetPeer(m_socket, addr_man.GetAddress());
+ if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR) {
return FALSE;
-
- m_internal->SetFD(m_fd);
+ }
// Enables bg events.
// ------------------
bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
{
- int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST);
+ int ret = _Wait(seconds, microseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
if (ret)
m_connected = TRUE;
return m_connected;
}
-void wxSocketClient::OnRequest(wxRequestEvent evt)
+void wxSocketClient::OnRequest(GSocketEvent evt)
{
- if (evt == EVT_CONNECT)
+ if (evt == GSOCK_CONNECTION)
{
if (m_connected)
{
- m_neededreq &= ~REQ_CONNECT;
+ m_neededreq &= ~GSOCK_CONNECTION_FLAG;
return;
}
m_connected = TRUE;
wxSocketBase::OnRequest(evt);
}
-/////////////////////////////////////////////////////////////////
-// wxSocketHandler ///////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
-wxSocketHandler *wxSocketHandler::master = NULL;
-#if defined(__WINDOWS__)
-static int win_initialized = 0;
-#endif
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler CONSTRUCTOR ------------------------
-// --------------------------------------------------------------
-wxSocketHandler::wxSocketHandler()
-{
-#if defined(__WINDOWS__)
- if (!win_initialized)
- {
- WSADATA wsaData;
-
- WSAStartup((1 << 8) | 1, &wsaData);
- win_initialized = 1;
- }
-#endif
-
- socks = new wxList;
-
-#ifndef __WINDOWS__
- signal(SIGPIPE, SIG_IGN);
-#endif
-}
-
// --------------------------------------------------------------
-// --------- wxSocketHandler DESTRUCTOR -------------------------
+// wxSocketEvent
// --------------------------------------------------------------
-wxSocketHandler::~wxSocketHandler()
-{
- wxNode *next_node, *node = socks->First();
- while (node)
- {
- wxSocketBase* sock = (wxSocketBase*)node->Data();
-
- delete sock;
- next_node = node->Next();
- delete node;
- node = next_node;
- }
-
- delete socks;
-
-#ifdef __WINDOWS__
- WSACleanup();
- win_initialized = 0;
-#endif
-}
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler registering functions --------------
-// --------------------------------------------------------------
-
-void wxSocketHandler::Register(wxSocketBase* sock)
-{
- wxNode *node;
-
- for (node = socks->First(); node != NULL; node = node->Next())
- {
- wxSocketBase* s = (wxSocketBase*)node->Data();
-
- if (s == sock)
- return;
- }
-
- if (sock)
- {
- socks->Append(sock);
- sock->SetHandler(this);
- }
-}
-
-void wxSocketHandler::UnRegister(wxSocketBase* sock)
-{
- wxNode *node;
-
- for (node = socks->First(); node; node = node->Next())
- {
- wxSocketBase* s = (wxSocketBase*)node->Data();
-
- if (s == sock)
- {
- delete node;
- sock->SetHandler(NULL);
- return;
- }
- }
-}
-
-unsigned long wxSocketHandler::Count() const
-{
- return socks->Number();
-}
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler "big" wait functions ---------------
-// --------------------------------------------------------------
-
-int wxSocketHandler::Wait(long seconds, long microseconds)
-{
- // TODO Needs the completely asynchronous notifier.
-
- /*
- int i;
- int on_wait;
- wxNode *node;
- for (node = socks->First(), i=0; node; node = node->Next(), i++)
- {
- wxSocketBase *sock = (wxSocketBase *)node->Data();
-
- sock->SaveState();
-
- sock->SetupCallbacks();
-
- sock->Callback(handler_cbk);
- sock->CallbackData((char *)&on_wait);
- }
- on_wait = 0;
- if (seconds != -1)
- s_wake.Start((seconds*1000) + (microseconds/1000), TRUE);
-
- while (!on_wait)
- PROCESS_EVENTS();
-
- for (node = socks->First(), i=0; node; node = node->Next(), i++)
- {
- wxSocketBase *sock = (wxSocketBase *)node->Data();
-
- sock->RestoreState();
- }
-
- if (on_wait == -2)
- return 0;
-
- return on_wait;
- */
- return 0;
-}
-
-void wxSocketHandler::YieldSock()
-{
- wxNode *node;
-
- // Nothing to do anymore here except waiting for the queue emptying.
- for (node = socks->First(); node; node=node->Next()) {
- wxSocketBase *sock = (wxSocketBase *)node->Data();
-
- sock->m_internal->WaitForEnd(NULL);
- }
-}
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler: create and register the socket ----
-// --------------------------------------------------------------
-wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
- wxSocketBase::wxSockFlags flags)
+wxSocketEvent::wxSocketEvent(int id)
+ : wxEvent(id)
{
- wxSocketServer *serv = new wxSocketServer(addr, flags);
+ wxEventType type = (wxEventType)wxEVT_SOCKET;
- Register(serv);
- return serv;
+ SetEventType(type);
}
-wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
+void wxSocketEvent::CopyObject(wxObject& obj_d) const
{
- wxSocketClient *client = new wxSocketClient(flags);
-
- Register(client);
- return client;
-}
+ wxSocketEvent *event = (wxSocketEvent *)&obj_d;
-bool wxSocketModule::OnInit()
-{
- wxSocketHandler::master = new wxSocketHandler();
- return TRUE;
-}
+ wxEvent::CopyObject(obj_d);
-void wxSocketModule::OnExit()
-{
- delete wxSocketHandler::master;
- wxSocketHandler::master = NULL;
+ event->m_skevt = m_skevt;
+ event->m_socket = m_socket;
}
-#endif
- // __WXSTUBS__
-
#endif
// wxUSE_SOCKETS
{
size_t s_toget = m_wbacksize-m_wbackcur;
+ if (!m_wback)
+ return 0;
+
if (bsize < s_toget)
s_toget = bsize;
char *buf = (char *)buffer;
retsize = GetWBack(buf, size);
+ m_lastcount = retsize;
if (retsize == size) {
- m_lastcount = size;
m_lasterror = wxStream_NOERROR;
return *this;
}
wxOutputStream& wxBufferedOutputStream::Write(const void *buffer, size_t size)
{
+ m_lastcount = 0;
m_o_streambuf->Write(buffer, size);
return *this;
}
return *TEXTCTRL(this);
}
-wxTextCtrl& wxTextCtrlBase::operator<<(const char c)
+wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c)
{
return operator<<(wxString(c));
}
m_protoinfo = info;
m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
- wxSocketHandler::Master().Register(m_protocol);
return TRUE;
}
info = info->next;
if (!isalpha(c) && c != _T('.') && c != _T('+') && c != _T('.') &&
c != _T('/')) {
- hexa_code.Printf(_T("%02X"), c);
+ hexa_code.Printf(_T("%%%02X"), c);
out_str += hexa_code;
} else
out_str += c;
size_t wxFileOutputStream::OnSysWrite(const void *buffer, size_t size)
{
size_t ret = m_file->Write(buffer, size);
- m_lasterror = wxStream_EOF; // TODO
+ if (m_file->Error())
+ m_lasterror = wxStream_WRITE_ERR;
+ else
+ m_lasterror = wxStream_NOERROR;
return ret;
}
win_gtk.c \
extended.c \
parser.c \
+ gsocket.c \
+ gsockgtk.c \
\
cmndata.cpp \
config.cpp \
resource.cpp \
sckaddr.cpp \
sckfile.cpp \
- sckint.cpp \
sckipc.cpp \
sckstrm.cpp \
serbase.cpp \
--- /dev/null
+#include <stdlib.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <wx/gsocket.h>
+#include "../unix/gsockunx.h"
+
+void _GSocket_GDK_Input(gpointer data, gint source, GdkInputCondition condition)
+{
+ GSocket *socket = (GSocket *)data;
+
+ switch (condition) {
+ case GDK_INPUT_READ:
+ _GSocket_Detected_Read(socket);
+ break;
+ case GDK_INPUT_WRITE:
+ _GSocket_Detected_Write(socket);
+ break;
+ default:
+ break;
+ }
+}
+
+void _GSocket_GUI_Init(GSocket *socket)
+{
+ int i;
+ gint *m_id;
+
+ socket->m_gui_dependent = (char *)malloc(sizeof(gint)*3);
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ for (i=0;i<3;i++)
+ m_id[i] = -1;
+}
+
+void _GSocket_GUI_Destroy(GSocket *socket)
+{
+ int i;
+ gint *m_id;
+
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ for (i=0;i<3;i++)
+ if (m_id[i] == -1)
+ gdk_input_remove(m_id[i]);
+
+ free(socket->m_gui_dependent);
+}
+
+void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
+{
+ GdkInputCondition flag;
+ int c;
+ gint *m_id;
+
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ switch (event) {
+ case GSOCK_CONNECTION:
+ case GSOCK_LOST:
+ case GSOCK_INPUT: c = 0; flag = GDK_INPUT_READ; break;
+ case GSOCK_OUTPUT: c = 1;flag = GDK_INPUT_WRITE; break;
+ default: return;
+ }
+
+ if (m_id[c] != -1)
+ gdk_input_remove(m_id[c]);
+
+ m_id[c] = gdk_input_add(socket->m_fd, flag,
+ _GSocket_GDK_Input, (gpointer)socket);
+}
+
+void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
+{
+ int c;
+ gint *m_id;
+
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ switch (event) {
+ case GSOCK_CONNECTION:
+ case GSOCK_LOST:
+ case GSOCK_INPUT: c = 0; break;
+ case GSOCK_OUTPUT: c = 1; break;
+ default: return;
+ }
+
+ if (m_id[c] != -1)
+ gdk_input_remove(m_id[c]);
+
+ m_id[c] = -1;
+}
+
+unsigned long GSocket_GetEventID(GSocket *socket)
+{
+ return 0;
+}
+
+void GSocket_DoEvent(unsigned long evt_id)
+{
+}
win_gtk.c \
extended.c \
parser.c \
+ gsocket.c \
+ gsockgtk.c \
\
cmndata.cpp \
config.cpp \
resource.cpp \
sckaddr.cpp \
sckfile.cpp \
- sckint.cpp \
sckipc.cpp \
sckstrm.cpp \
serbase.cpp \
--- /dev/null
+#include <stdlib.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <wx/gsocket.h>
+#include "../unix/gsockunx.h"
+
+void _GSocket_GDK_Input(gpointer data, gint source, GdkInputCondition condition)
+{
+ GSocket *socket = (GSocket *)data;
+
+ switch (condition) {
+ case GDK_INPUT_READ:
+ _GSocket_Detected_Read(socket);
+ break;
+ case GDK_INPUT_WRITE:
+ _GSocket_Detected_Write(socket);
+ break;
+ default:
+ break;
+ }
+}
+
+void _GSocket_GUI_Init(GSocket *socket)
+{
+ int i;
+ gint *m_id;
+
+ socket->m_gui_dependent = (char *)malloc(sizeof(gint)*3);
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ for (i=0;i<3;i++)
+ m_id[i] = -1;
+}
+
+void _GSocket_GUI_Destroy(GSocket *socket)
+{
+ int i;
+ gint *m_id;
+
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ for (i=0;i<3;i++)
+ if (m_id[i] == -1)
+ gdk_input_remove(m_id[i]);
+
+ free(socket->m_gui_dependent);
+}
+
+void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
+{
+ GdkInputCondition flag;
+ int c;
+ gint *m_id;
+
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ switch (event) {
+ case GSOCK_CONNECTION:
+ case GSOCK_LOST:
+ case GSOCK_INPUT: c = 0; flag = GDK_INPUT_READ; break;
+ case GSOCK_OUTPUT: c = 1;flag = GDK_INPUT_WRITE; break;
+ default: return;
+ }
+
+ if (m_id[c] != -1)
+ gdk_input_remove(m_id[c]);
+
+ m_id[c] = gdk_input_add(socket->m_fd, flag,
+ _GSocket_GDK_Input, (gpointer)socket);
+}
+
+void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
+{
+ int c;
+ gint *m_id;
+
+ m_id = (gint *)(socket->m_gui_dependent);
+
+ switch (event) {
+ case GSOCK_CONNECTION:
+ case GSOCK_LOST:
+ case GSOCK_INPUT: c = 0; break;
+ case GSOCK_OUTPUT: c = 1; break;
+ default: return;
+ }
+
+ if (m_id[c] != -1)
+ gdk_input_remove(m_id[c]);
+
+ m_id[c] = -1;
+}
+
+unsigned long GSocket_GetEventID(GSocket *socket)
+{
+ return 0;
+}
+
+void GSocket_DoEvent(unsigned long evt_id)
+{
+}
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name: gsocket.c
+ * Purpose: GSocket main Unix file
+ * CVSID: $Id$
+ * Log: $Log$
+ * Log: Revision 1.1 1999/07/22 17:51:54 GL
+ * Log: Added GSocket for Unix (only GTK for the moment)
+ * Log: Updated wxSocket to use GSocket API
+ * Log: Added a progress bar to client.cpp
+ * Log: Added CopyTo to wxMemoryOutputStream to copy the internal buffer to a specified buffer.
+ * Log: Various changes/fixes to the high-level protocols FTP/HTTP
+ * Log: Various Unicode fixes
+ * Log: Removed sckint.*
+ * Log:
+ * Log: Revision 1.2 1999/07/18 15:52:34 guilhem
+ * Log: * Copyright, etc.
+ * Log:
+ * -------------------------------------------------------------------------
+ */
+
+#include <assert.h>
+#include <sys/ioctl.h>
+#ifdef vms
+#include <socket.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef sun
+#include <sys/filio.h>
+#endif
+
+#ifdef sgi
+ #include <bstring.h>
+#endif
+
+#include <signal.h>
+
+#include <wx/gsocket.h>
+#include "gsockunx.h"
+
+/* Constructors / Destructors */
+
+GSocket *GSocket_new()
+{
+ int i;
+ GSocket *socket;
+
+ socket = (GSocket *)malloc(sizeof(GSocket));
+
+ socket->m_fd = -1;
+ for (i=0;i<GSOCK_MAX_EVENT;i++) {
+ socket->m_fbacks[i] = NULL;
+ socket->m_iocalls[i] = FALSE;
+ }
+ socket->m_local = NULL;
+ socket->m_peer = NULL;
+ socket->m_error = GSOCK_NOERROR;
+ socket->m_server = FALSE;
+ socket->m_stream = TRUE;
+ socket->m_gui_dependent = NULL;
+ socket->m_blocking = FALSE;
+
+ _GSocket_GUI_Init(socket);
+
+ return socket;
+}
+
+void GSocket_destroy(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ _GSocket_GUI_Destroy(socket);
+
+ if (socket->m_fd != -1)
+ GSocket_Shutdown(socket);
+
+ if (socket->m_local)
+ GAddress_destroy(socket->m_local);
+
+ if (socket->m_peer)
+ GAddress_destroy(socket->m_peer);
+
+ free(socket);
+}
+
+void GSocket_Shutdown(GSocket *socket)
+{
+ int evt;
+
+ assert(socket != NULL);
+
+ if (socket->m_fd != -1) {
+ shutdown(socket->m_fd, 2);
+ close(socket->m_fd);
+ socket->m_fd = -1;
+ }
+
+ for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
+ _GSocket_Uninstall_Fallback(socket, evt);
+}
+
+/* Address handling */
+
+GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
+{
+ if (socket == NULL || (socket->m_fd != -1 && !socket->m_server))
+ return GSOCK_INVSOCK;
+
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY)
+ return GSOCK_INVADDR;
+
+ if (socket->m_local)
+ GAddress_destroy(socket->m_local);
+
+ socket->m_local = GAddress_copy(address);
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
+{
+ if (socket == NULL)
+ return GSOCK_INVSOCK;
+
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
+ socket->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ if (socket->m_peer)
+ GAddress_destroy(socket->m_peer);
+
+ socket->m_peer = GAddress_copy(address);
+
+ return GSOCK_NOERROR;
+}
+
+GAddress *GSocket_GetLocal(GSocket *socket)
+{
+ GAddress *address;
+ struct sockaddr addr;
+ socklen_t size;
+
+ assert(socket != NULL);
+
+ if (socket->m_local)
+ return GAddress_copy(socket->m_local);
+
+ if (socket->m_fd == -1) {
+ socket->m_error = GSOCK_INVSOCK;
+ return NULL;
+ }
+
+ size = sizeof(addr);
+
+ if (getsockname(socket->m_fd, &addr, &size) < 0) {
+ socket->m_error = GSOCK_IOERR;
+ return NULL;
+ }
+
+ address = GAddress_new();
+ _GAddress_translate_from(address, &addr, size);
+
+ return address;
+}
+
+GAddress *GSocket_GetPeer(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ if (socket->m_peer)
+ return GAddress_copy(socket->m_peer);
+
+ return NULL;
+}
+
+/* Server specific parts */
+
+/*
+ GSocket_SetServer() setup the socket as a server. It uses the "Local" field
+ of GSocket. "Local" must be set by GSocket_SetLocal() before
+ GSocket_SetServer() is called. GSOCK_INVSOCK if socket has been initialized.
+ In the other cases, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_SetServer(GSocket *sck)
+{
+ int type;
+
+ assert(sck != NULL);
+
+ if (sck->m_fd != -1) {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_local) {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ if (sck->m_stream)
+ type = SOCK_STREAM;
+ else
+ type = SOCK_DGRAM;
+
+ sck->m_fd = socket(sck->m_local->m_realfamily, type, 0);
+
+ if (sck->m_fd == -1) {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
+ close(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ if (listen(sck->m_fd, 5) < 0) {
+ close(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ sck->m_server = TRUE;
+
+ return GSOCK_NOERROR;
+
+}
+
+/*
+ GSocket_WaitConnection() waits for an incoming client connection.
+*/
+GSocket *GSocket_WaitConnection(GSocket *socket)
+{
+ GSocket *connection;
+
+ assert(socket != NULL);
+
+ if (socket->m_fd == -1 || !socket->m_server) {
+ socket->m_error = GSOCK_INVSOCK;
+ return NULL;
+ }
+
+ _GSocket_Enable(socket, GSOCK_CONNECTION);
+
+ connection = GSocket_new();
+
+ connection->m_fd = accept(socket->m_fd, NULL, NULL);
+ if (connection->m_fd == -1) {
+ GSocket_destroy(connection);
+ socket->m_error = GSOCK_IOERR;
+ return NULL;
+ }
+
+ connection->m_stream = TRUE;
+ connection->m_server = FALSE;
+ connection->m_oriented = TRUE;
+
+ return connection;
+}
+
+/* Non oriented connections */
+
+GSocketError GSocket_SetNonOriented(GSocket *sck)
+{
+ assert(sck != NULL);
+
+ if (sck->m_fd != -1) {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_local) {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ sck->m_stream = FALSE;
+ sck->m_server = FALSE;
+ sck->m_oriented = FALSE;
+
+ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+
+ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
+ close(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ return GSOCK_NOERROR;
+}
+
+/* Client specific parts */
+
+/*
+ GSocket_Connect() establishes a client connection to a server using the "Peer"
+ field of GSocket. "Peer" must be set by GSocket_SetPeer() before
+ GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
+{
+ int type;
+
+ assert(sck != NULL);
+
+ if (sck->m_fd != -1) {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_peer) {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ sck->m_stream = (stream == GSOCK_STREAMED);
+ sck->m_oriented = TRUE;
+
+ if (sck->m_stream)
+ type = SOCK_STREAM;
+ else
+ type = SOCK_DGRAM;
+
+ sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
+
+ if (sck->m_fd == -1) {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ if (connect(sck->m_fd, sck->m_peer->m_addr,
+ sck->m_peer->m_len) != 0) {
+ close(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ sck->m_server = FALSE;
+
+ return GSOCK_NOERROR;
+}
+
+/* Generic IO */
+
+/* Like recv(), send(), ... */
+int GSocket_Read(GSocket *socket, char *buffer, int size)
+{
+ assert(socket != NULL);
+
+ if (socket->m_fd == -1 || socket->m_server) {
+ socket->m_error = GSOCK_INVSOCK;
+ return -1;
+ }
+
+ _GSocket_Enable(socket, GSOCK_INPUT);
+
+ if (socket->m_oriented)
+ return _GSocket_Recv_Stream(socket, buffer, size);
+ else
+ return _GSocket_Recv_Dgram(socket, buffer, size);
+}
+
+int GSocket_Write(GSocket *socket, const char *buffer,
+ int size)
+{
+ assert(socket != NULL);
+
+ if (socket->m_fd == -1 || socket->m_server) {
+ socket->m_error = GSOCK_INVSOCK;
+ return -1;
+ }
+
+ _GSocket_Enable(socket, GSOCK_OUTPUT);
+
+ if (socket->m_oriented)
+ return _GSocket_Send_Stream(socket, buffer, size);
+ else
+ return _GSocket_Send_Dgram(socket, buffer, size);
+}
+
+bool GSocket_DataAvailable(GSocket *socket)
+{
+ fd_set read_set;
+ struct timeval tv;
+
+ assert(socket != NULL);
+
+ if (socket->m_fd == -1 || socket->m_server) {
+ socket->m_error = GSOCK_INVSOCK;
+ return FALSE;
+ }
+
+ FD_ZERO(&read_set);
+ FD_SET(socket->m_fd, &read_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ select(socket->m_fd+1, &read_set, NULL, NULL, &tv);
+
+ return FD_ISSET(socket->m_fd, &read_set);
+}
+
+/* Flags */
+
+/*
+ GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
+ if we don't want to wait.
+*/
+void GSocket_SetBlocking(GSocket *socket, bool block)
+{
+ assert(socket != NULL);
+
+ socket->m_blocking = block;
+
+ if (socket->m_fd != -1)
+ ioctl(socket->m_fd, FIONBIO, &block);
+}
+
+/*
+ GSocket_GetError() returns the last error occured on the socket stream.
+*/
+
+GSocketError GSocket_GetError(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ return socket->m_error;
+}
+
+/* Callbacks */
+
+/*
+ Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
+ INPUT: The function is called when there is at least a byte in the
+ input buffer
+ OUTPUT: The function is called when the system is sure the next write call
+ will not block
+ CONNECTION: Two cases is possible:
+ Client socket -> the connection is established
+ Server socket -> a client request a connection
+ LOST: the connection is lost
+
+ SetFallback accepts a combination of these flags so a same callback can
+ receive different events.
+
+ An event is generated only once and its state is reseted when the relative
+ IO call is requested.
+ For example: INPUT -> GSocket_Read()
+ CONNECTION -> GSocket_Accept()
+*/
+void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
+ GSocketFallback fallback, char *cdata)
+{
+ int count;
+
+ assert (socket != NULL);
+
+ for (count=0;count<GSOCK_MAX_EVENT;count++) {
+ if ((event & (1 << count)) != 0) {
+ socket->m_fbacks[count] = fallback;
+ socket->m_data[count] = cdata;
+
+ _GSocket_Install_Fallback(socket, count);
+ _GSocket_Enable(socket, count);
+ }
+ }
+}
+
+/*
+ UnsetFallback will disables all fallbacks specified by "event".
+ NOTE: event may be a combination of flags
+*/
+void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
+{
+ int count = 0;
+
+ assert(socket != NULL);
+
+ for (count=0;count<GSOCK_MAX_EVENT;count++) {
+ if ((event & (1 << count)) != 0) {
+ _GSocket_Disable(socket, count);
+ socket->m_fbacks[count] = NULL;
+ _GSocket_Uninstall_Fallback(socket, count);
+ }
+ }
+}
+
+#define CALL_FALLBACK(socket, event) \
+if (socket->m_iocalls[event] && \
+ socket->m_fbacks[event]) {\
+ _GSocket_Disable(socket, event); \
+ socket->m_fbacks[event](socket, 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); \
+}
+
+void _GSocket_Enable(GSocket *socket, GSocketEvent event)
+{
+ socket->m_iocalls[event] = TRUE;
+ if (socket->m_fbacks[event])
+ _GSocket_Install_Fallback(socket, event);
+}
+
+void _GSocket_Disable(GSocket *socket, GSocketEvent event)
+{
+ socket->m_iocalls[event] = FALSE;
+ if (socket->m_fbacks[event])
+ _GSocket_Uninstall_Fallback(socket, event);
+}
+
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
+{
+ int ret;
+
+ MASK_SIGNAL();
+ ret = recv(socket->m_fd, buffer, size, 0);
+ UNMASK_SIGNAL();
+ if (ret == -1) {
+ socket->m_error = GSOCK_IOERR;
+ return -1;
+ }
+ return ret;
+}
+
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
+{
+ struct sockaddr from;
+ int fromlen, ret;
+
+ fromlen = sizeof(from);
+
+ MASK_SIGNAL();
+ ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
+ UNMASK_SIGNAL();
+ if (ret == -1) {
+ socket->m_error = GSOCK_IOERR;
+ return -1;
+ }
+
+ if (!socket->m_peer)
+ socket->m_peer = GAddress_new();
+ _GAddress_translate_from(socket->m_peer, &from, fromlen);
+
+ return ret;
+}
+
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
+{
+ int ret;
+
+ MASK_SIGNAL();
+ ret = send(socket->m_fd, buffer, size, 0);
+ UNMASK_SIGNAL();
+ if (ret == -1) {
+ socket->m_error = GSOCK_IOERR;
+ return -1;
+ }
+ return ret;
+}
+
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
+{
+ struct sockaddr *addr;
+ int len, ret;
+
+ if (!socket->m_peer) {
+ socket->m_error = GSOCK_INVADDR;
+ return -1;
+ }
+
+ _GAddress_translate_to(socket->m_peer, &addr, &len);
+
+ MASK_SIGNAL();
+ ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
+ UNMASK_SIGNAL();
+ if (ret == -1) {
+ socket->m_error = GSOCK_IOERR;
+ return -1;
+ }
+
+ free(addr);
+
+ return ret;
+}
+
+void _GSocket_Detected_Read(GSocket *socket)
+{
+ char c;
+ int ret;
+
+ if (socket->m_stream) {
+ ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
+
+ if (ret < 0 && socket->m_server) {
+ CALL_FALLBACK(socket, GSOCK_CONNECTION);
+ return;
+ }
+
+ if (ret > 0) {
+ CALL_FALLBACK(socket, GSOCK_INPUT);
+ } else {
+ CALL_FALLBACK(socket, GSOCK_LOST);
+ }
+ }
+}
+
+void _GSocket_Detected_Write(GSocket *socket)
+{
+ CALL_FALLBACK(socket, GSOCK_OUTPUT);
+}
+
+#undef CALL_FALLBACK
+#undef MASK_SIGNAL
+#undef UNMASK_SIGNAL
+
+/*
+ * -------------------------------------------------------------------------
+ * GAddress
+ * -------------------------------------------------------------------------
+ */
+
+#define CHECK_ADDRESS(address, family, retval) \
+{ \
+ if (address->m_family == GSOCK_NOFAMILY) \
+ _GAddress_Init_##family(address); \
+ if (address->m_family != GSOCK_##family) {\
+ address->m_error = GSOCK_INVADDR; \
+ return retval; \
+ } \
+}
+
+GAddress *GAddress_new()
+{
+ GAddress *address;
+
+ address = (GAddress *)malloc(sizeof(GAddress));
+
+ address->m_family = GSOCK_NOFAMILY;
+ address->m_addr = NULL;
+ address->m_len = 0;
+
+ return address;
+}
+
+GAddress *GAddress_copy(GAddress *address)
+{
+ GAddress *addr2;
+
+ assert(address != NULL);
+
+ addr2 = (GAddress *)malloc(sizeof(GAddress));
+ memcpy(addr2, address, sizeof(GAddress));
+
+ if (address->m_addr) {
+ addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
+ memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
+ }
+
+ return addr2;
+}
+
+void GAddress_destroy(GAddress *address)
+{
+ assert(address != NULL);
+
+ free(address);
+}
+
+void GAddress_SetFamily(GAddress *address, GAddressType type)
+{
+ assert(address != NULL);
+
+ address->m_family = type;
+}
+
+GAddressType GAddress_GetFamily(GAddress *address)
+{
+ assert(address != NULL);
+
+ return address->m_family;
+}
+
+void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
+ address->m_realfamily = addr->sa_family;
+ switch (addr->sa_family) {
+ case AF_INET:
+ address->m_family = GSOCK_INET;
+ break;
+ case AF_UNIX:
+ address->m_family = GSOCK_UNIX;
+ break;
+ case AF_INET6:
+ address->m_family = GSOCK_INET6;
+ break;
+ default:
+ /* TODO error */
+ }
+
+ if (address->m_addr)
+ free(address->m_addr);
+
+ address->m_len = len;
+ address->m_addr = (struct sockaddr *)malloc(len);
+ memcpy(address->m_addr, addr, len);
+}
+
+void _GAddress_translate_to(GAddress *address,
+ struct sockaddr **addr, int *len)
+{
+ if (!address->m_addr) {
+ /* TODO error */
+ return;
+ }
+
+ *len = address->m_len;
+ *addr = (struct sockaddr *)malloc(address->m_len);
+ memcpy(*addr, address->m_addr, address->m_len);
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * Internet address family
+ * -------------------------------------------------------------------------
+ */
+
+void _GAddress_Init_INET(GAddress *address)
+{
+ address->m_len = sizeof(struct sockaddr_in);
+ address->m_addr = (struct sockaddr *)malloc(address->m_len);
+ address->m_family = GSOCK_INET;
+ address->m_realfamily = PF_INET;
+ ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
+ ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
+}
+
+GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
+{
+ struct hostent *he;
+ struct in_addr *addr;
+
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
+
+ /* only name for the moment */
+ if (inet_aton(hostname, addr) == 0) {
+ struct in_addr *array_addr;
+
+ if ((he = gethostbyname(hostname)) == NULL) {
+ address->m_error = GSOCK_NOHOST;
+ return GSOCK_NOHOST;
+ }
+ array_addr = (struct in_addr *) *(he->h_addr_list);
+ addr->s_addr = array_addr[0].s_addr;
+ }
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetHostAddress(GAddress *address,
+ unsigned long hostaddr)
+{
+ struct in_addr *addr;
+
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
+ addr->s_addr = hostaddr;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port)
+{
+ struct servent *se;
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ if (!port) {
+ address->m_error = GSOCK_INVPORT;
+ return GSOCK_INVOP;
+ }
+
+ /* TODO: TCP or UDP */
+ se = getservbyname(port, "tcp");
+ if (!se) {
+ if (isdigit(port[0])) {
+ int port_int;
+
+ port_int = atoi(port);
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr->sin_port = htons(port_int);
+ return GSOCK_NOERROR;
+ }
+
+ address->m_error = GSOCK_INVPORT;
+ return GSOCK_INVPORT;
+ }
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr->sin_port = se->s_port;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
+{
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr->sin_port = htons(port);
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
+{
+ struct hostent *he;
+ char *addr_buf;
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr_buf = (char *)&(addr->sin_addr);
+
+ he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
+ if (he == NULL) {
+ address->m_error = GSOCK_NOHOST;
+ return GSOCK_NOHOST;
+ }
+
+ strncpy(hostname, he->h_name, sbuf);
+
+ return GSOCK_NOERROR;
+}
+
+unsigned long GAddress_INET_GetHostAddress(GAddress *address)
+{
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, 0);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+
+ return addr->sin_addr.s_addr;
+}
+
+unsigned short GAddress_INET_GetPort(GAddress *address)
+{
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, 0);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ return ntohs(addr->sin_port);
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * Unix address family
+ * -------------------------------------------------------------------------
+ */
+
+void _GAddress_Init_UNIX(GAddress *address)
+{
+ address->m_len = sizeof(struct sockaddr_un);
+ address->m_addr = (struct sockaddr *)malloc(address->m_len);
+ address->m_family = GSOCK_UNIX;
+ address->m_realfamily = PF_UNIX;
+ ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
+ ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
+}
+
+GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
+{
+ struct sockaddr_un *addr;
+
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
+
+ addr = ((struct sockaddr_un *)address->m_addr);
+ memcpy(addr->sun_path, path, strlen(path));
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
+{
+ struct sockaddr_un *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
+
+ addr = (struct sockaddr_un *)address->m_addr;
+
+ strncpy(path, addr->sun_path, sbuf);
+
+ return GSOCK_NOERROR;
+}
--- /dev/null
+#ifndef __GSOCK_UNX_H
+#define __GSOCK_UNX_H
+
+#include <wx/gsocket.h>
+
+/* Definition of GSocket */
+struct _GSocket {
+ int m_fd;
+ GAddress *m_local, *m_peer;
+ GSocketError m_error;
+
+ bool m_blocking, m_server, m_stream, m_oriented;
+
+ /* Fallbacks */
+ GSocketFallback m_fbacks[GSOCK_MAX_EVENT];
+ char *m_data[GSOCK_MAX_EVENT];
+
+ /* IO calls associated */
+ bool m_iocalls[GSOCK_MAX_EVENT];
+
+ char *m_gui_dependent;
+};
+
+/* Definition of GAddress */
+struct _GAddress {
+ struct sockaddr *m_addr;
+ size_t m_len;
+
+ GAddressType m_family;
+ int m_realfamily;
+
+ GSocketError m_error;
+};
+
+void _GSocket_Enable(GSocket *socket, GSocketEvent event);
+void _GSocket_Disable(GSocket *socket, GSocketEvent event);
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size);
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size);
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size);
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
+void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent count);
+void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent count);
+void _GSocket_Detected_Read(GSocket *socket);
+void _GSocket_Detected_Write(GSocket *socket);
+void _GSocket_GUI_Init(GSocket *socket);
+void _GSocket_GUI_Destroy(GSocket *socket);
+void _GAddress_translate_from(GAddress *address,
+ struct sockaddr *addr, int len);
+void _GAddress_translate_to(GAddress *address,
+ struct sockaddr **addr, int *len);
+
+/* Internet address family */
+void _GAddress_Init_INET(GAddress *address);
+/* Local address family */
+void _GAddress_Init_UNIX(GAddress *address);
+
+#endif