]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/gsocket.c
Fixes for smoother cross compilation;
[wxWidgets.git] / src / unix / gsocket.c
index 4157d89baaf28eeb49805c141b90c357641c3030..2ffafc86b6993ac60e806f8c349d0853966e723d 100644 (file)
@@ -23,6 +23,7 @@
 #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 <string.h>
 #include <unistd.h>
 
 #endif
 
 
 #endif
 
+#if !defined(__LINUX__) && !defined(__FREEBSD__)
+#   define CAN_USE_TIMEOUT
+#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+#   if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1)
+#      define CAN_USE_TIMEOUT
+#   endif
+#endif
+
 /* Global initialisers */
 
 bool GSocket_Init()
 /* Global initialisers */
 
 bool GSocket_Init()
@@ -76,9 +85,12 @@ 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_fd                  = -1;
   for (i=0;i<GSOCK_MAX_EVENT;i++) {
-    socket->m_fbacks[i]         = NULL;
+    socket->m_cbacks[i]         = NULL;
     socket->m_iocalls[i]        = FALSE;
   }
   socket->m_local               = NULL;
     socket->m_iocalls[i]        = FALSE;
   }
   socket->m_local               = NULL;
@@ -87,7 +99,9 @@ GSocket *GSocket_new()
   socket->m_server             = FALSE;
   socket->m_stream             = TRUE;
   socket->m_gui_dependent      = NULL;
   socket->m_server             = FALSE;
   socket->m_stream             = TRUE;
   socket->m_gui_dependent      = NULL;
-  socket->m_blocking           = FALSE;
+  socket->m_non_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);
@@ -125,14 +139,16 @@ void GSocket_Shutdown(GSocket *socket)
 
   /* If socket has been created, we shutdown it */
   if (socket->m_fd != -1) {
 
   /* If socket has been created, we shutdown it */
   if (socket->m_fd != -1) {
-    shutdown(socket->m_fd, 2);
+    /* Only oriented connection should be shutdowned */
+    if (socket->m_oriented)
+      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++)
     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);
+    _GSocket_Uninstall_Callback(socket, evt);
 }
 
 /* Address handling */
 }
 
 /* Address handling */
@@ -200,7 +216,14 @@ 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) != GSOCK_NOERROR) {
+    GAddress_destroy(address);
+    return NULL;
+  }
 
   return address;
 }
 
   return address;
 }
@@ -242,6 +265,7 @@ GSocketError GSocket_SetServer(GSocket *sck)
 
   /* We always have a stream here  */
   sck->m_stream = TRUE;
 
   /* We always have a stream here  */
   sck->m_stream = TRUE;
+  sck->m_server = TRUE;
 
   /* Create the socket */
   sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
 
   /* Create the socket */
   sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
@@ -267,6 +291,9 @@ GSocketError GSocket_SetServer(GSocket *sck)
     return GSOCK_IOERR;
   }
 
     return GSOCK_IOERR;
   }
 
+  GSocket_SetNonBlocking(sck, sck->m_non_blocking);
+  GSocket_SetTimeout(sck, sck->m_timeout);
+
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
 
@@ -338,6 +365,9 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
     return GSOCK_IOERR;
   }
 
     return GSOCK_IOERR;
   }
 
+  GSocket_SetNonBlocking(sck, sck->m_non_blocking);
+  GSocket_SetTimeout(sck, sck->m_timeout);
+
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
 
@@ -393,6 +423,9 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
   /* It is not a server */
   sck->m_server = FALSE;
 
   /* It is not a server */
   sck->m_server = FALSE;
 
+  GSocket_SetNonBlocking(sck, sck->m_non_blocking);
+  GSocket_SetTimeout(sck, sck->m_timeout);
+
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
 
@@ -461,17 +494,47 @@ 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);
 
-  socket->m_blocking = block;
+  socket->m_non_blocking = non_block;
 
   if (socket->m_fd != -1)
 
   if (socket->m_fd != -1)
