]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/gsocket.c
Changed wxChoice->wxComboBox as list of all paper sizes is too large to fit
[wxWidgets.git] / src / unix / gsocket.c
index 86711be59972c3ee6528988611280cbcc6a19cab..aa3f28ae855141d06b00356e161d24eb7d471efd 100644 (file)
@@ -6,6 +6,10 @@
  * -------------------------------------------------------------------------
  */
 
  * -------------------------------------------------------------------------
  */
 
+#include "wx/setup.h"
+
+#if wxUSE_SOCKETS
+
 #include <assert.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <assert.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <errno.h>
 
 #include <string.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <string.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
 
 #ifdef sun
 
 #ifdef sun
-  #include <sys/filio.h>
+#    include <sys/filio.h>
 #endif
 
 #ifdef sgi
 #endif
 
 #ifdef sgi
-  #include <bstring.h>
+#    include <bstring.h>
 #endif
 
 #include <signal.h>
 
 #endif
 
 #include <signal.h>
 
-#include "wx/setup.h"
 #include "wx/gsocket.h"
 #include "gsockunx.h"
 
 #include "wx/gsocket.h"
 #include "gsockunx.h"
 
@@ -71,6 +77,9 @@ GSocket *GSocket_new()
 
   socket = (GSocket *)malloc(sizeof(GSocket));
 
 
   socket = (GSocket *)malloc(sizeof(GSocket));
 
+  if (socket == NULL)
+    return NULL;
+
   socket->m_fd                  = -1;
   for (i=0;i<GSOCK_MAX_EVENT;i++) {
     socket->m_fbacks[i]         = NULL;
   socket->m_fd                  = -1;
   for (i=0;i<GSOCK_MAX_EVENT;i++) {
     socket->m_fbacks[i]         = NULL;
@@ -83,6 +92,8 @@ GSocket *GSocket_new()
   socket->m_stream             = TRUE;
   socket->m_gui_dependent      = NULL;
   socket->m_blocking           = FALSE;
   socket->m_stream             = TRUE;
   socket->m_gui_dependent      = NULL;
   socket->m_blocking           = FALSE;
+  socket->m_timeout             = 10*60*1000;
+                                      // 10 minutes * 60 sec * 1000 millisec
 
   /* We initialize the GUI specific entries here */
   _GSocket_GUI_Init(socket);
 
   /* We initialize the GUI specific entries here */
   _GSocket_GUI_Init(socket);
@@ -127,7 +138,7 @@ void GSocket_Shutdown(GSocket *socket)
 
   /* We also disable GUI callbacks */
   for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
 
   /* We also disable GUI callbacks */
   for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
-    _GSocket_Uninstall_Fallback(socket, evt);
+    _GSocket_Uninstall_Callback(socket, evt);
 }
 
 /* Address handling */
 }
 
 /* Address handling */
@@ -195,7 +206,15 @@ GAddress *GSocket_GetLocal(GSocket *socket)
   }
 
   address = GAddress_new();
   }
 
   address = GAddress_new();
-  _GAddress_translate_from(address, &addr, size);
+  if (address == NULL) {
+    socket->m_error = GSOCK_MEMERR;
+    return NULL;
+  }
+  if (!_GAddress_translate_from(address, &addr, size)) {
+    socket->m_error = GSOCK_MEMERR;
+    GAddress_destroy(address);
+    return NULL;
+  }
 
   return address;
 }
 
   return address;
 }
@@ -235,18 +254,18 @@ GSocketError GSocket_SetServer(GSocket *sck)
     return GSOCK_INVADDR;
   }
 
     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;
   }
 
 
   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;
   if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
     close(sck->m_fd);
     sck->m_fd = -1;
@@ -254,6 +273,7 @@ GSocketError GSocket_SetServer(GSocket *sck)
     return GSOCK_IOERR;
   }
 
     return GSOCK_IOERR;
   }
 
+  /* Enable listening up to 5 connections */
   if (listen(sck->m_fd, 5) < 0) {
     close(sck->m_fd);
     sck->m_fd = -1;
   if (listen(sck->m_fd, 5) < 0) {
     close(sck->m_fd);
     sck->m_fd = -1;
@@ -261,10 +281,10 @@ GSocketError GSocket_SetServer(GSocket *sck)
     return GSOCK_IOERR;
   }
 
     return GSOCK_IOERR;
   }
 
