* 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 "wx/setup.h"
+
+#if wxUSE_SOCKETS
+
#include <assert.h>
#include <sys/ioctl.h>
+#include <sys/types.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 <stdlib.h>
#ifdef sun
-#include <sys/filio.h>
+# include <sys/filio.h>
#endif
#ifdef sgi
- #include <bstring.h>
+# include <bstring.h>
#endif
#include <signal.h>
-#include <wx/gsocket.h>
+#include "wx/gsocket.h"
#include "gsockunx.h"
+#ifndef SOCKLEN_T
+
+#ifdef __GLIBC__
+# if __GLIBC__ == 2
+# define SOCKLEN_T socklen_t
+# endif
+#else
+# define SOCKLEN_T int
+#endif
+
+#endif
+
+/* Global initialisers */
+
+bool GSocket_Init()
+{
+ return TRUE;
+}
+
+void GSocket_Cleanup()
+{
+}
+
/* Constructors / Destructors */
GSocket *GSocket_new()
socket->m_gui_dependent = NULL;
socket->m_blocking = FALSE;
+ /* We initialize the GUI specific entries here */
_GSocket_GUI_Init(socket);
return socket;
{
assert(socket != NULL);
- _GSocket_GUI_Destroy(socket);
-
+ /* First, we check that the socket is really shutdowned */
if (socket->m_fd != -1)
GSocket_Shutdown(socket);
+ /* We destroy GUI specific variables */
+ _GSocket_GUI_Destroy(socket);
+
+ /* We destroy private addresses */
if (socket->m_local)
GAddress_destroy(socket->m_local);
if (socket->m_peer)
GAddress_destroy(socket->m_peer);
+ /* We destroy socket itself */
free(socket);
}
assert(socket != NULL);
+ /* If socket has been created, we shutdown it */
if (socket->m_fd != -1) {
shutdown(socket->m_fd, 2);
close(socket->m_fd);
socket->m_fd = -1;
}
+ /* We also disable GUI callbacks */
for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
_GSocket_Uninstall_Fallback(socket, evt);
}
GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
{
- if (socket == NULL || (socket->m_fd != -1 && !socket->m_server))
+ assert(socket != NULL);
+
+ if ((socket->m_fd != -1 && !socket->m_server)) {
+ socket->m_error = GSOCK_INVSOCK;
return GSOCK_INVSOCK;
+ }
- if (address == NULL || address->m_family == GSOCK_NOFAMILY)
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
+ socket->m_error = GSOCK_INVADDR;
return GSOCK_INVADDR;
+ }
if (socket->m_local)
GAddress_destroy(socket->m_local);
GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
{
- if (socket == NULL)
- return GSOCK_INVSOCK;
+ assert(socket != NULL);
if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
socket->m_error = GSOCK_INVADDR;
{
GAddress *address;
struct sockaddr addr;
- socklen_t size;
+ SOCKLEN_T size;
assert(socket != NULL);
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.
+ In case, you haven't yet defined the local address, it returns GSOCK_INVADDR.
+ In the other cases it returns GSOCK_IOERR.
*/
GSocketError GSocket_SetServer(GSocket *sck)
{
return GSOCK_INVADDR;
}
- if (sck->m_stream)
- type = SOCK_STREAM;
- else
- type = SOCK_DGRAM;
+ /* We always have a stream here */
+ sck->m_stream = TRUE;
- sck->m_fd = socket(sck->m_local->m_realfamily, type, 0);
+ /* Create the socket */
+ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
if (sck->m_fd == -1) {
sck->m_error = GSOCK_IOERR;
return GSOCK_IOERR;
}
+ /* Bind the socket to the LOCAL address */
if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
close(sck->m_fd);
sck->m_fd = -1;
return GSOCK_IOERR;
}
+ /* Enable listening up to 5 connections */
if (listen(sck->m_fd, 5) < 0) {
close(sck->m_fd);
sck->m_fd = -1;
return GSOCK_IOERR;
}
- sck->m_server = TRUE;
-
return GSOCK_NOERROR;
-
}
/*
assert(socket != NULL);
+ /* If the socket has already been created, we exit immediately */
if (socket->m_fd == -1 || !socket->m_server) {
socket->m_error = GSOCK_INVSOCK;
return NULL;
}
+ /* Reenable GSOCK_CONNECTION event */
_GSocket_Enable(socket, GSOCK_CONNECTION);
+ /* Create a GSocket object for the new connection */
connection = GSocket_new();
+ /* Accept the incoming connection */
connection->m_fd = accept(socket->m_fd, NULL, NULL);
if (connection->m_fd == -1) {
GSocket_destroy(connection);
return NULL;
}
+ /* Initialize all fields */
connection->m_stream = TRUE;
connection->m_server = FALSE;
connection->m_oriented = TRUE;
sck->m_server = FALSE;
sck->m_oriented = FALSE;
+ /* Create the socket */
sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+ /* Bind it to the LOCAL address */
if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
close(sck->m_fd);
sck->m_fd = -1;
return GSOCK_INVADDR;
}
+ /* Test whether we want the socket to be a stream (e.g. TCP) */
sck->m_stream = (stream == GSOCK_STREAMED);
sck->m_oriented = TRUE;
else
type = SOCK_DGRAM;
+ /* Create the socket */
sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
if (sck->m_fd == -1) {
return GSOCK_IOERR;
}
+ /* Connect it to the PEER address */
if (connect(sck->m_fd, sck->m_peer->m_addr,
sck->m_peer->m_len) != 0) {
close(sck->m_fd);
return GSOCK_IOERR;
}
+ /* It is not a server */
sck->m_server = FALSE;
return GSOCK_NOERROR;
return -1;
}
+ /* Reenable GSOCK_INPUT event */
_GSocket_Enable(socket, GSOCK_INPUT);
- if (socket->m_oriented)
+ if (socket->m_stream)
return _GSocket_Recv_Stream(socket, buffer, size);
else
return _GSocket_Recv_Dgram(socket, buffer, size);
_GSocket_Enable(socket, GSOCK_OUTPUT);
- if (socket->m_oriented)
+ if (socket->m_stream)
return _GSocket_Send_Stream(socket, buffer, size);
else
return _GSocket_Send_Dgram(socket, buffer, size);
assert (socket != NULL);
for (count=0;count<GSOCK_MAX_EVENT;count++) {
+ /* We test each flag and, if it is enabled, we enable the corresponding
+ event */
if ((event & (1 << count)) != 0) {
socket->m_fbacks[count] = fallback;
socket->m_data[count] = cdata;
int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
{
struct sockaddr from;
- int fromlen, ret;
+ SOCKLEN_T fromlen;
+ int ret;
fromlen = sizeof(from);
return -1;
}
+ /* Translate a system address into a GSocket address */
if (!socket->m_peer)
socket->m_peer = GAddress_new();
_GAddress_translate_from(socket->m_peer, &from, fromlen);
return -1;
}
+ /* Frees memory allocated from _GAddress_translate_to */
free(addr);
return ret;
* -------------------------------------------------------------------------
*/
+/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
+ * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
+ * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
+ */
#define CHECK_ADDRESS(address, family, retval) \
{ \
if (address->m_family == GSOCK_NOFAMILY) \
case AF_UNIX:
address->m_family = GSOCK_UNIX;
break;
+#ifdef AF_INET6
case AF_INET6:
address->m_family = GSOCK_INET6;
break;
+#endif
default:
+ {
/* TODO error */
+ }
}
if (address->m_addr)
addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
- /* only name for the moment */
+ /* If it is a numeric host name, convert it now */
if (inet_aton(hostname, addr) == 0) {
struct in_addr *array_addr;
+ /* It is a real name, we solve it */
if ((he = gethostbyname(hostname)) == NULL) {
address->m_error = GSOCK_NOHOST;
return GSOCK_NOHOST;
return GSOCK_NOERROR;
}
-GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port)
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
+ const char *protocol)
{
struct servent *se;
struct sockaddr_in *addr;
return GSOCK_INVOP;
}
- /* TODO: TCP or UDP */
- se = getservbyname(port, "tcp");
+ se = getservbyname(port, protocol);
if (!se) {
if (isdigit(port[0])) {
int port_int;
return GSOCK_NOERROR;
}
+
+#endif // wxUSE_SOCKETS