-    ioctl(socket->m_fd, FIONBIO, &block);
+    ioctl(socket->m_fd, FIONBIO, &non_block);
+}
+
+/*
+ * GSocket_SetTimeout()
+ */
+
+void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
+{
+  assert(socket != NULL);
+
+  socket->m_timeout = millisec;
+ /* Neither GLIBC 2.0 nor the kernel 2.0.36 define SO_SNDTIMEO or
+    SO_RCVTIMEO. The man pages, that these flags should exist but
+    are read only. RR. */
+ /* OK, restrict this to GLIBC 2.1. GL. */
+ /* Anyway, they seem to pose problems: I need to know the socket level and
+    it varies (may be SOL_TCP, SOL_UDP, ...). I disables this and use the
+    other solution. GL. */
+#if 0
+#ifdef CAN_USE_TIMEOUT 
+  if (socket->m_fd != -1) {
+    struct timeval tval;
+
+    tval.tv_sec = millisec / 1000;
+    tval.tv_usec = (millisec % 1000) * 1000;
+    setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
+    setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
+  }
+#endif
+#endif
 }
 
 /*
 }
 
 /*
@@ -488,7 +551,7 @@ GSocketError GSocket_GetError(GSocket *socket)
 /* Callbacks */
 
 /* 
 /* Callbacks */
 
 /* 
-   Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
+   Only one callback 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
    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
@@ -498,7 +561,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
@@ -506,8 +569,8 @@ 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 callback, char *cdata)
 {
   int count;
 
 {
   int count;
 
@@ -517,20 +580,18 @@ void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
     /* We test each flag and, if it is enabled, we enable the corresponding
        event */
     if ((event & (1 << count)) != 0) {
     /* 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_cbacks[count] = callback;
       socket->m_data[count] = cdata;
       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 callbacks 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;
 
@@ -539,17 +600,16 @@ void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
   for (count=0;count<GSOCK_MAX_EVENT;count++) {
     if ((event & (1 << count)) != 0) {
       _GSocket_Disable(socket, count);
   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);
+      socket->m_cbacks[count] = NULL;
     }
   }
 }
 
 #define CALL_FALLBACK(socket, event) \
 if (socket->m_iocalls[event] && \
     }
   }
 }
 
 #define CALL_FALLBACK(socket, event) \
 if (socket->m_iocalls[event] && \
-    socket->m_fbacks[event]) {\
+    socket->m_cbacks[event]) {\
   _GSocket_Disable(socket, event); \
   _GSocket_Disable(socket, event); \
-  socket->m_fbacks[event](socket, event, \
+  socket->m_cbacks[event](socket, event, \
                    socket->m_data[event]); \
 }
 
                    socket->m_data[event]); \
 }
 
@@ -563,18 +623,37 @@ if (socket->m_iocalls[event] && \
   signal(SIGPIPE, old_handler); \
 }
 
   signal(SIGPIPE, old_handler); \
 }
 
+#define ENABLE_TIMEOUT(socket) \
+{ \
+  struct itimerval old_ival, new_ival; \
+  void (*old_timer_sig)(int); \
+\
+  old_timer_sig = signal(SIGALRM, SIG_DFL); \
+  siginterrupt(SIGALRM, 1); \
+  new_ival.it_value.tv_sec = socket->m_timeout / 1000; \
+  new_ival.it_value.tv_usec = (socket->m_timeout % 1000) * 1000; \
+  new_ival.it_interval.tv_sec = 0; \
+  new_ival.it_interval.tv_usec = 0; \
+  setitimer(ITIMER_REAL, &new_ival, &old_ival);
+
+#define DISABLE_TIMEOUT(socket) \
+  signal(SIGALRM, old_timer_sig); \
+  siginterrupt(SIGALRM, 0); \
+  setitimer(ITIMER_REAL, &old_ival, NULL); \
+}
+
 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = TRUE;
 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = TRUE;
-  if (socket->m_fbacks[event])
-    _GSocket_Install_Fallback(socket, event);
+  if (socket->m_cbacks[event])
+    _GSocket_Install_Callback(socket, event);
 }
 
 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = FALSE;
 }
 
 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
 {
   socket->m_iocalls[event] = FALSE;
-  if (socket->m_fbacks[event])
-    _GSocket_Uninstall_Fallback(socket, event);
+  if (socket->m_cbacks[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)
@@ -582,12 +661,19 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
   int ret;
 
   MASK_SIGNAL();
   int ret;
 
   MASK_SIGNAL();
+  ENABLE_TIMEOUT(socket);
   ret = recv(socket->m_fd, buffer, size, 0);
   ret = recv(socket->m_fd, buffer, size, 0);
+  DISABLE_TIMEOUT(socket);
   UNMASK_SIGNAL();
   UNMASK_SIGNAL();
-  if (ret == -1) {
+
+  if (ret == -1 && errno != EWOULDBLOCK) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
+  if (errno == EWOULDBLOCK) {
+    socket->m_error = GSOCK_WOULDBLOCK;
+    return -1;
+  }
   return ret;
 }
 
   return ret;
 }
 
@@ -600,17 +686,29 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
   fromlen = sizeof(from);
 
   MASK_SIGNAL();
   fromlen = sizeof(from);
 
   MASK_SIGNAL();
+  ENABLE_TIMEOUT(socket);
   ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
   ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
+  DISABLE_TIMEOUT(socket);
   UNMASK_SIGNAL();
   UNMASK_SIGNAL();
-  if (ret == -1) {
+  if (ret == -1 && errno != EWOULDBLOCK) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
+  if (errno == EWOULDBLOCK) {
+    socket->m_error = GSOCK_WOULDBLOCK;
+    return -1;
+  }
 
   /* Translate a system address into a GSocket address */
 
   /* Translate a system address into a GSocket address */
-  if (!socket->m_peer)
+  if (!socket->m_peer) {
     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) != GSOCK_NOERROR)