-  sck->m_server = TRUE;
+  GSocket_SetNonBlocking(sck, sck->m_blocking);
+  GSocket_SetTimeout(sck, sck->m_timeout);
 
   return GSOCK_NOERROR;
 
   return GSOCK_NOERROR;
-     
 }
 
 /*
 }
 
 /*
@@ -276,15 +296,19 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
 
   assert(socket != NULL);
 
 
   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;
   }
 
   if (socket->m_fd == -1 || !socket->m_server) {
     socket->m_error = GSOCK_INVSOCK;
     return NULL;
   }
 
+  /* Reenable GSOCK_CONNECTION event */
   _GSocket_Enable(socket, GSOCK_CONNECTION);
 
   _GSocket_Enable(socket, GSOCK_CONNECTION);
 
+  /* Create a GSocket object for the new connection */
   connection = GSocket_new();
 
   connection = GSocket_new();
 
+  /* Accept the incoming connection */
   connection->m_fd = accept(socket->m_fd, NULL, NULL);
   if (connection->m_fd == -1) {
     GSocket_destroy(connection);
   connection->m_fd = accept(socket->m_fd, NULL, NULL);
   if (connection->m_fd == -1) {
     GSocket_destroy(connection);
@@ -292,6 +316,7 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
     return NULL;
   }
 
     return NULL;
   }
 
+  /* Initialize all fields */
   connection->m_stream   = TRUE;
   connection->m_server   = FALSE;
   connection->m_oriented = TRUE;
   connection->m_stream   = TRUE;
   connection->m_server   = FALSE;
   connection->m_oriented = TRUE;
@@ -319,8 +344,10 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
   sck->m_server   = FALSE;
   sck->m_oriented = FALSE;
 
   sck->m_server   = FALSE;
   sck->m_oriented = FALSE;
 
+  /* Create the socket */
   sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
 
   sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
 
+  /* 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;
   if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
     close(sck->m_fd);
     sck->m_fd    = -1;
@@ -328,6 +355,9 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
     return GSOCK_IOERR;
   }
 
     return GSOCK_IOERR;
   }
 
+  GSocket_SetNonBlocking(sck, sck->m_blocking);
+  GSocket_SetTimeout(sck, sck->m_timeout);
+
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
 
@@ -354,6 +384,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     return GSOCK_INVADDR;
   }
 
     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;
 
   sck->m_stream = (stream == GSOCK_STREAMED);
   sck->m_oriented = TRUE;
 
@@ -362,6 +393,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
   else
     type = SOCK_DGRAM;
 
   else
     type = SOCK_DGRAM;
 
+  /* Create the socket */
   sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
 
   if (sck->m_fd == -1) {
   sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
 
   if (sck->m_fd == -1) {
@@ -369,6 +401,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     return GSOCK_IOERR;
   }
 
     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);
   if (connect(sck->m_fd, sck->m_peer->m_addr,
               sck->m_peer->m_len) != 0) {
     close(sck->m_fd);
@@ -377,8 +410,12 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     return GSOCK_IOERR;
   }
   
     return GSOCK_IOERR;
   }
   
+  /* It is not a server */
   sck->m_server = FALSE;
 
   sck->m_server = FALSE;
 
+  GSocket_SetNonBlocking(sck, sck->m_blocking);
+  GSocket_SetTimeout(sck, sck->m_timeout);
+
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
 
@@ -394,9 +431,10 @@ int GSocket_Read(GSocket *socket, char *buffer, int size)
     return -1;
   }
 
     return -1;
   }
 
+  /* Reenable GSOCK_INPUT event */
   _GSocket_Enable(socket, GSOCK_INPUT);
 
   _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);
     return _GSocket_Recv_Stream(socket, buffer, size);
   else
     return _GSocket_Recv_Dgram(socket, buffer, size);
@@ -414,7 +452,7 @@ int GSocket_Write(GSocket *socket, const char *buffer,
 
   _GSocket_Enable(socket, GSOCK_OUTPUT);
 
 
   _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);
     return _GSocket_Send_Stream(socket, buffer, size);
   else
     return _GSocket_Send_Dgram(socket, buffer, size);
@@ -446,10 +484,10 @@ bool GSocket_DataAvailable(GSocket *socket)
 /* Flags */
 
 /*
 /* Flags */
 
 /*
-  GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
+  GSocket_SetNonBlocking() puts the socket in non-blocking mode. This is useful
   if we don't want to wait.
 */
   if we don't want to wait.
 */
