You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/12/01 07:04:00 UTC

svn commit: r350181 [159/198] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/ depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/ depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/ depends/oss/win....

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/port/hysock.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/port/hysock.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/port/hysock.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/port/hysock.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,5209 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define CDEV_CURRENT_FUNCTION _comment_
+/**
+ * @file
+ * @ingroup Port
+ * @brief Sockets
+ */
+
+#undef CDEV_CURRENT_FUNCTION
+
+#include "hysock.h"
+#include "hymutex.h"
+#include "portpriv.h"
+#include "hyportptb.h"
+#include <fcntl.h>
+#include <string.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for struct in_addr */
+#include <sys/ioctl.h>
+#include <net/if.h>             /* for struct ifconf */
+
+#if defined(LINUX)
+#define IPV6_FLOWINFO_SEND      33
+#if defined(HARDHAT)
+#else
+#define HAS_RTNETLINK 1
+#endif
+#endif
+
+#if defined(HAS_RTNETLINK)
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+typedef struct linkReq_struct
+{
+  struct nlmsghdr netlinkHeader;
+  struct ifinfomsg msg;
+} linkReq_struct;
+typedef struct addrReq_struct
+{
+  struct nlmsghdr netlinkHeader;
+  struct ifaddrmsg msg;
+} addrReq_struct;
+#define NETLINK_DATA_BUFFER_SIZE 1024
+#define NETLINK_READTIMEOUT_SECS 20
+typedef struct netlinkContext_struct
+{
+  int netlinkSocketHandle;
+  char buffer[NETLINK_DATA_BUFFER_SIZE];
+  struct nlmsghdr *netlinkHeader;
+  U_32 remainingLength;
+  U_32 done;
+} netlinkContext_struct;
+#else
+/* need something so that functions still compile */
+typedef struct netlinkContext_struct
+{
+  int netlinkSocketHandle;
+} netlinkContext_struct;
+typedef struct nlmsghdr
+{
+  int length;
+};
+#endif
+
+#define INVALID_SOCKET (hysocket_t) -1
+
+/* these platforms include a colon in aliases so additional tests are required */
+
+/* The platforms that do not define the standard type socklen_t seem to all want an int in the socket calls */
+
+/*the number of times to retry a gethostby* call if the return code is TRYAGAIN*/
+#define MAX_RETRIES 50
+
+#if NO_R
+/*use a mutex if the gethostbyaddr, gethostbyname calls are not threadsafe*/
+MUTEX hostentLock = PTHREAD_MUTEX_INITIALIZER;
+#endif /*NO_R */
+
+#define VALIDATE_ALLOCATIONS 1
+
+/* needed for connect_with_timeout */
+typedef struct selectFDSet_struct
+{
+  int nfds;
+  int sock;
+  fd_set writeSet;
+  fd_set readSet;
+  fd_set exceptionSet;
+} selectFDSet_strut;
+
+#define CDEV_CURRENT_FUNCTION _prototypes_private
+
+I_32 platformSocketOption (I_32 portableSocketOption);
+
+I_32 initNetlinkContext (struct HyPortLibrary *portLibrary,
+                         I_32 netlinkSocketHandle,
+                         struct netlinkContext_struct *netlinkContext);
+
+I_32 getNextNetlinkMsg (struct HyPortLibrary *portLibrary,
+                        struct netlinkContext_struct *netlinkContext,
+                        struct nlmsghdr **nextMessage);
+
+static I_32 copy_hostent (struct HyPortLibrary *portLibrary,
+                          OSHOSTENT * source, PortlibPTBuffers_t * ptBuffers);
+
+I_32 platformSocketLevel (I_32 portableSocketLevel);
+
+static I_32 findError (I_32 errorCode);
+
+I_32 map_protocol_family_Hy_to_OS (I_32 addr_family);
+
+I_32 map_addr_family_Hy_to_OS (I_32 addr_family);
+
+I_32 map_sockettype_Hy_to_OS (I_32 socket_type);
+
+static I_32 findHostError (int herr);
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION copy_hostent
+
+static I_32
+copy_hostent (struct HyPortLibrary *portLibrary, OSHOSTENT * source,
+              PortlibPTBuffers_t * ptBuffers)
+{
+#if NO_R
+  int h_len = strlen (source->h_name);
+  int total = 0;
+  int i = 0;
+  char *buffer;
+  OSHOSTENT *dest = &(*ptBuffers)->hostent;
+  /* add trailing NULL, and round off to nearest pointer size */
+  h_len = (h_len + 1 + sizeof (void *)) & ~(sizeof (void *) - 1);
+  while (source->h_addr_list[i])
+    i++;
+  total = h_len + ((i + 2) * sizeof (void *)) + (i * sizeof (U_32));
+  if (!(*ptBuffers)->gethostBuffer || (*ptBuffers)->gethostBufferSize < total)
+    {
+      (*ptBuffers)->gethostBuffer =
+        portLibrary->mem_allocate_memory (portLibrary, total);
+      if (!(*ptBuffers)->gethostBuffer)
+        {
+          return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+        }
+      (*ptBuffers)->gethostBufferSize = total;
+    }
+  buffer = (*ptBuffers)->gethostBuffer;
+  dest->h_name = buffer;
+  strcpy (buffer, source->h_name);
+  buffer += h_len;
+  dest->h_aliases = (void *) buffer;
+  *((void **) buffer) = NULL;
+  buffer += sizeof (void *);
+  dest->h_addrtype = source->h_addrtype;
+  dest->h_length = source->h_length;
+  dest->h_addr_list = (void *) buffer;
+  buffer += (i + 1) * sizeof (void *);
+  i = 0;
+  while (source->h_addr_list[i])
+    {
+      dest->h_addr_list[i] = (void *) buffer;
+      *((U_32 *) buffer) = *((U_32 *) source->h_addr_list[i]);
+      buffer += sizeof (U_32);
+      i++;
+    }
+  dest->h_addr_list[i] = NULL;
+
+#endif
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION findError
+
+/**
+ * @internal
+ * Determines the proper portable error code to return given a native error code
+ *
+ * @param[in] errorCode The error code reported by the OS
+ *
+ * @return	the (negative) portable error code
+ */
+static I_32
+findError (I_32 errorCode)
+{
+  switch (errorCode)
+    {
+    case HYPORT_ERROR_SOCKET_UNIX_EBADF:
+      return HYPORT_ERROR_SOCKET_BADDESC;
+    case HYPORT_ERROR_SOCKET_UNIX_ENOBUFS:
+      return HYPORT_ERROR_SOCKET_NOBUFFERS;
+    case HYPORT_ERROR_SOCKET_UNIX_EOPNOTSUP:
+      return HYPORT_ERROR_SOCKET_OPNOTSUPP;
+    case HYPORT_ERROR_SOCKET_UNIX_ENOPROTOOPT:
+      return HYPORT_ERROR_SOCKET_OPTUNSUPP;
+    case HYPORT_ERROR_SOCKET_UNIX_EINVAL:
+      return HYPORT_ERROR_SOCKET_SOCKLEVELINVALID;
+    case HYPORT_ERROR_SOCKET_UNIX_ENOTSOCK:
+      return HYPORT_ERROR_SOCKET_NOTSOCK;
+    case HYPORT_ERROR_SOCKET_UNIX_EINTR:
+      return HYPORT_ERROR_SOCKET_INTERRUPTED;
+    case HYPORT_ERROR_SOCKET_UNIX_ENOTCONN:
+      return HYPORT_ERROR_SOCKET_NOTCONNECTED;
+    case HYPORT_ERROR_SOCKET_UNIX_EAFNOSUPPORT:
+      return HYPORT_ERROR_SOCKET_BADAF;
+      /* note: HYPORT_ERROR_SOCKET_UNIX_ECONNRESET not included because it has the same
+       * value as HYPORT_ERROR_SOCKET_UNIX_CONNRESET and they both map to HYPORT_ERROR_SOCKET_CONNRESET */
+    case HYPORT_ERROR_SOCKET_UNIX_CONNRESET:
+      return HYPORT_ERROR_SOCKET_CONNRESET;
+    case HYPORT_ERROR_SOCKET_UNIX_EAGAIN:
+      return HYPORT_ERROR_SOCKET_WOULDBLOCK;
+    case HYPORT_ERROR_SOCKET_UNIX_EPROTONOSUPPORT:
+      return HYPORT_ERROR_SOCKET_BADPROTO;
+    case HYPORT_ERROR_SOCKET_UNIX_EFAULT:
+      return HYPORT_ERROR_SOCKET_ARGSINVALID;
+    case HYPORT_ERROR_SOCKET_UNIX_ETIMEDOUT:
+      return HYPORT_ERROR_SOCKET_TIMEOUT;
+    case HYPORT_ERROR_SOCKET_UNIX_CONNREFUSED:
+      return HYPORT_ERROR_SOCKET_CONNECTION_REFUSED;
+    case HYPORT_ERROR_SOCKET_UNIX_ENETUNREACH:
+      return HYPORT_ERROR_SOCKET_ENETUNREACH;
+    case HYPORT_ERROR_SOCKET_UNIX_EACCES:
+      return HYPORT_ERROR_SOCKET_EACCES;
+    default:
+      return HYPORT_ERROR_SOCKET_OPFAILED;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION findHostError
+
+/**
+ * @internal Determines the proper portable error code to return given a native host error code
+ *
+ * @return	the (negative) error code
+ */
+static I_32
+findHostError (int herr)
+{
+  switch (herr)
+    {
+    case HYPORT_ERROR_SOCKET_UNIX_NORECOVERY:
+      return HYPORT_ERROR_SOCKET_NORECOVERY;
+    case HYPORT_ERROR_SOCKET_UNIX_HOSTNOTFOUND:
+      return HYPORT_ERROR_SOCKET_HOSTNOTFOUND;
+    case HYPORT_ERROR_SOCKET_UNIX_NODATA:
+      return HYPORT_ERROR_SOCKET_NODATA;
+    case HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN:
+      return HYPORT_ERROR_SOCKET_INTERRUPTED;
+    default:
+      return HYPORT_ERROR_SOCKET_BADSOCKET;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION map_addr_family_Hy_to_OS
+
+/**
+ * @internal Map the portable address family to the platform address family. 
+ *
+ * @param	addr_family	the portable address family to convert
+ *
+ * @return	the platform family, or OS_AF_UNSPEC if none exists
+ */
+I_32
+map_addr_family_Hy_to_OS (I_32 addr_family)
+{
+  switch (addr_family)
+    {
+    case HYADDR_FAMILY_AFINET4:
+      return OS_AF_INET4;
+    case HYADDR_FAMILY_AFINET6:
+      return OS_AF_INET6;
+    }
+  return OS_AF_UNSPEC;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION map_protocol_family_Hy_to_OS
+
+/**
+ * @internal Map the portable address protocol to the platform protocol
+ *
+ * @param	addr_protocol  the portable address protocol to convert
+ *
+ * @return	the platform family, or OS_PF_UNSPEC if none exists
+ */
+I_32
+map_protocol_family_Hy_to_OS (I_32 addr_family)
+{
+  switch (addr_family)
+    {
+    case HYPROTOCOL_FAMILY_INET4:
+      return OS_PF_INET4;
+    case HYPROTOCOL_FAMILY_INET6:
+      return OS_PF_INET6;
+    }
+  return OS_PF_UNSPEC;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION map_sockettype_Hy_to_OS
+
+/**
+ * @internal Map the portable socket type to the platform type. 
+ *
+ * @param	addr_family	the portable socket type to convert
+ *
+ * @return	the platform family, or OSSOCK_ANY if none exists
+ */
+I_32
+map_sockettype_Hy_to_OS (I_32 socket_type)
+{
+  switch (socket_type)
+    {
+    case HYSOCKET_STREAM:
+      return OSSOCK_STREAM;
+    case HYSOCKET_DGRAM:
+      return OSSOCK_DGRAM;
+    case HYSOCKET_RAW:
+      return OSSOCK_RAW;
+    case HYSOCKET_RDM:
+      return OSSOCK_RDM;
+    case HYSOCKET_SEQPACKET:
+      return OSSOCK_SEQPACKET;
+    }
+  return OSSOCK_ANY;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION platformSocketLevel
+
+/**
+ * @internal
+ * Map the portable to the platform socket level.  Used to resolve the arguments of socket option functions.
+ * Levels currently in use are:
+ * \arg SOL_SOCKET, for most options
+ * \arg IPPROTO_TCP, for the TCP noDelay option
+ * \arg IPPROTO_IP, for the option operations associated with multicast (join, drop, interface)
+ *
+ * @param[in] portableSocketLevel The portable socket level to convert.
+ *
+ * @return	the platform socket level or a (negative) error code if no equivalent level exists.
+ */
+/**
+ * @internal Map the portable to the platform socket level.  Used to resolve the arguments of socket option functions.
+ * Levels currently in use are:
+ *		SOL_SOCKET, for most options
+ *		IPPROTO_TCP, for the TCP noDelay option
+ *		IPPROTO_IP, for the option operations associated with multicast (join, drop, interface)
+ *
+ * @param	portlib		pointer to the VM port library
+ * @param	portableSocketLevel	the portable socket level to convert
+ *
+ * @return	the platform socket level or an error if no equivalent level exists
+ */
+I_32
+platformSocketLevel (I_32 portableSocketLevel)
+{
+  switch (portableSocketLevel)
+    {
+    case HY_SOL_SOCKET:
+      return OS_SOL_SOCKET;
+    case HY_IPPROTO_TCP:
+      return OS_IPPROTO_TCP;
+    case HY_IPPROTO_IP:
+      return OS_IPPROTO_IP;
+#if defined(IPv6_FUNCTION_SUPPORT)
+    case HY_IPPROTO_IPV6:
+      return OS_IPPROTO_IPV6;
+#endif
+
+    }
+  return HYPORT_ERROR_SOCKET_SOCKLEVELINVALID;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION platformSocketOption
+
+/**
+ * @internal
+ * Map the portable to the platform socket options.  Used to resolve the arguments of socket option functions.
+ * Options currently in supported are:
+ * \arg SOL_LINGER, the linger timeout
+ * \arg TCP_NODELAY, the buffering scheme implementing Nagle's algorithm
+ * \arg IP_MULTICAST_TTL, the packet Time-To-Live
+ * \arg IP_ADD_MEMBERSHIP, to join a multicast group
+ * \arg  IP_DROP_MEMBERSHIP, to leave a multicast group
+ * \arg IP_MULTICAST_IF, the multicast interface
+ *
+ * @param[in] portableSocketOption The portable socket option to convert.
+ *
+ * @return	the platform socket option or a (negative) error code if no equivalent option exists.
+ */
+/**
+ * @internal Map the portable to the platform socket options.  Used to resolve the arguments of socket option functions.
+ * Options currently in supported are:
+ *		SOL_LINGER, the linger timeout
+ *		TCP_NODELAY, the buffering scheme implementing Nagle's algorithm
+ *		IP_MULTICAST_TTL, the packet Time-To-Live
+ *		IP_ADD_MEMBERSHIP, to join a multicast group
+ *		IP_DROP_MEMBERSHIP, to leave a multicast group
+ *		IP_MULTICAST_IF, the multicast interface
+ *
+ * @param	portlib		pointer to the VM port library
+ * @param	portableSocketOption	the portable socket option to convert
+ *
+ * @return	the platform socket option or an error if no equivalent option exists
+ */
+/* Support datagram broadcasts */
+I_32
+platformSocketOption (I_32 portableSocketOption)
+{
+  switch (portableSocketOption)
+    {
+    case HY_SO_LINGER:
+      return OS_SO_LINGER;
+    case HY_SO_KEEPALIVE:
+      return OS_SO_KEEPALIVE;
+    case HY_TCP_NODELAY:
+      return OS_TCP_NODELAY;
+    case HY_MCAST_TTL:
+      return OS_MCAST_TTL;
+    case HY_MCAST_ADD_MEMBERSHIP:
+      return OS_MCAST_ADD_MEMBERSHIP;
+    case HY_MCAST_DROP_MEMBERSHIP:
+      return OS_MCAST_DROP_MEMBERSHIP;
+    case HY_MCAST_INTERFACE:
+      return OS_MCAST_INTERFACE;
+    case HY_SO_REUSEADDR:
+      return OS_SO_REUSEADDR;
+    case HY_SO_SNDBUF:
+      return OS_SO_SNDBUF;
+    case HY_SO_RCVBUF:
+      return OS_SO_RCVBUF;
+    case HY_SO_BROADCAST:
+      return OS_SO_BROADCAST;
+
+    case HY_SO_OOBINLINE:
+      return OS_SO_OOBINLINE;
+    case HY_IP_MULTICAST_LOOP:
+      return OS_MCAST_LOOP;
+    case HY_IP_TOS:
+      return OS_IP_TOS;
+#if defined(IPv6_FUNCTION_SUPPORT)
+    case HY_MCAST_INTERFACE_2:
+      return OS_MCAST_INTERFACE_2;
+    case HY_IPV6_ADD_MEMBERSHIP:
+      return OS_IPV6_ADD_MEMBERSHIP;
+    case HY_IPV6_DROP_MEMBERSHIP:
+      return OS_IPV6_DROP_MEMBERSHIP;
+#endif
+
+    }
+  return HYPORT_ERROR_SOCKET_OPTUNSUPP;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_accept
+
+/**
+ * The accept function extracts the first connection on the queue of pending connections 
+ * on socket sock. It then creates a new socket and returns a handle to the new socket. 
+ * The newly created socket is the socket that will handle the actual the connection and 
+ * has the same properties as socket sock.  
+ *
+ * The accept function can block the caller until a connection is present if no pending 
+ * connections are present on the queue.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] serverSock  A hysocket_t  from which data will be read.
+ * @param[in] addrHandle An optional pointer to a buffer that receives the address of the connecting 
+ * entity, as known to the communications layer. The exact format of the addr parameter 
+ * is determined by the address family established when the socket was created. 
+ * @param[in] sockHandle A pointer to a hysocket_t  which will point to the newly created 
+ * socket once accept returns succesfully
+ *
+ * @return 
+ * \arg 0 on success
+ * \arg HYPORT_ERROR_SOCKET_BADSOCKET, on generic error
+ * \arg HYPORT_ERROR_SOCKET_NOTINITIALIZED, if socket library uninitialized
+ * \arg HYPORT_ERROR_SOCKET_INTERRUPTED, the call was cancelled
+ * \arg HYPORT_ERROR_SOCKET_ADDRNOTAVAIL, the addr parameter is not valid
+ * \arg HYPORT_ERROR_SOCKET_SYSTEMBUSY, if system busy handling other requests
+ * \arg HYPORT_ERROR_SOCKET_SYSTEMFULL, is too many sockets are active
+ * \arg HYPORT_ERROR_SOCKET_WOULDBLOCK, the socket is marked as nonblocking and no connections are present to be accepted., 
+ */
+I_32 VMCALL
+hysock_accept (struct HyPortLibrary * portLibrary, hysocket_t serverSock,
+               hysockaddr_t addrHandle, hysocket_t * sockHandle)
+{
+#if defined(LINUX)
+#define ACCEPTCAST (socklen_t *)
+#else
+#define ACCEPTCAST
+#endif
+
+  I_32 rc = 0;
+  int sc;
+  socklen_t fromlen = sizeof (addrHandle->addr);
+
+  *sockHandle = INVALID_SOCKET;
+
+  sc =
+    accept (SOCKET_CAST (serverSock), (struct sockaddr *) &addrHandle->addr,
+            ACCEPTCAST & fromlen);
+  if (sc < 0)
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<accept failed, err=%d>\n", rc);
+      rc =
+        portLibrary->error_set_last_error (portLibrary, rc,
+                                           HYPORT_ERROR_SOCKET_ADDRNOTAVAIL);
+    }
+
+  if (rc == 0)
+    {
+      *sockHandle =
+        portLibrary->mem_allocate_memory (portLibrary,
+                                          sizeof (struct hysocket_struct));
+#if (defined(VALIDATE_ALLOCATIONS))
+      if (*sockHandle == NULL)
+        {
+          close (sc);
+          *sockHandle = INVALID_SOCKET;
+          return HYPORT_ERROR_SOCKET_NOBUFFERS;
+        }
+#endif
+
+      SOCKET_CAST (*sockHandle) = sc;
+      (*sockHandle)->family = serverSock->family;
+    }
+  return rc;
+}
+
+#undef ACCEPTCAST
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_bind
+
+/**
+ * The bind function is used on an unconnected socket before subsequent 
+ * calls to the connect or listen functions. When a socket is created with a 
+ * call to the socket function, it exists in a name space (address family), but 
+ * it has no name assigned to it. Use bind to establish the local association 
+ * of the socket by assigning a local name to an unnamed socket.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock hysocket_t which will be be associated with the specified name.
+ * @param[in] addr Address to bind to socket.
+ *
+ * @return
+ * \arg 0, on success
+ * \arg HYPORT_ERROR_SOCKET_BADSOCKET, on generic error
+ * \arg HYPORT_ERROR_SOCKET_NOTINITIALIZED, if socket library uninitialized
+ * \arg HYPORT_ERROR_SOCKET_ADDRINUSE  A process on the machine is already bound to the same fully-qualified address 
+ * and the socket has not been marked to allow address re-use with SO_REUSEADDR. 
+ * \arg HYPORT_ERROR_SOCKET_ADDRNOTAVAIL The specified address is not a valid address for this machine 
+ * \arg HYPORT_ERROR_SOCKET_SYSTEMBUSY, if system busy handling other requests
+ * \arg HYPORT_ERROR_SOCKET_SYSTEMFULL, is too many sockets are active
+ * \arg HYPORT_ERROR_SOCKET_BADADDR, the addr parameter is not a valid part of the user address space, 
+ */
+I_32 VMCALL
+hysock_bind (struct HyPortLibrary * portLibrary, hysocket_t sock,
+             hysockaddr_t addr)
+{
+  I_32 rc = 0;
+  I_32 length = sizeof (addr->addr);
+
+#if defined(SIN6_LEN)
+  length = sizeof (struct sockaddr_storage);
+#if defined(IPv6_FUNCTION_SUPPORT)
+  if (((OSSOCKADDR *) & addr->addr)->sin_family == OS_AF_INET6)
+    {
+      length = ((OSSOCKADDR_IN6 *) & addr->addr)->sin6_len;
+    }
+#endif
+#endif
+
+  if (bind
+      (SOCKET_CAST (sock), (struct sockaddr *) &addr->addr,
+       sizeof (addr->addr)) < 0)
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<bind failed, err=%d>\n", rc);
+      rc =
+        portLibrary->error_set_last_error (portLibrary, rc,
+                                           HYPORT_ERROR_SOCKET_ADDRNOTAVAIL);
+    }
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_close
+
+/**
+ * The close function closes a socket. Use it to release the socket descriptor socket so 
+ * further references to socket will fail.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock hysocket_t  which will be closed.
+ *
+ * @return
+ * \arg 0, on success
+ * \arg HYPORT_ERROR_SOCKET_BADSOCKET, on generic error
+ * \arg HYPORT_ERROR_SOCKET_SYSTEMBUSY, if system busy handling other requests
+ * \arg HYPORT_ERROR_SOCKET_WOULDBLOCK,  the socket is marked as nonblocking and SO_LINGER is set to a nonzero time-out value.
+ */
+I_32 VMCALL
+hysock_close (struct HyPortLibrary * portLibrary, hysocket_t * sock)
+{
+  I_32 rc = 0;
+
+  if ((*sock == INVALID_SOCKET) || (close (SOCKET_CAST (*sock)) < 0))
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<closesocket failed, err=%d>\n", rc);
+      rc =
+        portLibrary->error_set_last_error (portLibrary, rc,
+                                           HYPORT_ERROR_SOCKET_BADSOCKET);
+    }
+
+  if (*sock != INVALID_SOCKET)
+    {
+      portLibrary->mem_free_memory (portLibrary, *sock);
+    }
+  *sock = INVALID_SOCKET;
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_connect
+
+/**
+ * Establish a connection to a peer.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock pointer to the unconnected local socket.
+ * @param[in] addr	pointer to the sockaddr, specifying remote host/port.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_connect (struct HyPortLibrary * portLibrary, hysocket_t sock,
+                hysockaddr_t addr)
+{
+  I_32 rc = 0;
+
+  if (connect
+      (SOCKET_CAST (sock), (struct sockaddr *) &addr->addr,
+       sizeof (addr->addr)) < 0)
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<connect failed, err=%d>\n", rc);
+      rc =
+        portLibrary->error_set_last_error (portLibrary, rc,
+                                           HYPORT_ERROR_SOCKET_OPFAILED);
+    }
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_error_message
+
+/**
+ * Return an error message describing the last OS error that occurred.  The last
+ * error returned is not thread safe, it may not be related to the operation that
+ * failed for this thread.
+ *
+ * @param[in] portLibrary The port library
+ *
+ * @return	error message describing the last OS error, may return NULL.
+ *
+ * @internal
+ * @note  This function gets the last error code from the OS and then returns
+ * the corresponding string.  It is here as a helper function for JCL.  Once hyerror
+ * is integrated into the port library this function should probably disappear.
+ */
+const char *VMCALL
+hysock_error_message (struct HyPortLibrary *portLibrary)
+{
+  return portLibrary->error_last_error_message (portLibrary);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_fdset_init
+
+/**
+ * Create a file descriptor (FD) set of one element.  The call may not be generally useful,
+ * as it currently only supports a single FD and is assumed to be used in conjunction with the 
+ * hysock_select function.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] socketP pointer to the socket to be added to the FD set.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_fdset_init (struct HyPortLibrary * portLibrary, hysocket_t socketP)
+{
+  PortlibPTBuffers_t ptBuffers;
+  hyfdset_t fdset;
+
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+
+  if (NULL == ptBuffers->fdset)
+    {
+      ptBuffers->fdset =
+        portLibrary->mem_allocate_memory (portLibrary,
+                                          sizeof (struct hyfdset_struct));
+      if (NULL == ptBuffers->fdset)
+        {
+          return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+        }
+    }
+  fdset = ptBuffers->fdset;
+  memset (fdset, 0, sizeof (struct hyfdset_struct));
+
+  FD_ZERO (&fdset->handle);
+  FD_SET (SOCKET_CAST (socketP), &fdset->handle);
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_fdset_size
+
+/**
+ * Answer the maximum size of the fdset currently declared for the platform.
+ * This value is a parameter of the @ref hysock_select call.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle
+ *
+ * @return	the maximum size of the fdset, otherwise the (negative) error code.
+ *
+ * @note On Unix, the value was the maximum file descriptor plus one, although
+ * on many flavors, the value is ignored in the select function.
+ * It is essential on Neutrino 2.0.
+ * On Windows, the value is ignored by the select function.
+ * On OS/2, the value is the number of file descriptors to be checked.
+ */
+I_32 VMCALL
+hysock_fdset_size (struct HyPortLibrary * portLibrary, hysocket_t handle)
+{
+  return SOCKET_CAST (handle) + 1;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_freeaddrinfo
+
+/**
+ * Frees the memory created by the call to @ref hysock_getaddrinfo().
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Hints on what results are returned and how the response if formed .
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_freeaddrinfo (struct HyPortLibrary * portLibrary, hyaddrinfo_t handle)
+{
+
+#if defined(IPv6_FUNCTION_SUPPORT)
+  freeaddrinfo ((OSADDRINFO *) handle->addr_info);
+#endif
+
+  handle->addr_info = NULL;
+  handle->length = 0;
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getaddrinfo
+
+/**
+ * Answers a list of addresses as an opaque pointer in "result".
+ * 
+ * Use the following functions to extract the details:
+ * \arg \ref hysock_getaddrinfo_length
+ * \arg \ref hysock_getaddrinfo_name
+ * \arg \ref hysock_getaddrinfo_address
+ * \arg \ref hysock_getaddrinfo_family
+ *
+ * If the machine type supports IPv6 you can specify how you want the results returned with the following function:
+ * \arg \ref hysock_create_getaddrinfo_hints.
+ * Passing the structure into a machine with only IPv4 support will have no effect.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] name The name of the host in either host name format or in IPv4 or IPv6 accepted notations.
+ * @param[in] hints Hints on what results are returned and how the response if formed (can be NULL for default action).
+ * @param[out] result An opaque pointer to a list of results (hyaddrinfo_struct must be preallocated).
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ *
+ * @note you must free the "result" structure with @ref hysock_freeaddrinfo to free up memory.  This must be done
+ * before you make a subsequent call in the same thread to this function. 
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_getaddrinfo (struct HyPortLibrary * portLibrary, char *name,
+                    hyaddrinfo_t hints, hyaddrinfo_t result)
+{
+  /* If we have the IPv6 functions available we will call them, otherwise we'll call the IPv4 function */
+#if defined(IPv6_FUNCTION_SUPPORT)
+  OSADDRINFO *ipv6_result;
+  OSADDRINFO *addr_info_hints = NULL;
+  int count = 0;
+  if (hints != NULL)
+    {
+      addr_info_hints = (OSADDRINFO *) hints->addr_info;
+    }
+  if (0 != getaddrinfo (name, NULL, addr_info_hints, &ipv6_result))
+    {
+      I_32 errorCode = errno;
+      HYSOCKDEBUG ("<getaddrinfo failed, err=%d>\n", errorCode);
+      return portLibrary->error_set_last_error (portLibrary, errorCode,
+                                                findError (errorCode));
+    }
+  memset (result, 0, sizeof (struct hyaddrinfo_struct));
+  result->addr_info = (void *) ipv6_result;
+  while (ipv6_result->ai_next != NULL)
+    {
+      count++;
+      ipv6_result = ipv6_result->ai_next;
+    }
+  result->length = ++count;     /* Have to add an extra, because we didn't count the first entry */
+
+  return 0;
+#else /* IPv6_FUNCTION_SUPPORT */
+  I_32 rc = 0;
+  U_32 addr = 0;
+  U_32 count = 0;
+  struct hyhostent_struct hyhostent;
+  if (0 != portLibrary->sock_inetaddr (portLibrary, name, &addr))
+    {
+      if (0 !=
+          (rc =
+           portLibrary->sock_gethostbyname (portLibrary, name, &hyhostent)))
+        {
+          return rc;
+        }
+    }
+  else
+    {
+      if (0 !=
+          (rc =
+           portLibrary->sock_gethostbyaddr (portLibrary, (char *) &addr,
+                                            sizeof (addr), HYSOCK_AFINET,
+                                            &hyhostent)))
+        {
+          return rc;
+        }
+    }
+  memset (result, 0, sizeof (struct hyaddrinfo_struct));
+  result->addr_info = (void *) hyhostent.entity;
+  /* count the host names and the addresses */
+  while (hyhostent.entity->h_addr_list[count] != 0)
+    {
+      count++;
+    }
+  result->length = count;
+  return 0;
+#endif /* IPv6_FUNCTION_SUPPORT */
+
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getaddrinfo_address
+
+/**
+ * Answers a U_8 array representing the address at "index" in the structure returned from @ref hysock_getaddrinfo, indexed starting at 0.
+ * The address is in network byte order. 
+ *
+ * The address will either be 4 or 16 bytes depending on whether it is an OS_AF_INET  address or an OS_AF_INET6  address.  You can check
+ * this will a call to @ref hysock_getaddrinfo_family.  Therefore you should either check the family type before preallocating the "address"
+ * or define it as 16 bytes.
+ *
+ * @param[in]   portLibrary The port library.
+ * @param[in]   handle The result structure returned by @ref hysock_getaddrinfo.
+ * @param[out] address The address at "index" in a preallocated buffer.
+ * @param[in]   index The address index into the structure returned by @ref hysock_getaddrinfo.
+ * @param[out] scope_id  The scope id associated with the address if applicable
+ *
+ * @return	
+ * \arg 0, if no errors occurred, otherwise the (negative) error code
+ * \arg HYPORT_ERROR_SOCKET_VALUE_NULL when we have have the old IPv4 gethostbyname call and the address indexed is out
+ * of range.  This is because the address list and the host alias list are not the same length.  Just skip this entry.
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_getaddrinfo_address (struct HyPortLibrary * portLibrary,
+                            hyaddrinfo_t handle, U_8 * address, int index,
+                            U_32 * scope_id)
+{
+  I_32 rc = 0;
+  OSADDRINFO *addr;
+  void *sock_addr;
+  char **addr_list;
+  int i;
+
+  /* If we have the IPv6 functions available we cast to an OSADDRINFO structure otherwise a OSHOSTENET structure */
+#if defined(IPv6_FUNCTION_SUPPORT)
+  addr = (OSADDRINFO *) handle->addr_info;
+  for (i = 0; i < index; i++)
+    {
+      addr = addr->ai_next;
+    }
+  if (addr->ai_family == OS_AF_INET6)
+    {
+      sock_addr = ((OSSOCKADDR_IN6 *) addr->ai_addr)->sin6_addr.s6_addr;
+      memcpy (address, sock_addr, 16);
+      *scope_id = ((OSSOCKADDR_IN6 *) addr->ai_addr)->sin6_scope_id;
+    }
+  else
+    {
+      sock_addr = &((OSSOCKADDR *) addr->ai_addr)->sin_addr.s_addr;
+      memcpy (address, sock_addr, 4);
+    }
+#else
+  addr_list = ((OSHOSTENT *) handle->addr_info)->h_addr_list;
+  for (i = 0; i < index; i++)
+    {
+      if (addr_list[i] == NULL)
+        {
+          return HYPORT_ERROR_SOCKET_VALUE_NULL;
+        }
+    }
+  memcpy (address, addr_list[index], 4);
+#endif
+
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getaddrinfo_create_hints
+
+/**
+ * Answers a hints structure as an opaque pointer in "result".
+ * 
+ * This hints structure is used to modify the results returned by a call to @ref hysock_getaddrinfo.  There is one of
+ * these structures per thread, so subsequent calls to this function will overwrite the same structure in memory.
+ * The structure is cached in ptBuffers and is cleared when a call to @ref hyport_free_ptBuffer is made.
+ *
+ * This function is only works on IPv6 supported OS's.  If it is called on an OS that does not support IPv6 then
+ * it essentially returns a NULL pointer, meaning it will have no effect on the call to @ref hysock_getaddrinfo.
+ *
+ * See man pages, or MSDN doc on getaddrinfo for information on how the hints structure works.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[out] result The filled in (per thread) hints structure
+ * @param[in] family A address family type
+ * @param[in] socktype A socket type
+ * @param[in] protocol A protocol family
+ * @param[in] flags Flags for modifying the result
+ *
+ * @return
+ * \arg 0, if no errors occurred, otherwise the (negative) error code
+ * \arg HYPORT_ERROR_SOCKET_SYSTEMFULL -- when we can't allocate memory for the ptBuffers, or the hints structure
+ *
+ * @note current supported family types are:
+ * \arg HYADDR_FAMILY_UNSPEC
+ * \arg HYADDR_FAMILY_AFINET4
+ * \arg HYADDR_FAMILY_AFINET6
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_getaddrinfo_create_hints (struct HyPortLibrary * portLibrary,
+                                 hyaddrinfo_t * result, I_16 family,
+                                 I_32 socktype, I_32 protocol, I_32 flags)
+{
+  I_32 rc = 0;
+#if defined(IPv6_FUNCTION_SUPPORT)
+  OSADDRINFO *addrinfo;
+  PortlibPTBuffers_t ptBuffers;
+#endif /* IPv6_FUNCTION_SUPPORT */
+
+  *result = NULL;
+
+  /* If we have the IPv6 functions available we fill in the structure, otherwise it is null */
+#if defined(IPv6_FUNCTION_SUPPORT)
+#define addrinfohints (ptBuffers->addr_info_hints).addr_info
+  /* Initialized the pt buffers if necessary */
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+  if (!addrinfohints)
+    {
+      addrinfohints =
+        portLibrary->mem_allocate_memory (portLibrary, sizeof (OSADDRINFO));
+      if (!addrinfohints)
+        {
+          return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+        }
+    }
+  memset (addrinfohints, 0, sizeof (OSADDRINFO));
+  addrinfo = (OSADDRINFO *) addrinfohints;
+  addrinfo->ai_flags = flags;
+  addrinfo->ai_family = map_addr_family_Hy_to_OS (family);
+  addrinfo->ai_socktype = map_sockettype_Hy_to_OS (socktype);
+  addrinfo->ai_protocol = map_protocol_family_Hy_to_OS (protocol);
+  *result = &ptBuffers->addr_info_hints;
+#undef addrinfohints
+#endif /*IPv6_FUNCTION_SUPPORT */
+
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getaddrinfo_family
+
+/**
+ * Answers the family type of the address at "index" in the structure returned from @ref hysock_getaddrinfo, indexed starting at 0.
+ *
+ * Currently the family types we support are HYSOCK_AFINET and HYSOCK_AFINET6.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle The result structure returned by @ref hysock_getaddrinfo.
+ * @param[out] family The family at "index".
+ * @param[in] index The address index into the structure returned by @ref hysock_getaddrinfo.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_getaddrinfo_family (struct HyPortLibrary * portLibrary,
+                           hyaddrinfo_t handle, I_32 * family, int index)
+{
+  I_32 rc = 0;
+  OSADDRINFO *addr;
+  int i;
+
+  /* If we have the IPv6 functions then we'll cast to a OSADDRINFO othewise we have a hostent */
+#if defined(IPv6_FUNCTION_SUPPORT)
+  addr = (OSADDRINFO *) handle->addr_info;
+  for (i = 0; i < index; i++)
+    {
+      addr = addr->ai_next;
+    }
+  if (addr->ai_family == OS_AF_INET4)
+    {
+      *family = HYADDR_FAMILY_AFINET4;
+    }
+  else
+    {
+      *family = HYADDR_FAMILY_AFINET6;
+    }
+#else
+  *family = HYADDR_FAMILY_AFINET4;
+#endif
+
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getaddrinfo_length
+
+/**
+ * Answers the number of results returned from @ref hysock_getaddrinfo.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle The result structure returned by @ref hysock_getaddrinfo.
+ * @param[out] length The number of results.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_getaddrinfo_length (struct HyPortLibrary * portLibrary,
+                           hyaddrinfo_t handle, I_32 * length)
+{
+  *length = handle->length;
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getaddrinfo_name
+
+/**
+ * Answers the cannon name of the address at "index" in the structure returned from @ref hysock_getaddrinfo, indexed starting at 0.
+ * 
+ * The preallocated buffer for "name" should be the size of the maximum host name: OSNIMAXHOST.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle The result structure returned by @ref hysock_getaddrinfo.
+ * @param[out] name The name of the address at "index" in a preallocated buffer.
+ * @param[in] index The address index into the structure returned by @ref hysock_getaddrinfo.
+ *
+ * @return
+ * \arg 0, if no errors occurred, otherwise the (negative) error code.
+ * \arg HYPORT_ERROR_SOCKET_VALUE_NULL when we have have the old IPv4 gethostbyname call and the name indexed is out
+ * of range.  This is because the address list and the host alias list are not the same length.  Just skip this entry.
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_getaddrinfo_name (struct HyPortLibrary * portLibrary,
+                         hyaddrinfo_t handle, char *name, int index)
+{
+  I_32 rc = 0;
+  char **alias_list;
+  int i;
+  OSADDRINFO *addr;
+
+  /* If we have the IPv6 functions available we cast to an OSADDRINFO structure otherwise a OSHOSTENET structure */
+#if defined(IPv6_FUNCTION_SUPPORT)
+  addr = (OSADDRINFO *) handle->addr_info;
+  for (i = 0; i < index; i++)
+    {
+      addr = addr->ai_next;
+    }
+  if (addr->ai_canonname == NULL)
+    {
+      name[0] = 0;
+    }
+  else
+    {
+      strcpy (name, addr->ai_canonname);
+    }
+#else
+  alias_list = ((OSHOSTENT *) handle->addr_info)->h_aliases;
+  for (i = 0; i < index; i++)
+    {
+      if (alias_list[i] == NULL)
+        {
+          return HYPORT_ERROR_SOCKET_VALUE_NULL;
+        }
+    }
+  if (alias_list[index] == NULL)
+    {
+      name[0] = 0;
+    }
+  else
+    {
+      strcpy (name, alias_list[index]);
+    }
+#endif
+
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_gethostbyaddr
+
+/**
+ * Answer information on the host referred to by the address.  The information includes name, aliases and
+ * addresses for the nominated host (the latter being relevant on multi-homed hosts).
+ * This call has only been tested for addresses of type AF_INET.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] addr Pointer to the binary-format (not null-terminated) address, in network byte order.
+ * @param[in] length Length of the addr.
+ * @param[in] type The type of the addr.
+ * @param[out] handle Pointer to the hyhostent_struct, to be linked to the per thread platform hostent struct.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_gethostbyaddr (struct HyPortLibrary * portLibrary, char *addr,
+                      I_32 length, I_32 type, hyhostent_t handle)
+{
+#if !HOSTENT_DATA_R
+  OSHOSTENT *result;
+#endif
+
+#if GLIBC_R||OTHER_R
+  BOOLEAN allocBuffer = FALSE;
+#endif
+
+  int herr = 0;
+  int i = 0;
+
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R||NO_R
+  PortlibPTBuffers_t ptBuffers;
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+#define hostentBuffer (&ptBuffers->hostent)
+#endif /*HOSTENT_DATA_R || GLIBC_R || OTHER_R */
+
+/* one of several threadsafe gethostbyaddr calls must be made depending on the current platform */
+/* if there is a transient error (HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN), try making the call again */
+  for (i = 0; i < MAX_RETRIES; i++)
+    {
+#if HOSTENT_DATA_R
+#define dataBuffer (ptBuffers->hostent_data)
+      if (NULL == dataBuffer)
+        {
+          dataBuffer =
+            portLibrary->mem_allocate_memory (portLibrary,
+                                              sizeof (OSHOSTENT_DATA));
+          if (NULL == dataBuffer)
+            {
+              return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+            }
+        }
+      herr = gethostbyaddr_r (addr, length, type, hostentBuffer, dataBuffer);
+#undef dataBuffer
+#elif ORIGINAL_R || NO_R
+#if NO_R
+      MUTEX_ENTER (hostentLock);
+#endif
+      result = gethostbyaddr (addr, length, type);
+#if NO_R
+      if (result)
+        {
+          herr = copy_hostent (portLibrary, result, &ptBuffers);
+        }
+      MUTEX_EXIT (hostentLock);
+      if (herr != 0)
+        {
+          return herr;
+        }
+#endif
+      herr = h_errno;
+#elif GLIBC_R || OTHER_R
+#define buffer (ptBuffers->gethostBuffer)
+#define bufferSize (ptBuffers->gethostBufferSize)
+      if (NULL == buffer)
+        {
+          bufferSize = GET_HOST_BUFFER_SIZE;
+        }
+      while (TRUE)
+        {
+          if (allocBuffer == TRUE || (NULL == buffer))
+            {
+              /* The buffer is allocated bufferSize + EXTRA_SPACE, while gethostby*_r is only aware of bufferSize
+               * because there seems to be a bug on Linux 386 where gethostbyname_r writes past the end of the
+               * buffer.  This bug has not been observed on other platforms, but EXTRA_SPACE is added anyway as a precaution.*/
+              buffer =
+                portLibrary->mem_allocate_memory (portLibrary,
+                                                  bufferSize + EXTRA_SPACE);
+              if (NULL == buffer)
+                {
+                  return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+                }
+              allocBuffer = FALSE;
+            }
+#if GLIBC_R
+          gethostbyaddr_r (addr, length, type, hostentBuffer, buffer,
+                           bufferSize, &result, &herr);
+#elif OTHER_R
+          result =
+            gethostbyaddr_r (addr, length, type, hostentBuffer, buffer,
+                             bufferSize, &herr);
+#endif /* GLIBC_R */
+/* allocate more space if the buffer is too small */
+          if (errno == ERANGE || herr == ERANGE)
+            {
+              portLibrary->mem_free_memory (portLibrary, buffer);
+              bufferSize *= 2;
+              allocBuffer = TRUE;
+            }
+          else
+            {
+              break;
+            }
+        }
+#undef buffer
+#undef bufferSize
+#endif
+
+      if (herr != HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN)
+        {
+          break;
+        }
+    }
+
+#if HOSTENT_DATA_R
+  if (herr != 0)
+    {
+      herr = h_errno;
+      HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
+      return portLibrary->error_set_last_error (portLibrary, herr,
+                                                findHostError (herr));
+    }
+#else
+  if (result == NULL)
+    {
+      HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
+      return portLibrary->error_set_last_error (portLibrary, herr,
+                                                findHostError (herr));
+    }
+#endif
+
+  else
+    {
+      memset (handle, 0, sizeof (struct hyhostent_struct));
+#if HOSTENT_DATA_R||NO_R
+      handle->entity = hostentBuffer;
+#else
+      handle->entity = result;
+#endif
+
+    }
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R
+#undef hostentBuffer
+#endif /*HOSTENT_DATA_R || GLIBC_R || OTHER_R */
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_gethostbyname
+
+/**
+ * Answer information on the host, specified by name.  The information includes host name,
+ * aliases and addresses.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] name The host name string.
+ * @param[out] handle Pointer to the hyhostent_struct (to be linked to the per thread platform hostent struct).
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_gethostbyname (struct HyPortLibrary * portLibrary, char *name,
+                      hyhostent_t handle)
+{
+#if !HOSTENT_DATA_R
+  OSHOSTENT *result;
+#endif
+
+#if GLIBC_R||OTHER_R
+  BOOLEAN allocBuffer = FALSE;
+#endif
+
+  int herr = 0;
+  int i = 0;
+
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R||NO_R
+  PortlibPTBuffers_t ptBuffers;
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+#define hostentBuffer (&ptBuffers->hostent)
+#endif /*HOSTENT_DATA_R || GLIBC_R || OTHER_R */
+
+/* one of several threadsafe gethostbyname calls must be made depending on the current platform */
+/* if there is a transient error (HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN), try making the call again */
+  for (i = 0; i < MAX_RETRIES; i++)
+    {
+#if HOSTENT_DATA_R
+#define dataBuffer (ptBuffers->hostent_data)
+      if (!dataBuffer)
+        {
+          dataBuffer =
+            portLibrary->mem_allocate_memory (portLibrary,
+                                              sizeof (OSHOSTENT_DATA));
+          if (!dataBuffer)
+            {
+              return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+            }
+        }
+      herr = gethostbyname_r (name, hostentBuffer, dataBuffer);
+#undef dataBuffer
+#elif ORIGINAL_R || NO_R
+#if NO_R
+      MUTEX_ENTER (hostentLock);
+#endif
+      result = gethostbyname (name);
+#if NO_R
+      if (result)
+        {
+          herr = copy_hostent (portLibrary, result, &ptBuffers);
+        }
+      MUTEX_EXIT (hostentLock);
+      if (herr != 0)
+        {
+          return herr;
+        }
+#endif
+      herr = h_errno;
+#elif GLIBC_R || OTHER_R
+#define buffer (ptBuffers->gethostBuffer)
+#define bufferSize (ptBuffers->gethostBufferSize)
+      if (!buffer)
+        {
+          bufferSize = GET_HOST_BUFFER_SIZE;
+        }
+      while (TRUE)
+        {
+          if (allocBuffer == TRUE || !buffer)
+            {
+              /* The buffer is allocated bufferSize + EXTRA_SPACE, while gethostby*_r is only aware of bufferSize
+               * because there seems to be a bug on Linux 386 where gethostbyname_r writes past the end of the
+               * buffer.  This bug has not been observed on other platforms, but EXTRA_SPACE is added anyway as a precaution.*/
+              buffer =
+                portLibrary->mem_allocate_memory (portLibrary,
+                                                  bufferSize + EXTRA_SPACE);
+              if (!buffer)
+                {
+                  return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+                }
+              allocBuffer = FALSE;
+            }
+#if GLIBC_R
+          gethostbyname_r (name, hostentBuffer, buffer, bufferSize, &result,
+                           &herr);
+#elif OTHER_R
+          result =
+            gethostbyname_r (name, hostentBuffer, buffer, bufferSize, &herr);
+#endif /* GLIBC_R */
+/* allocate more space if the buffer is too small */
+          if (errno == ERANGE || herr == ERANGE)
+            {
+              portLibrary->mem_free_memory (portLibrary, buffer);
+              bufferSize *= 2;
+              allocBuffer = TRUE;
+            }
+          else
+            {
+              break;
+            }
+        }
+#undef buffer
+#undef bufferSize
+#endif
+
+      if (herr != HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN)
+        {
+          break;
+        }
+    }
+
+#if HOSTENT_DATA_R
+  if (herr != 0)
+    {
+      herr = h_errno;
+      HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
+      return portLibrary->error_set_last_error (portLibrary, herr,
+                                                findHostError (herr));
+    }
+#else
+  if (result == NULL)
+    {
+      HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
+      return portLibrary->error_set_last_error (portLibrary, herr,
+                                                findHostError (herr));
+    }
+#endif
+
+  else
+    {
+      memset (handle, 0, sizeof (struct hyhostent_struct));
+#if HOSTENT_DATA_R||NO_R
+      handle->entity = hostentBuffer;
+#else
+      handle->entity = result;
+#endif
+
+    }
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R
+#undef hostentBuffer
+#endif /*HOSTENT_DATA_R || GLIBC_R || OTHER_R */
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_gethostname
+
+/**
+ * Answer the name of the local host machine.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in,out] buffer The string buffer to receive the name
+ * @param[in] length The length of the buffer
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code
+ */
+I_32 VMCALL
+hysock_gethostname (struct HyPortLibrary * portLibrary, char *buffer,
+                    I_32 length)
+{
+  if (gethostname (buffer, length) != 0)
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<gethostname failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getnameinfo
+
+/**
+ * Answers the host name of the "in_addr" in a preallocated buffer.
+ *
+ * The preallocated buffer for "name" should be the size of the maximum host name: OSNIMAXHOST.
+ * Currently only AF_INET and AF_INET6 are supported.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] in_addr The address we want to do a name lookup on
+ * @param[in] sockaddr_size The size of "in_addr"
+ * @param[out] name The hostname of the passed address in a preallocated buffer.
+ * @param[in] name_length The length of the buffer pointed to by name
+ * @param[in] flags Flags on how to form the repsonse (see man pages or doc for getnameinfo)
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code
+ *
+ * @note Added for IPv6 support.
+ * @note "flags" do not affect results on OS's that do not support the IPv6 calls.
+ */
+I_32 VMCALL
+hysock_getnameinfo (struct HyPortLibrary * portLibrary, hysockaddr_t in_addr,
+                    I_32 sockaddr_size, char *name, I_32 name_length,
+                    int flags)
+{
+
+/* If we have the IPv6 functions available we will call them, otherwise we'll call the IPv4 function */
+#if defined(IPv6_FUNCTION_SUPPORT)
+  OSSOCKADDR *addr;
+  int size;
+  int rc = 0;
+  rc =
+    getnameinfo ((OSADDR *) & in_addr->addr, sizeof (in_addr->addr), name,
+                 name_length, NULL, 0, flags);
+  if (rc != 0)
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<gethostbyaddr failed, err=%d>\n", rc);
+      return portLibrary->error_set_last_error (portLibrary, rc,
+                                                findError (rc));
+    }
+  return 0;
+#else /* IPv6_FUNCTION_SUPPORT */
+#if !HOSTENT_DATA_R
+  OSHOSTENT *result;
+#endif
+
+#if GLIBC_R||OTHER_R
+  BOOLEAN allocBuffer = FALSE;
+#endif
+  int herr = 0;
+  int i = 0;
+  int rc = 0;
+  int length;
+  OSSOCKADDR *addr;
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R||NO_R
+  PortlibPTBuffers_t ptBuffers;
+#endif /* HOSTENT_DATA_R || GLIBC_R || OTHER_R || NO_R */
+  addr = (OSSOCKADDR *) & in_addr->addr;
+  if (addr->sin_family == OS_AF_INET4)
+    {
+      length = 4;
+    }
+  else
+    {
+      length = 16;
+    }
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R||NO_R
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+#define hostentBuffer (&ptBuffers->hostent)
+#endif /* HOSTENT_DATA_R || GLIBC_R || OTHER_R || NO_R */
+/* one of several threadsafe gethostbyaddr calls must be made depending on the current platform */
+/* if there is a transient error (HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN), try making the call again */
+  for (i = 0; i < MAX_RETRIES; i++)
+    {
+#if HOSTENT_DATA_R
+#define dataBuffer (ptBuffers->hostent_data)
+      if (!dataBuffer)
+        {
+          dataBuffer =
+            portLibrary->mem_allocate_memory (portLibrary,
+                                              sizeof (OSHOSTENT_DATA));
+          if (!dataBuffer)
+            {
+              return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+            }
+        }
+      herr =
+        gethostbyaddr_r (&addr->sin_addr, length, addr->sin_family,
+                         hostentBuffer, dataBuffer);
+#undef dataBuffer
+#elif ORIGINAL_R || NO_R
+#if NO_R
+      MUTEX_ENTER (hostentLock);
+#endif
+      result = gethostbyaddr (&addr->sin_addr, length, addr->sin_family);
+#if NO_R
+      if (result)
+        {
+          herr = copy_hostent (portLibrary, result, &ptBuffers);
+        }
+      MUTEX_EXIT (hostentLock);
+      if (herr != 0)
+        {
+          return herr;
+        }
+#endif
+      herr = h_errno;
+#elif GLIBC_R || OTHER_R
+#define buffer (ptBuffers->gethostBuffer)
+#define bufferSize (ptBuffers->gethostBufferSize)
+      if (!buffer)
+        {
+          bufferSize = GET_HOST_BUFFER_SIZE;
+        }
+      while (TRUE)
+        {
+          if (allocBuffer == TRUE || !buffer)
+            {
+              /* The buffer is allocated bufferSize + EXTRA_SPACE, while gethostby*_r is only aware of bufferSize
+               * because there seems to be a bug on Linux 386 where gethostbyname_r writes past the end of the
+               * buffer.  This bug has not been observed on other platforms, but EXTRA_SPACE is added anyway as a precaution.*/
+              buffer =
+                portLibrary->mem_allocate_memory (portLibrary,
+                                                  bufferSize + EXTRA_SPACE);
+              if (!buffer)
+                {
+                  return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+                }
+              allocBuffer = FALSE;
+            }
+#if GLIBC_R
+          gethostbyaddr_r ((char *) &addr->sin_addr, length, addr->sin_family,
+                           hostentBuffer, buffer, bufferSize, &result, &herr);
+#elif OTHER_R
+          result =
+            gethostbyaddr_r ((char *) &addr->sin_addr, length,
+                             addr->sin_family, hostentBuffer, buffer,
+                             bufferSize, &herr);
+#endif /* GLIBC_R */
+/* allocate more space if the buffer is too small */
+          if (errno == ERANGE || herr == ERANGE)
+            {
+              portLibrary->mem_free_memory (portLibrary, buffer);
+              bufferSize *= 2;
+              allocBuffer = TRUE;
+            }
+          else
+            {
+              break;
+            }
+        }
+#undef buffer
+#undef bufferSize
+#endif
+      if (herr != HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN)
+        {
+          break;
+        }
+    }
+#if HOSTENT_DATA_R
+  if (herr != 0)
+    {
+      herr = h_errno;
+      HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
+      return portLibrary->error_set_last_error (portLibrary, herr,
+                                                findHostError (herr));
+    }
+#else
+  if (result == NULL)
+    {
+      HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
+      return portLibrary->error_set_last_error (portLibrary, herr,
+                                                findHostError (herr));
+    }
+#endif
+  else
+    {
+      memset (name, 0, sizeof (char) * name_length);
+#if HOSTENT_DATA_R||NO_R
+      strcpy (name, hostentBuffer->h_name);
+#else
+      strcpy (name, result->h_name);
+#endif
+    }
+#if HOSTENT_DATA_R||GLIBC_R||OTHER_R
+#undef hostentBuffer
+#endif /*HOSTENT_DATA_R || GLIBC_R || OTHER_R */
+  return 0;
+#endif /* IPv6_FUNCTION_SUPPORT */
+
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getopt_bool
+
+/**
+ * Answer the value of the nominated boolean socket option.
+ * Refer to the private platformSocketLevel & platformSocketOption functions for details of the options
+ * supported.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] socketP Pointer to the socket to query for the option value.
+ * @param[in] optlevel	 The level within the IP stack at which the option is defined.
+ * @param[in] optname The name of the option to retrieve.
+ * @param[out] optval Pointer to the boolean to update with the option value.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_getopt_bool (struct HyPortLibrary * portLibrary, hysocket_t socketP,
+                    I_32 optlevel, I_32 optname, BOOLEAN * optval)
+{
+  I_32 platformLevel = platformSocketLevel (optlevel);
+  I_32 platformOption = platformSocketOption (optname);
+  socklen_t optlen = sizeof (*optval);
+  U_8 uCharOptval = 0;
+
+  if (0 > platformLevel)
+    {
+      return platformLevel;
+    }
+  if (0 > platformOption)
+    {
+      return platformOption;
+    }
+
+  if (OS_MCAST_LOOP == platformOption)
+    {
+      /* most options are gotten using an 32 bit int which matches the definition of BOOLEAN.  Howerver, for unix
+         platforms this option is gotten with a unsighed char.  Some platforms accept both but some such as AIX
+         and false return an EINVAL if we try to set with an int instead of a unsigned char.  For windows platforms
+         the spec indicates that it is get with a DWORD which seems to match the BOOLEAN.  Therefore since this
+         is a platform specific case for a boolean option we handle it as a special case within this method */
+      optlen = sizeof (uCharOptval);
+      if (0 !=
+          getsockopt (SOCKET_CAST (socketP), platformLevel, platformOption,
+                      (void *) &uCharOptval, &optlen))
+        {
+          I_32 err = errno;
+          HYSOCKDEBUG ("<getsockopt (for bool) failed, err=%d>\n", err);
+          return portLibrary->error_set_last_error (portLibrary, err,
+                                                    findError (err));
+        }
+      *optval = uCharOptval;
+    }
+  else
+    {
+      if (0 !=
+          getsockopt (SOCKET_CAST (socketP), platformLevel, platformOption,
+                      (void *) optval, &optlen))
+        {
+          I_32 err = errno;
+          HYSOCKDEBUG ("<getsockopt (for bool) failed, err=%d>\n", err);
+          return portLibrary->error_set_last_error (portLibrary, err,
+                                                    findError (err));
+        }
+    }
+  /* 0 indicates the option is disabled, while non-zero indicates that the option is enabled.  The caller
+     of this method assumes that the value returned is 1 if the option is enabled.  For many platforms
+     but on some platforms it is not the case for some boolean options (ex AIX for SO_OOBINLINE).
+     Therefore, make sure we return 1 if the value is non zero */
+  if (*optval != 0)
+    {
+      *optval = 1;
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getopt_byte
+
+/**
+ * Answer the value of the nominated byte socket option.
+ * Refer to the private platformSocketLevel & platformSocketOption functions for details of the options
+ * supported.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] socketP Pointer to the socket to query for the option value.
+ * @param[in] optlevel	 The level within the IP stack at which the option is defined.
+ * @param[in] optname The name of the option to retrieve.
+ * @param[out] optval Pointer to the byte to update with the option value.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_getopt_byte (struct HyPortLibrary * portLibrary, hysocket_t socketP,
+                    I_32 optlevel, I_32 optname, U_8 * optval)
+{
+  I_32 platformLevel = platformSocketLevel (optlevel);
+  I_32 platformOption = platformSocketOption (optname);
+  socklen_t optlen = sizeof (*optval);
+
+  if (0 > platformLevel)
+    {
+      return platformLevel;
+    }
+  if (0 > platformOption)
+    {
+      return platformOption;
+    }
+
+  if (0 !=
+      getsockopt (SOCKET_CAST (socketP), platformLevel, platformOption,
+                  (void *) optval, &optlen))
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<getsockopt (for byte) failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getopt_int
+
+/**
+ * Answer the value of the nominated integer socket option.
+ * Refer to the private platformSocketLevel & platformSocketOption functions for details of the options
+ * supported.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] socketP Pointer to the socket to query for the option value.
+ * @param[in] optlevel The level within the IP stack at which the option is defined.
+ * @param[in] optname The name of the option to retrieve.
+ * @param[out] optval Pointer to the integer to update with the option value.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_getopt_int (struct HyPortLibrary * portLibrary, hysocket_t socketP,
+                   I_32 optlevel, I_32 optname, I_32 * optval)
+{
+  I_32 platformLevel = platformSocketLevel (optlevel);
+  I_32 platformOption = platformSocketOption (optname);
+  socklen_t optlen = sizeof (*optval);
+
+  if (0 > platformLevel)
+    {
+      return platformLevel;
+    }
+  if (0 > platformOption)
+    {
+      return platformOption;
+    }
+
+  if (0 !=
+      getsockopt (SOCKET_CAST (socketP), platformLevel, platformOption,
+                  (void *) optval, &optlen))
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<getsockopt (for int) failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getopt_linger
+
+/**
+ * Answer the value of the socket linger option.
+ * See the @ref hysock_linger_init for details of the linger behavior.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] socketP Pointer to the socket to query for the option value
+ * @param[in] optlevel The level within the IP stack at which the option is defined
+ * @param[in] optname The name of the option to retrieve
+ * @param[out] optval Pointer to the linger struct to update with the option value
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code
+ */
+I_32 VMCALL
+hysock_getopt_linger (struct HyPortLibrary * portLibrary, hysocket_t socketP,
+                      I_32 optlevel, I_32 optname, hylinger_t optval)
+{
+  I_32 platformLevel = platformSocketLevel (optlevel);
+  I_32 platformOption = platformSocketOption (optname);
+  socklen_t optlen = sizeof (optval->linger);
+
+  if (0 > platformLevel)
+    {
+      return platformLevel;
+    }
+  if (0 > platformOption)
+    {
+      return platformOption;
+    }
+
+  if (0 !=
+      getsockopt (SOCKET_CAST (socketP), platformLevel, platformOption,
+                  (char *) (&optval->linger), &optlen))
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<getsockopt (for linger) failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getopt_sockaddr
+
+/**
+ * Answer the value of the socket option, an address struct.
+ * Currently only used to retrieve the interface of multicast sockets, 
+ * but the more general call style has been used.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] socketP Pointer to the socket to query for the option value.
+ * @param[in] optlevel	 The level within the IP stack at which the option is defined.
+ * @param[in] optname The name of the option to retrieve.
+ * @param[out] optval Pointer to the sockaddr struct to update with the option value.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_getopt_sockaddr (struct HyPortLibrary * portLibrary,
+                        hysocket_t socketP, I_32 optlevel, I_32 optname,
+                        hysockaddr_t optval)
+{
+  I_32 platformLevel = platformSocketLevel (optlevel);
+  I_32 platformOption = platformSocketOption (optname);
+  U_32 val[3];
+  socklen_t optlen = sizeof (val);
+  OSSOCKADDR *sockaddr;
+
+  if (0 > platformLevel)
+    {
+      return platformLevel;
+    }
+  if (0 > platformOption)
+    {
+      return platformOption;
+    }
+
+  if (0 !=
+      getsockopt (SOCKET_CAST (socketP), platformLevel, platformOption,
+                  (char *) val, &optlen))
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<getsockopt (for sockaddr) failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  sockaddr = (OSSOCKADDR *) & optval->addr;
+  if (optlen == 4)
+    {
+      sockaddr->sin_addr.s_addr = val[0];       /* false */
+    }
+  else
+    {                           /*Linux */
+      sockaddr->sin_addr.s_addr = val[1];
+      sockaddr->sin_port = val[2];
+    }
+
+  /* A temporary fix as Linux false (maybe others) returns 0 for the family.  Maybe there is a way to get it to return the
+     right family.  However we now depend on the family to be set correctly to determine whether or not we have an 
+     IPv6 address or not.  For now, we'll assume that this function will only be called for IPv4 multicast sockets */
+  sockaddr->sin_family = OS_AF_INET4;
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getpeername
+
+/**
+ * Answer the remote name for the socket.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the socket to get the address of.
+ * @param[out] addrHandle Pointer to the sockaddr struct to update with the address.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_getpeername (struct HyPortLibrary * portLibrary, hysocket_t handle,
+                    hysockaddr_t addrHandle)
+{
+  socklen_t addrlen = sizeof (addrHandle->addr);
+
+  if (getpeername
+      (SOCKET_CAST (handle), (struct sockaddr *) &addrHandle->addr,
+       &addrlen) != 0)
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<getpeername failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_getsockname
+
+/**
+ * Answer the local name for the socket.  Note, the stack getsockname function
+ * actually answers a sockaddr structure, not a string name as the function name
+ * might imply.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the socket to get the address of.
+ * @param[out] addrHandle Pointer to the sockaddr struct to update with the address.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_getsockname (struct HyPortLibrary * portLibrary, hysocket_t handle,
+                    hysockaddr_t addrHandle)
+{
+  socklen_t addrlen = sizeof (addrHandle->addr);
+
+  if (getsockname
+      (SOCKET_CAST (handle), (struct sockaddr *) &addrHandle->addr,
+       &addrlen) != 0)
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<getsockname failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_hostent_addrlist
+
+/**
+ * Answer the nominated element of the address list within the argument hostent struct.
+ * The address is in network order.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the hostent struct, in which to access the addr_list.
+ * @param[in] index The index of the element within the addr_list to retrieve.
+ *
+ * @return	the address, in network order.
+ */
+I_32 VMCALL
+hysock_hostent_addrlist (struct HyPortLibrary * portLibrary,
+                         hyhostent_t handle, U_32 index)
+{
+  return *((I_32 *) handle->entity->h_addr_list[index]);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_hostent_aliaslist
+
+/**
+ * Answer a reference to the list of alternative names for the host within the argument hostent struct.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the hostent struct, in which to access the addr_list
+ * @param[out] aliasList Pointer to the list of alternative names, to be updated 
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code
+ */
+I_32 VMCALL
+hysock_hostent_aliaslist (struct HyPortLibrary * portLibrary,
+                          hyhostent_t handle, char ***aliasList)
+{
+  *aliasList = handle->entity->h_addr_list;
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_hostent_hostname
+
+/**
+ * Answer the host name (string) within the argument hostent struct.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the hostent struct, in which to access the hostName.
+ * @param[out] hostName Host name string.
+ *
+ * @return	0, the function does not validate the name access.
+ */
+I_32 VMCALL
+hysock_hostent_hostname (struct HyPortLibrary * portLibrary,
+                         hyhostent_t handle, char **hostName)
+{
+  *hostName = handle->entity->h_name;
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_htonl
+
+/**
+ * Answer the 32 bit host ordered argument, in network byte order.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] val The 32 bit host ordered number.
+ *
+ * @return	the 32 bit network ordered number.
+ */
+I_32 VMCALL
+hysock_htonl (struct HyPortLibrary * portLibrary, I_32 val)
+{
+  return htonl (val);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_htons
+
+/**
+ * Answer the 16 bit host ordered argument, in network byte order.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] val The 16 bit host ordered number.
+ *
+ * @return	the 16 bit network ordered number.
+ */
+U_16 VMCALL
+hysock_htons (struct HyPortLibrary * portLibrary, U_16 val)
+{
+  return htons (val);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_inetaddr
+
+/**
+ * Answer the dotted IP string as an Internet address.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[out] addrStr The dotted IP string.
+ * @param[in] addr Pointer to the Internet address.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_inetaddr (struct HyPortLibrary * portLibrary, char *addrStr,
+                 U_32 * addr)
+{
+  I_32 rc = 0;
+  U_32 val;
+
+  val = inet_addr (addrStr);
+  if (val == -1)
+    {
+      HYSOCKDEBUGPRINT ("<inet_addr failed>\n");
+      rc = HYPORT_ERROR_SOCKET_ADDRNOTAVAIL;
+    }
+  else
+    {
+      *addr = val;
+    }
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_inetntoa
+
+/**
+ * Answer the Internet address as a dotted IP string.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[out] addrStr The dotted IP string.
+ * @param[in] nipAddr The Internet address.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_inetntoa (struct HyPortLibrary * portLibrary, char **addrStr,
+                 U_32 nipAddr)
+{
+  U_8 *addr = (U_8 *) & nipAddr;
+  PortlibPTBuffers_t ptBuffers;
+
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+  portLibrary->str_printf (portLibrary, ptBuffers->ntoa, NTOA_SIZE,
+                           "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+  *addrStr = ptBuffers->ntoa;
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_ipmreq_init
+
+/**
+ * Initializes a new multicast membership structure.  The membership structure is used to join & leave
+ * multicast groups @see hysock_setopt_ipmreq.  The group may be joined using 0 (HYSOCK_INADDR_ANY)
+ * as the local interface, in which case the default local address will be used.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[out] handle Pointer to the multicast membership struct.
+ * @param[in] nipmcast The address, in network order, of the multicast group to join.
+ * @param[in] nipinterface The address, in network order, of the local machine interface to join on.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_ipmreq_init (struct HyPortLibrary * portLibrary, hyipmreq_t handle,
+                    U_32 nipmcast, U_32 nipinterface)
+{
+  memset (handle, 0, sizeof (struct hyipmreq_struct));
+
+  handle->addrpair.imr_multiaddr.s_addr = nipmcast;
+  handle->addrpair.imr_interface.s_addr = nipinterface;
+  return 0;
+
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_ipv6_mreq_init
+
+/**
+ * Fills in a preallocated hyipv6_mreq_struct
+ *
+ * @param[in] portLibrary The port library.
+ * @param[out] handle A pointer to the hyipv6_mreq_struct to populate.
+ * @param[in] ipmcast_addr The ip mulitcast address.
+ * @param[in] ipv6mr_interface The ip mulitcast inteface.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ *
+ * @note Added for IPv6 support.
+ */
+I_32 VMCALL
+hysock_ipv6_mreq_init (struct HyPortLibrary * portLibrary,
+                       hyipv6_mreq_t handle, U_8 * ipmcast_addr,
+                       U_32 ipv6mr_interface)
+{
+#if defined(IPv6_FUNCTION_SUPPORT)
+  memset (handle, 0, sizeof (struct hyipmreq_struct));
+  memcpy (handle->mreq.ipv6mr_multiaddr.s6_addr, ipmcast_addr, 16);
+  handle->mreq.ipv6mr_interface = ipv6mr_interface;
+#endif
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_linger_enabled
+
+/**
+ * Answer true if the linger is enabled in the argument linger struct.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the linger struct to be accessed.
+ * @param[out] enabled Pointer to the boolean to be updated with the linger status.
+ *
+ * @return	0, the function does not validate the access.
+ */
+I_32 VMCALL
+hysock_linger_enabled (struct HyPortLibrary * portLibrary, hylinger_t handle,
+                       BOOLEAN * enabled)
+{
+  *enabled = (BOOLEAN) (handle->linger.l_onoff);
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_linger_init
+
+/**
+ * Initializes a new linger structure, enabled or disabled, with the timeout as specified.
+ * Linger defines the behavior when unsent messages exist for a socket that has been sent close.
+ * If linger is disabled, the default, close returns immediately and the stack attempts to deliver unsent messages.
+ * If linger is enabled:
+ * \arg if the timeout is 0, the close will block indefinitely until the messages are sent
+ * \arg if the timeout is set, the close will return after the messages are sent or the timeout period expired
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the linger struct to be accessed.
+ * @param[in] enabled Aero to disable, a non-zero value to enable linger.
+ * @param[in] timeout	 0 to linger indefinitely or a positive timeout value (in seconds).
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_linger_init (struct HyPortLibrary * portLibrary, hylinger_t handle,
+                    I_32 enabled, U_16 timeout)
+{
+  memset (handle, 0, sizeof (struct hylinger_struct));
+  handle->linger.l_onoff = enabled;
+  handle->linger.l_linger = (I_32) timeout;
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_linger_linger
+
+/**
+ * Answer the linger timeout value in the argument linger struct.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Pointer to the linger struct to be accessed.
+ * @param[out] linger Pointer to the integer, to be updated with the linger value (in seconds).
+ *
+ * @return	0, the function does not validate the access.
+ */
+I_32 VMCALL
+hysock_linger_linger (struct HyPortLibrary * portLibrary, hylinger_t handle,
+                      U_16 * linger)
+{
+  *linger = (U_16) (handle->linger.l_linger);
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_listen
+
+/**
+ * Set the socket to listen for incoming connection requests.  This call is made prior to accepting requests,
+ * via the @ref hysock_accept function.  The backlog specifies the maximum length of the queue of pending connections,
+ * after which further requests are rejected.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock Pointer to the socket to modify.
+ * @param[in] backlog The maximum number of queued requests.
+ *
+ * @return	0, if no errors occurred, otherwise the (negative) error code.
+ */
+I_32 VMCALL
+hysock_listen (struct HyPortLibrary * portLibrary, hysocket_t sock,
+               I_32 backlog)
+{
+  I_32 rc = 0;
+
+  if (listen (SOCKET_CAST (sock), backlog) < 0)
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<listen failed, err=%d>\n", rc);
+      rc =
+        portLibrary->error_set_last_error (portLibrary, rc,
+                                           HYPORT_ERROR_SOCKET_OPFAILED);
+    }
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_ntohl
+
+/**
+ * Answer the 32 bit network ordered argument, in host byte order.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] val The 32 bit network ordered number.
+ *
+ * @return	the 32 bit host ordered number.
+ */
+I_32 VMCALL
+hysock_ntohl (struct HyPortLibrary * portLibrary, I_32 val)
+{
+  return ntohl (val);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_ntohs
+
+/**
+ * Answer the 16-bit network ordered argument, in host byte order.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] val The 16-bit network ordered number.
+ *
+ * @return	the 16-bit host ordered number.
+ */
+U_16 VMCALL
+hysock_ntohs (struct HyPortLibrary * portLibrary, U_16 val)
+{
+  return ntohs (val);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_read
+
+/**
+ * The read function receives data from a connected socket.  Calling read will return as much 
+ *	information as is currently available up to the size of the buffer supplied. If no incoming 
+ * data is available at the socket, the read call blocks and waits for data to arrive.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock Pointer to the socket to read on
+ * @param[out] buf Pointer to the buffer where input bytes are written
+ * @param[in] nbyte The length of buf
+ * @param[in] flags The flags, to influence this read (in addition to the socket options)
+ *
+ * @return
+ * \arg If no error occurs, return the number of bytes received.
+ * \arg If the connection has been gracefully closed, return 0.
+ * \arg Otherwise return the (negative) error code.
+ */
+I_32 VMCALL
+hysock_read (struct HyPortLibrary * portLibrary, hysocket_t sock, U_8 * buf,
+             I_32 nbyte, I_32 flags)
+{
+  I_32 bytesRec = 0;
+
+  bytesRec = recv (SOCKET_CAST (sock), buf, nbyte, flags);
+  if (-1 == bytesRec)
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<recv failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  else
+    {
+      return bytesRec;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_readfrom
+
+/**
+ * The read function receives data from a possibly connected socket.  Calling read will return as much 
+ * information as is currently available up to the size of the buffer supplied.  If the information is too large
+ * for the buffer, the excess will be discarded.  If no incoming  data is available at the socket, the read call 
+ * blocks and waits for data to arrive.  It the address argument is not null, the address will be updated with
+ * address of the message sender.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock Pointer to the socket to read on.
+ * @param[out] buf Pointer to the buffer where input bytes are written.
+ * @param[in] nbyte The length of buf.
+ * @param[in] flags Tthe flags, to influence this read.
+ * @param[out] addrHandle	if provided, the address to be updated with the sender information.
+ *
+ * @return
+ * \arg If no error occurs, return the number of bytes received.
+ * \arg If the connection has been gracefully closed, return 0.
+ * \arg Otherwise return the (negative) error code.
+ */
+I_32 VMCALL
+hysock_readfrom (struct HyPortLibrary * portLibrary, hysocket_t sock,
+                 U_8 * buf, I_32 nbyte, I_32 flags, hysockaddr_t addrHandle)
+{
+  I_32 bytesRec = 0;
+  socklen_t addrlen;
+
+  if (NULL == addrHandle)
+    {
+      addrlen = sizeof (*addrHandle);
+      bytesRec =
+        recvfrom (SOCKET_CAST (sock), buf, nbyte, flags, NULL, &addrlen);
+    }
+  else
+    {
+      addrlen = sizeof (addrHandle->addr);
+      bytesRec =
+        recvfrom (SOCKET_CAST (sock), buf, nbyte, flags,
+                  (struct sockaddr *) &addrHandle->addr, &addrlen);
+    }
+  if (bytesRec == -1)
+    {
+      I_32 err = errno;
+      HYSOCKDEBUG ("<recvfrom failed, err=%d>\n", err);
+      return portLibrary->error_set_last_error (portLibrary, err,
+                                                findError (err));
+    }
+  else
+    {
+      return bytesRec;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_select
+
+/**
+ * The select function allows the state of sockets for read & write operations and exceptional conditions to be tested.
+ * The function is used prior to a hysock_read/readfrom, to control the period the operation may block for.
+ * Depending upon the timeout specified:
+ * \arg 0, return immediately with the status of the descriptors
+ * \arg timeout, return when one of the descriptors is ready or after the timeout period has expired
+ * \arg null, block indefinitely for a ready descriptor
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] nfds Maximum number of file descriptors to be tested.
+ * @param[in] readfds Tthe set of descriptors to be checked if ready for read operations.
+ * @param[in] writefds The set of descriptors to be checked if ready for write operations.
+ * @param[in] exceptfds The set of descriptors to be checked for exceptional conditions.
+ * @param[in] timeout Pointer to the timeout (a hytimeval struct).
+ *
+ * @return	0 if no error occurs, otherwise return the (negative) error code.
+ */
+I_32 VMCALL
+hysock_select (struct HyPortLibrary * portLibrary, I_32 nfds,
+               hyfdset_t readfds, hyfdset_t writefds, hyfdset_t exceptfds,
+               hytimeval_t timeout)
+{
+  I_32 rc = 0;
+  I_32 result = 0;
+
+  result =
+    select (nfds, readfds == NULL ? NULL : &readfds->handle,
+            writefds == NULL ? NULL : &writefds->handle,
+            exceptfds == NULL ? NULL : &exceptfds->handle,
+            timeout == NULL ? NULL : &timeout->time);
+  if (result == -1)
+    {
+      rc = errno;
+      HYSOCKDEBUG ("<select failed, err=%d>\n", rc);
+      rc =
+        portLibrary->error_set_last_error (portLibrary, rc,
+                                           HYPORT_ERROR_SOCKET_OPFAILED);
+    }
+  else
+    {
+      if (result)
+        {
+          rc = result;
+        }
+      else
+        {
+          rc = HYPORT_ERROR_SOCKET_TIMEOUT;
+        }
+    }
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_select_read
+
+/**
+ * A helper method, to ensure a read operation can be performed without blocking.
+ * The portable version of a read operation is a blocking call (will wait indefinitely for data).
+ * This function should be called prior to a read operation, to provide a read timeout.
+ * If the result is 1, the caller is guaranteed to be able to complete a read on the socket without blocking.
+ * The actual contents of the fdset are not available for inspection (as provided in the more general 'select' function).
+ * The timeout is specified in seconds and microseconds.
+ * If the timeout is 0, skip this function (and thus the caller of a subsequent read operation may block).
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] hysocketP Pointer to the hysocket to query for available read data.
+ * @param[in] secTime The integer component of the timeout periond, in seconds.
+ * @param[in] uSecTime The fractional component of the timeout period, in microSeconds.
+ * @param[in] accept Set to true when called for an accept(), false when called for a read()
+ *
+ * @return
+ * \arg 1, if there is data available to read at the socket
+ * \arg HYPORT_ERROR_SOCKET_TIMEOUT if the call timed out
+ * \arg otherwise return the (negative) error code.
+ */
+I_32 VMCALL
+hysock_select_read (struct HyPortLibrary * portLibrary, hysocket_t hysocketP,
+                    I_32 secTime, I_32 uSecTime, BOOLEAN accept)
+{
+  hytimeval_struct timeP;
+  I_32 result = 0;
+  I_32 size = 0, flags = 0;
+  PortlibPTBuffers_t ptBuffers;
+
+  ptBuffers = hyport_tls_get (portLibrary);
+  if (NULL == ptBuffers)
+    {
+      return HYPORT_ERROR_SOCKET_SYSTEMFULL;
+    }
+
+/* The max fdset size per process is always expected to be less than a 32bit integer value.
+ * Is this valid on a 64bit platform?
+ */
+
+  /* Removed check for zero timeout */
+
+  result = hysock_fdset_init (portLibrary, hysocketP);
+  if (0 != result)
+    {
+      return result;
+    }
+
+  hysock_timeval_init (portLibrary, secTime, uSecTime, &timeP);
+  size = hysock_fdset_size (portLibrary, hysocketP);
+  if (0 > size)
+    {
+      result = HYPORT_ERROR_SOCKET_FDSET_SIZEBAD;
+    }
+  else
+    {
+      result =
+        hysock_select (portLibrary, size, ptBuffers->fdset, NULL, NULL,
+                       &timeP);
+    }
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysock_set_nonblocking
+
+/**
+ * Set the nonblocking state of the socket.
+ *
+ * @param[in] portLibrary The port library.

[... 2538 lines stripped ...]