+    return -1;
 
   return ret;
 }
 
   return ret;
 }
@@ -620,12 +718,18 @@ int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
   int ret;
 
   MASK_SIGNAL();
   int ret;
 
   MASK_SIGNAL();
+  ENABLE_TIMEOUT(socket);
   ret = send(socket->m_fd, buffer, size, 0);
   ret = send(socket->m_fd, buffer, size, 0);
+  DISABLE_TIMEOUT(socket);
   UNMASK_SIGNAL();
   UNMASK_SIGNAL();
-  if (ret == -1) {
+  if (ret == -1 && errno != EWOULDBLOCK) {
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
     socket->m_error = GSOCK_IOERR;
     return -1;
   }
+  if (errno == EWOULDBLOCK) {
+    socket->m_error = GSOCK_WOULDBLOCK;
+    return -1;
+  }
   return ret;
 }
 
   return ret;
 }
 
@@ -639,19 +743,28 @@ 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) != GSOCK_NOERROR) {
+    return -1;
+  }
 
   MASK_SIGNAL();
 
   MASK_SIGNAL();
+  ENABLE_TIMEOUT(socket);
   ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
   ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
+  DISABLE_TIMEOUT(socket);
   UNMASK_SIGNAL();
   UNMASK_SIGNAL();
-  if (ret == -1) {
-    socket->m_error = GSOCK_IOERR;
-    return -1;
-  }
 
   /* Frees memory allocated from _GAddress_translate_to */
   free(addr);
 
 
   /* Frees memory allocated from _GAddress_translate_to */
   free(addr);
 
+  if (ret == -1 && errno != EWOULDBLOCK) {
+    socket->m_error = GSOCK_IOERR;
+    return -1;
+  }
+  if (errno == EWOULDBLOCK) {
+    socket->m_error = GSOCK_WOULDBLOCK;
+    return -1;
+  }
+
   return ret;
 }
 
   return ret;
 }
 
@@ -698,7 +811,9 @@ void _GSocket_Detected_Write(GSocket *socket)
 #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) != GSOCK_NOERROR) {\
+      return address->m_error; \
+    }\
   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; \
@@ -711,6 +826,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;
@@ -725,10 +843,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);
   }
 
@@ -756,7 +882,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){
+GSocketError _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:
@@ -772,7 +898,8 @@ void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len)
 #endif
   default:
     {
 #endif
   default:
     {
-    /* TODO error */
+    address->m_error = GSOCK_INVOP;
+    return GSOCK_INVOP;
     }
   }
 
     }
   }
 
@@ -781,20 +908,32 @@ 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) {
+    address->m_error = GSOCK_MEMERR;
+    return GSOCK_MEMERR;
+  }
   memcpy(address->m_addr, addr, len);
   memcpy(address->m_addr, addr, len);
+
+  return GSOCK_NOERROR;
 }
 
 }
 
-void _GAddress_translate_to(GAddress *address,
-                            struct sockaddr **addr, int *len)
+GSocketError _GAddress_translate_to(GAddress *address,
+                                    struct sockaddr **addr, int *len)
 {
   if (!address->m_addr) {
 {
   if (!address->m_addr) {
-    /* TODO error */
-    return;
+    address->m_error = GSOCK_INVADDR;
+    return GSOCK_INVADDR;
   }
 
   *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) {
+    address->m_error = GSOCK_MEMERR;
+    return GSOCK_MEMERR;
+  }
+
   memcpy(*addr, address->m_addr, address->m_len);
   memcpy(*addr, address->m_addr, address->m_len);
+  return GSOCK_NOERROR;
 }
 
 /*
 }
 
 /*
@@ -803,14 +942,22 @@ void _GAddress_translate_to(GAddress *address,
  * -------------------------------------------------------------------------
  */
 
  * -------------------------------------------------------------------------
  */
 
-void _GAddress_Init_INET(GAddress *address)
+GSocketError _GAddress_Init_INET(GAddress *address)
 {
 {
+  address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
+  if (address->m_addr == NULL) {
+    address->m_error = GSOCK_MEMERR;
+    return GSOCK_MEMERR;
+  }
+
   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 GSOCK_NOERROR;
 }
 
 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
 }
 
 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
@@ -825,7 +972,15 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
   addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
 
   /* If it is a numeric host name, convert it now */
   addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
 
   /* If it is a numeric host name, convert it now */
+#if defined(HAVE_INET_ATON)
   if (inet_aton(hostname, addr) == 0) {
   if (inet_aton(hostname, addr) == 0) {
+#elif defined(HAVE_INET_ADDR)
+  /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
+  if ( (addr->s_addr = inet_addr(hostname)) == -1 ) {
+#else
+  /* Use gethostbyname by default */
+  if (1) {
+#endif
     struct in_addr *array_addr;
 
     /* It is a real name, we solve it */
     struct in_addr *array_addr;
 
     /* It is a real name, we solve it */
@@ -865,7 +1020,7 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
 
   if (!port) {
     address->m_error = GSOCK_INVPORT;
 
   if (!port) {
     address->m_error = GSOCK_INVPORT;
-    return GSOCK_INVOP;
+    return GSOCK_INVPORT;
   }
  
   se = getservbyname(port, protocol);
   }
  
   se = getservbyname(port, protocol);
@@ -954,14 +1109,21 @@ unsigned short GAddress_INET_GetPort(GAddress *address)
  * -------------------------------------------------------------------------
  */
 
  * -------------------------------------------------------------------------
  */
 
-void _GAddress_Init_UNIX(GAddress *address)
+GSocketError _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) {
+    address->m_error = GSOCK_MEMERR;
+    return GSOCK_MEMERR;
+  }
+
+  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)
@@ -992,4 +1154,5 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
   return GSOCK_NOERROR;
 }
 
   return GSOCK_NOERROR;
 }
 
-#endif // wxUSE_SOCKETS
+#endif
+  /* wxUSE_SOCKETS */