-void GSocket_SetBlocking(GSocket *socket, bool block)
+void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
 {
   assert(socket != NULL);
 
 {
   assert(socket != NULL);
 
@@ -459,6 +497,39 @@ void GSocket_SetBlocking(GSocket *socket, bool block)
     ioctl(socket->m_fd, FIONBIO, &block);
 }
 
     ioctl(socket->m_fd, FIONBIO, &block);
 }
 
+/*
+ * GSocket_SetTimeout()
+ */
+
+#ifndef LINUX
+#   define CAN_USE_TIMEOUT
+#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+#   if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1)
+#      define CAN_USE_TIMEOUT
+#   endif
+#endif
+
+void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
+{
+  assert(socket != NULL);
+
+ /* Neither GLIBC 2.0 nor the kernel 2.0.36 define SO_SNDTIMEO or
+    SO_RCVTIMEO. The man pages, that these flags should exist but
+    are read only. RR. */
+ /* OK, restrict this to GLIBC 2.1. GL. */
+#ifdef CAN_USE_TIMEOUT 
+  socket->m_timeout = millisec;
+  if (socket->m_fd != -1) {
+    struct timeval tval;
+
+    tval.tv_sec = millisec / 1000;
+    tval.tv_usec = (millisec % 1000) * 1000;
+    setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
+    setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
+  }
+#endif
+}
+
 /*
   GSocket_GetError() returns the last error occured on the socket stream.
 */
 /*
   GSocket_GetError() returns the last error occured on the socket stream.
 */
@@ -483,7 +554,7 @@ GSocketError GSocket_GetError(GSocket *socket)
             Server socket -> a client request a connection
    LOST: the connection is lost
 
             Server socket -> a client request a connection
    LOST: the connection is lost
 
-   SetFallback accepts a combination of these flags so a same callback can
+   SetCallback 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
    receive different events.
 
    An event is generated only once and its state is reseted when the relative
@@ -491,29 +562,29 @@ GSocketError GSocket_GetError(GSocket *socket)
    For example: INPUT -> GSocket_Read()
                 CONNECTION -> GSocket_Accept()
 */
    For example: INPUT -> GSocket_Read()
                 CONNECTION -> GSocket_Accept()
 */
-void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
-                        GSocketFallback fallback, char *cdata)
+void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
+                        GSocketCallback fallback, char *cdata)
 {
   int count;
 
   assert (socket != NULL);
 
   for (count=0;count<GSOCK_MAX_EVENT;count++) {
 {
   int count;
 
   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;
     if ((event & (1 << count)) != 0) {
       socket->m_fbacks[count] = fallback;
       socket->m_data[count] = cdata;
-
-      _GSocket_Install_Fallback(socket, count);
       _GSocket_Enable(socket, count);
     }
   }
 }
 
 /*
       _GSocket_Enable(socket, count);
     }
   }
 }
 
 /*
-  UnsetFallback will disables all fallbacks specified by "event".
+  UnsetCallback will disables all fallbacks specified by "event".
   NOTE: event may be a combination of flags
 */
   NOTE: event may be a combination of flags
 */
-void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
+void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
 {
   int count = 0;
 
 {
   int count = 0;
 
@@ -523,7 +594,6 @@ void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
     if ((event & (1 << count)) != 0) {
       _GSocket_Disable(socket, count);
       socket->m_fbacks[count] = NULL;
     if ((event & (1 << count)) != 0) {
       _GSocket_Disable(socket, count);
       socket->m_fbacks[count] = NULL;
-      _GSocket_Uninstall_Fallback(socket, count);
     }
   }
 }
     }
   }
 }
@@ -550,14 +620,14 @@ void _GSocket_Enable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = TRUE;
   if (socket->m_fbacks[event])
 {
   socket->m_iocalls[event] = TRUE;
   if (socket->m_fbacks[event])
-    _GSocket_Install_Fallback(socket, event);
+    _GSocket_Install_Callback(socket, event);
 }
 
 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = FALSE;
   if (socket->m_fbacks[event])
 }
 
 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = FALSE;
   if (socket->m_fbacks[event])
-    _GSocket_Uninstall_Fallback(socket, event);
+    _GSocket_Uninstall_Callback(socket, event);
 }
 
 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
 }
 
 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
@@ -567,10 +637,14 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
   MASK_SIGNAL();
   ret = recv(socket->m_fd, buffer, size, 0);
   UNMASK_SIGNAL();
   MASK_SIGNAL();
   ret = recv(socket->m_fd, buffer, size, 0);
   UNMASK_SIGNAL();
-  if (ret == -1) {
+  if (ret == -1 && errno != EAGAIN) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
+  if (errno == EAGAIN) {
+    socket->m_error = GSOCK_TRYAGAIN;
+    return -1;
+  }
   return ret;
 }
 
   return ret;
 }
 
@@ -585,14 +659,27 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
   MASK_SIGNAL();
   ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
   UNMASK_SIGNAL();
   MASK_SIGNAL();
   ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
   UNMASK_SIGNAL();
-  if (ret == -1) {
+  if (ret == -1 && errno != EAGAIN) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
+  if (errno == EAGAIN) {
+    socket->m_error = GSOCK_TRYAGAIN;
+    return -1;
+  }
 
 
-  if (!socket->m_peer)
+  /* Translate a system address into a GSocket address */
+  if (!socket->m_peer) {
     socket->m_peer = GAddress_new();
     socket->m_peer = GAddress_new();
-  _GAddress_translate_from(socket->m_peer, &from, fromlen);
+    if (!socket->m_peer) {
+      socket->m_error = GSOCK_MEMERR;
+      return -1;
+    }
+  }
+  if (!_GAddress_translate_from(socket->m_peer, &from, fromlen)) {
+    socket->m_error = GSOCK_MEMERR;
+    return -1;
+  }
 
   return ret;
 }
 
   return ret;
 }
@@ -604,10 +691,14 @@ int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
   MASK_SIGNAL();
   ret = send(socket->m_fd, buffer, size, 0);
   UNMASK_SIGNAL();
   MASK_SIGNAL();
   ret = send(socket->m_fd, buffer, size, 0);
   UNMASK_SIGNAL();
-  if (ret == -1) {
+  if (ret == -1 && errno != EAGAIN) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
+  if (errno == EAGAIN) {
+    socket->m_error = GSOCK_TRYAGAIN;
+    return -1;
+  }
   return ret;
 }
 
   return ret;
 }
 
@@ -621,17 +712,26 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
     return -1;
   }
 
     return -1;
   }
 
-  _GAddress_translate_to(socket->m_peer, &addr, &len);
+  if (!_GAddress_translate_to(socket->m_peer, &addr, &len)) {
+    socket->m_error = GSOCK_MEMERR;
+    return -1;
+  }
 
   MASK_SIGNAL();
   ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
   UNMASK_SIGNAL();
 
   MASK_SIGNAL();
   ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
   UNMASK_SIGNAL();
-  if (ret == -1) {
+
+  /* Frees memory allocated from _GAddress_translate_to */
+  free(addr);
+
+  if (ret == -1 && errno != EAGAIN) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
-
-  free(addr);
+  if (errno == EAGAIN) {
+    socket->m_error = GSOCK_TRYAGAIN;
+    return -1;
+  }
 
   return ret;
 }
 
   return ret;
 }
@@ -672,10 +772,17 @@ 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) \
 #define CHECK_ADDRESS(address, family, retval) \
 { \
   if (address->m_family == GSOCK_NOFAMILY) \
-    _GAddress_Init_##family(address); \
+    if (!_GAddress_Init_##family(address)) {\
+      address->m_error = GSOCK_MEMERR; \
+      return retval; \
+    }\
   if (address->m_family != GSOCK_##family) {\
     address->m_error = GSOCK_INVADDR; \
     return retval; \
   if (address->m_family != GSOCK_##family) {\
     address->m_error = GSOCK_INVADDR; \
     return retval; \
@@ -688,6 +795,9 @@ GAddress *GAddress_new()
 
   address = (GAddress *)malloc(sizeof(GAddress));
 
 
   address = (GAddress *)malloc(sizeof(GAddress));
 
+  if (address == NULL)
+    return NULL;
+
   address->m_family  = GSOCK_NOFAMILY;
   address->m_addr    = NULL;
   address->m_len     = 0;
   address->m_family  = GSOCK_NOFAMILY;
   address->m_addr    = NULL;
   address->m_len     = 0;
@@ -702,10 +812,18 @@ GAddress *GAddress_copy(GAddress *address)
   assert(address != NULL);
 
   addr2 = (GAddress *)malloc(sizeof(GAddress));
   assert(address != NULL);
 
   addr2 = (GAddress *)malloc(sizeof(GAddress));
+
+  if (addr2 == NULL)
+    return NULL;
+
   memcpy(addr2, address, sizeof(GAddress));
 
   if (address->m_addr) {
     addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
   memcpy(addr2, address, sizeof(GAddress));
 
   if (address->m_addr) {
     addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
+    if (addr2->m_addr == NULL) {
+      free(addr2);
+      return NULL;
+    }
     memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
   }
 
     memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
   }
 
@@ -733,7 +851,7 @@ GAddressType GAddress_GetFamily(GAddress *address)
   return address->m_family;
 }
 
   return address->m_family;
 }
 
-void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
+bool _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_realfamily = addr->sa_family;
   switch (addr->sa_family) {
   case AF_INET:
@@ -758,10 +876,14 @@ void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len)
 
   address->m_len  = len;
   address->m_addr = (struct sockaddr *)malloc(len);
 
   address->m_len  = len;
   address->m_addr = (struct sockaddr *)malloc(len);
+  if (address->m_addr == NULL)
+    return FALSE;
   memcpy(address->m_addr, addr, len);
   memcpy(address->m_addr, addr, len);
+
+  return TRUE;
 }
 
 }
 
-void _GAddress_translate_to(GAddress *address,
+bool _GAddress_translate_to(GAddress *address,
                             struct sockaddr **addr, int *len)
 {
   if (!address->m_addr) {
                             struct sockaddr **addr, int *len)
 {
   if (!address->m_addr) {
@@ -771,7 +893,11 @@ void _GAddress_translate_to(GAddress *address,
 
   *len = address->m_len;
   *addr = (struct sockaddr *)malloc(address->m_len);
 
   *len = address->m_len;
   *addr = (struct sockaddr *)malloc(address->m_len);
+  if (*addr == NULL)
+    return FALSE;
+
   memcpy(*addr, address->m_addr, address->m_len);
   memcpy(*addr, address->m_addr, address->m_len);
+  return TRUE;
 }
 
 /*
 }
 
 /*
@@ -780,14 +906,20 @@ void _GAddress_translate_to(GAddress *address,
  * -------------------------------------------------------------------------
  */
 
  * -------------------------------------------------------------------------
  */
 
-void _GAddress_Init_INET(GAddress *address)
+bool _GAddress_Init_INET(GAddress *address)
 {
 {
+  address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
+  if (address->m_addr == NULL)
+    return FALSE;
+
   address->m_len  = sizeof(struct sockaddr_in);
   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;
   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;
+
+  return TRUE;
 }
 
 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
 }
 
 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
@@ -801,10 +933,11 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
 
   addr = &(((struct sockaddr_in *)address->m_addr)->sin_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;
 
   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;
     if ((he = gethostbyname(hostname)) == NULL) {
       address->m_error = GSOCK_NOHOST;
       return GSOCK_NOHOST;
@@ -844,7 +977,6 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
     return GSOCK_INVOP;
   }
  
     return GSOCK_INVOP;
   }
  
-  /* TODO: TCP or UDP */
   se = getservbyname(port, protocol);
   if (!se) {
     if (isdigit(port[0])) {
   se = getservbyname(port, protocol);
   if (!se) {
     if (isdigit(port[0])) {
@@ -931,14 +1063,19 @@ unsigned short GAddress_INET_GetPort(GAddress *address)
  * -------------------------------------------------------------------------
  */
 
  * -------------------------------------------------------------------------
  */
 
-void _GAddress_Init_UNIX(GAddress *address)
+bool _GAddress_Init_UNIX(GAddress *address)
 {
 {
-  address->m_len  = sizeof(struct sockaddr_un);
   address->m_addr = (struct sockaddr *)malloc(address->m_len);
   address->m_addr = (struct sockaddr *)malloc(address->m_len);
+  if (address->m_addr == NULL)
+    return FALSE;
+
+  address->m_len  = sizeof(struct sockaddr_un);
   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;
   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;
+
+  return TRUE;
 }
 
 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
 }
 
 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
@@ -968,3 +1105,5 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
 
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
+
+#endif // wxUSE_SOCKETS