]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/gsocket.c
Conditional compilation fix.
[wxWidgets.git] / src / unix / gsocket.c
index 36a2ca622fbb5220b9df7dc3edf8852e7e137867..3f1c19c86284d93295a2f7caf0269f0fcf0571f9 100644 (file)
@@ -3,8 +3,8 @@
  * Name:    gsocket.c
  * Authors: Guilhem Lavaux,
  *          Guillermo Rodriguez Garcia <guille@iies.es> (maintainer)
- * Purpose: GSocket main Unix file
- * Licence: The wxWindows licence
+ * Purpose: GSocket main Unix and OS/2 file
+ * Licence: The wxWidgets licence
  * CVSID:   $Id$
  * -------------------------------------------------------------------------
  */
 #include "wx/setup.h"
 #endif
 
+#if defined(__VISAGECPP__)
+/* Seems to be needed by Visual Age C++, though I don't see how it manages
+   to not break on including a C++ header into a plain C source file      */
+#include "wx/defs.h"
+#define BSD_SELECT /* use Berkley Sockets select */
+#endif
+
 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
 
 #include <assert.h>
 #include <sys/types.h>
+#ifdef __VISAGECPP__
+#include <string.h>
+#include <sys/time.h>
+#include <types.h>
+#include <netinet/in.h>
+#endif
 #include <netdb.h>
 #include <sys/ioctl.h>
 
@@ -37,12 +50,42 @@ struct sockaddr_un
 #include <sys/un.h>
 #endif
 
+#ifndef __VISAGECPP__
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#else
+#include <nerrno.h>
+#  if __IBMCPP__ < 400
+#include <machine/endian.h>
+#include <socket.h>
+#include <ioctl.h>
+#include <select.h>
+#include <unistd.h>
+
+#define EBADF   SOCEBADF
+
+#    ifdef min
+#    undef min
+#    endif
+#  else
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+
+#define close(a) soclose(a)
+#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
+int _System bsdselect(int,
+                      struct fd_set *,
+                      struct fd_set *,
+                      struct fd_set *,
+                      struct timeval *);
+int _System soclose(int);
+#  endif
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -218,7 +261,10 @@ GSocket *GSocket_new(void)
 void GSocket_close(GSocket *socket)
 {
     _GSocket_Disable_Events(socket);
+    /* gsockosx.c calls CFSocketInvalidate which closes the socket for us */
+#if !(defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__)))
     close(socket->m_fd);
+#endif
     socket->m_fd = INVALID_SOCKET;
 }
 
@@ -430,10 +476,18 @@ GSocketError GSocket_SetServer(GSocket *sck)
     sck->m_error = GSOCK_IOERR;
     return GSOCK_IOERR;
   }
-
+#if defined(__EMX__) || defined(__VISAGECPP__)
+  ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
+#else
   ioctl(sck->m_fd, FIONBIO, &arg);
+#endif
   _GSocket_Enable_Events(sck);
 
+  /* allow a socket to re-bind if the socket is in the TIME_WAIT
+     state after being previously closed.
+   */
+  setsockopt(sck->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long));
+
   /* Bind to the local address,
    * retrieve the actual address bound,
    * and listen up to 5 connections.
@@ -535,8 +589,11 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
     socket->m_error = err;
     return NULL;
   }
-
+#if defined(__EMX__) || defined(__VISAGECPP__)
+  ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
+#else
   ioctl(connection->m_fd, FIONBIO, &arg);
+#endif
   _GSocket_Enable_Events(connection);
 
   return connection;
@@ -604,8 +661,11 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
     sck->m_error = GSOCK_IOERR;
     return GSOCK_IOERR;
   }
-
+#if defined(__EMX__) || defined(__VISAGECPP__)
+  ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
+#else
   ioctl(sck->m_fd, FIONBIO, &arg);
+#endif
   _GSocket_Enable_Events(sck);
 
   /* Connect it to the peer address, with a timeout (see below) */
@@ -708,8 +768,11 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
     sck->m_error = GSOCK_IOERR;
     return GSOCK_IOERR;
   }
-
+#if defined(__EMX__) || defined(__VISAGECPP__)
+  ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
+#else
   ioctl(sck->m_fd, FIONBIO, &arg);
+#endif
   _GSocket_Enable_Events(sck);
 
   /* Bind to the local address,
@@ -737,24 +800,26 @@ int GSocket_Read(GSocket *socket, char *buffer, int size)
 
   assert(socket != NULL);
 
-  /* Reenable INPUT events */
-  _GSocket_Enable(socket, GSOCK_INPUT);
-
   if (socket->m_fd == INVALID_SOCKET || socket->m_server)
   {
     socket->m_error = GSOCK_INVSOCK;
     return -1;
   }
 
