]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/gsocket.c
Added wxInternetFilesystemModule to fs_inet.cpp
[wxWidgets.git] / src / unix / gsocket.c
index 7456ccf6351fc4db9f6876def8a430fcf2145c09..1e6e0254febffc4f91f3e6b20e1de4941beb5333 100644 (file)
@@ -3,31 +3,22 @@
  * 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()
@@ -73,6 +87,7 @@ 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;
@@ -82,17 +97,21 @@ void GSocket_destroy(GSocket *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);
 }
 
@@ -102,12 +121,14 @@ void GSocket_Shutdown(GSocket *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);
 }
@@ -116,11 +137,17 @@ void GSocket_Shutdown(GSocket *socket)
 
 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);
@@ -132,8 +159,7 @@ GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
 
 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;
@@ -152,7 +178,7 @@ GAddress *GSocket_GetLocal(GSocket *socket)
 {
   GAddress *address;
   struct sockaddr addr;
-  socklen_t size;
+  SOCKLEN_T size;
 
   assert(socket != NULL);
 
@@ -193,7 +219,8 @@ GAddress *GSocket_GetPeer(GSocket *socket)
   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)
 {
@@ -211,18 +238,18 @@ 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;
@@ -230,6 +257,7 @@ GSocketError GSocket_SetServer(GSocket *sck)
     return GSOCK_IOERR;
   }
 
+  /* Enable listening up to 5 connections */
   if (listen(sck->m_fd, 5) < 0) {
     close(sck->m_fd);
     sck->m_fd = -1;
@@ -237,10 +265,7 @@ GSocketError GSocket_SetServer(GSocket *sck)
     return GSOCK_IOERR;
   }
 
-  sck->m_server = TRUE;
-
   return GSOCK_NOERROR;
-     
 }
 
 /*
@@ -252,15 +277,19 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
 
   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);
@@ -268,6 +297,7 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
     return NULL;
   }
 
+  /* Initialize all fields */
   connection->m_stream   = TRUE;
   connection->m_server   = FALSE;
   connection->m_oriented = TRUE;
@@ -295,8 +325,10 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
   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;
@@ -330,6 +362,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     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;
 
@@ -338,6 +371,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
   else
     type = SOCK_DGRAM;
 
+  /* Create the socket */
   sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
 
   if (sck->m_fd == -1) {
@@ -345,6 +379,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     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);
@@ -353,6 +388,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     return GSOCK_IOERR;
   }
   
+  /* It is not a server */
   sck->m_server = FALSE;
 
   return GSOCK_NOERROR;
@@ -370,9 +406,10 @@ int GSocket_Read(GSocket *socket, char *buffer, int size)
     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);
@@ -390,7 +427,7 @@ int GSocket_Write(GSocket *socket, const char *buffer,
 
   _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);
@@ -475,6 +512,8 @@ void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
   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;
@@ -553,7 +592,8 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
 {
   struct sockaddr from;
-  int fromlen, ret;
+  SOCKLEN_T fromlen;
+  int ret;
 
   fromlen = sizeof(from);
 
@@ -565,6 +605,7 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
     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);
@@ -606,6 +647,7 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
     return -1;
   }
 
+  /* Frees memory allocated from _GAddress_translate_to */
   free(addr);
 
   return ret;
@@ -647,6 +689,10 @@ void _GSocket_Detected_Write(GSocket *socket)
  * -------------------------------------------------------------------------
  */
 
+/* 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) \
@@ -717,11 +763,15 @@ void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len)
   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)
@@ -772,10 +822,11 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
 
   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;
@@ -801,7 +852,8 @@ GSocketError GAddress_INET_SetHostAddress(GAddress *address,
   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;
@@ -814,8 +866,7 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port)
     return GSOCK_INVOP;
   }
  
-  /* TODO: TCP or UDP */
-  se = getservbyname(port, "tcp");
+  se = getservbyname(port, protocol);
   if (!se) {
     if (isdigit(port[0])) {
       int port_int;
@@ -938,3 +989,5 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
 
   return GSOCK_NOERROR;
 }
+
+#endif // wxUSE_SOCKETS