+  /* Disable events during query of socket status */
+  _GSocket_Disable(socket, GSOCK_INPUT);
+    
   /* If the socket is blocking, wait for data (with a timeout) */
   if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
-    return -1;
-
-  /* Read the data */
-  if (socket->m_stream)
-    ret = _GSocket_Recv_Stream(socket, buffer, size);
-  else
-    ret = _GSocket_Recv_Dgram(socket, buffer, size);
+    /* We no longer return here immediately, otherwise socket events would not be re-enabled! */
+    ret = -1;
+  else {
+    /* Read the data */
+    if (socket->m_stream)
+      ret = _GSocket_Recv_Stream(socket, buffer, size);
+    else
+      ret = _GSocket_Recv_Dgram(socket, buffer, size);
+  }
     
   if (ret == -1)
   {
@@ -764,6 +829,9 @@ int GSocket_Read(GSocket *socket, char *buffer, int size)
       socket->m_error = GSOCK_IOERR;
   }
   
+  /* Enable events again now that we are done processing */
+  _GSocket_Enable(socket, GSOCK_INPUT);
+  
   return ret;
 }
 
@@ -842,17 +910,18 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
     fd_set exceptfds;
     struct timeval tv;
 
-    /* Do not use a static struct, Linux can garble it */
-    tv.tv_sec = 0;
-    tv.tv_usec = 0;
-
     assert(socket != NULL);
 
+    /* Do not use a static struct, Linux can garble it */
+    tv.tv_sec = socket->m_timeout / 1000;
+    tv.tv_usec = (socket->m_timeout % 1000) / 1000;
+
     FD_ZERO(&readfds);
     FD_ZERO(&writefds);
     FD_ZERO(&exceptfds);
     FD_SET(socket->m_fd, &readfds);
-    FD_SET(socket->m_fd, &writefds);
+    if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
+      FD_SET(socket->m_fd, &writefds);
     FD_SET(socket->m_fd, &exceptfds);
 
     /* Check 'sticky' CONNECTION flag first */
@@ -1216,9 +1285,13 @@ int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
 {
   int ret;
 
+#ifndef __VISAGECPP__
   MASK_SIGNAL();
   ret = send(socket->m_fd, buffer, size, 0);
   UNMASK_SIGNAL();
+#else
+  ret = send(socket->m_fd, (char *)buffer, size, 0);
+#endif
 
   return ret;
 }
@@ -1242,9 +1315,13 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
     return -1;
   }
 
+#ifndef __VISAGECPP__
   MASK_SIGNAL();
   ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
   UNMASK_SIGNAL();
+#else
+  ret = sendto(socket->m_fd, (char *)buffer, size, 0, addr, len);
+#endif
 
   /* Frees memory allocated from _GAddress_translate_to */
   free(addr);
@@ -1536,7 +1613,10 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
   {
 #else
   /* Use gethostbyname by default */
-  if (1)
+#ifndef __WXMAC__
+  int val = 1;  /* VA doesn't like constants in conditional expressions */
+  if (val)
+#endif
   {
 #endif
     struct in_addr *array_addr;
@@ -1570,7 +1650,7 @@ GSocketError GAddress_INET_SetHostAddress(GAddress *address,
   CHECK_ADDRESS(address, INET);
 
   addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
-  addr->s_addr = hostaddr;
+  addr->s_addr = htonl(hostaddr);
 
   return GSOCK_NOERROR;
 }
@@ -1661,7 +1741,7 @@ unsigned long GAddress_INET_GetHostAddress(GAddress *address)
 
   addr = (struct sockaddr_in *)address->m_addr;
 
-  return addr->sin_addr.s_addr;
+  return ntohl(addr->sin_addr.s_addr);
 }
 
 unsigned short GAddress_INET_GetPort(GAddress *address)
@@ -1681,6 +1761,7 @@ unsigned short GAddress_INET_GetPort(GAddress *address)
  * -------------------------------------------------------------------------
  */
 
+#ifndef __VISAGECPP__
 GSocketError _GAddress_Init_UNIX(GAddress *address)
 {
   address->m_len  = sizeof(struct sockaddr_un);
@@ -1729,6 +1810,6 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
 
   return GSOCK_NOERROR;
 }
-
+#endif  /* !defined(__VISAGECPP__) */
 #endif  /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */