OS_NS_sys_socket.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // OS_NS_sys_socket.inl,v 1.38 2006/05/30 13:15:25 schmidt Exp
00004 
00005 #include "ace/OS_NS_errno.h"
00006 #include "ace/OS_NS_macros.h"
00007 #include "ace/OS_NS_sys_uio.h"
00008 #include "ace/OS_NS_stdio.h"
00009 #include "ace/OS_QoS.h"
00010 #include "ace/Global_Macros.h"
00011 #include "ace/os_include/netinet/os_in.h"
00012 
00013 #if defined (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO) \
00014          && (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO == 1)
00015 #include "ace/OS_NS_string.h"
00016 #endif
00017 
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 #if defined (ACE_HAS_VOIDPTR_SOCKOPT)
00021 typedef void *ACE_SOCKOPT_TYPE1;
00022 #elif defined (ACE_HAS_CHARPTR_SOCKOPT)
00023 typedef char *ACE_SOCKOPT_TYPE1;
00024 #else
00025 typedef const char *ACE_SOCKOPT_TYPE1;
00026 #endif /* ACE_HAS_VOIDPTR_SOCKOPT */
00027 
00028 ACE_INLINE ACE_HANDLE
00029 ACE_OS::accept (ACE_HANDLE handle,
00030                 struct sockaddr *addr,
00031                 int *addrlen)
00032 {
00033   ACE_OS_TRACE ("ACE_OS::accept");
00034   // On a non-blocking socket with no connections to accept, this
00035   // system call will return EWOULDBLOCK or EAGAIN, depending on the
00036   // platform.  UNIX 98 allows either errno, and they may be the same
00037   // numeric value.  So to make life easier for upper ACE layers as
00038   // well as application programmers, always change EAGAIN to
00039   // EWOULDBLOCK.  Rather than hack the ACE_OSCALL_RETURN macro, it's
00040   // handled explicitly here.  If the ACE_OSCALL macro ever changes,
00041   // this function needs to be reviewed.  On Win32, the regular macros
00042   // can be used, as this is not an issue.
00043 
00044 #if defined (ACE_WIN32)
00045   ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
00046                                  addr,
00047                                  (ACE_SOCKET_LEN *) addrlen),
00048                        ACE_HANDLE,
00049                        ACE_INVALID_HANDLE);
00050 #else
00051 #  if defined (ACE_HAS_BROKEN_ACCEPT_ADDR)
00052   // Apparently some platforms like VxWorks can't correctly deal with
00053   // a NULL addr.
00054 
00055    sockaddr_in fake_addr;
00056    int fake_addrlen;
00057 
00058    if (addrlen == 0)
00059      addrlen = &fake_addrlen;
00060 
00061    if (addr == 0)
00062      {
00063        addr = (sockaddr *) &fake_addr;
00064        *addrlen = sizeof fake_addr;
00065      }
00066 #  endif /* ACE_HAS_BROKEN_ACCEPT_ADDR */
00067   ACE_HANDLE ace_result = ::accept ((ACE_SOCKET) handle,
00068                                     addr,
00069                                     (ACE_SOCKET_LEN *) addrlen);
00070 
00071 # if !(defined (EAGAIN) && defined (EWOULDBLOCK) && EAGAIN == EWOULDBLOCK)
00072   // Optimize this code out if we can detect that EAGAIN ==
00073   // EWOULDBLOCK at compile time.  If we cannot detect equality at
00074   // compile-time (e.g. if EAGAIN or EWOULDBLOCK are not preprocessor
00075   // macros) perform the check at run-time.  The goal is to avoid two
00076   // TSS accesses in the _REENTRANT case when EAGAIN == EWOULDBLOCK.
00077   if (ace_result == ACE_INVALID_HANDLE
00078 #  if !defined (EAGAIN) || !defined (EWOULDBLOCK)
00079       && EAGAIN != EWOULDBLOCK
00080 #  endif  /* !EAGAIN || !EWOULDBLOCK */
00081       && errno == EAGAIN)
00082     {
00083       errno = EWOULDBLOCK;
00084     }
00085 # endif /* EAGAIN != EWOULDBLOCK*/
00086 
00087   return ace_result;
00088 
00089 #endif /* defined (ACE_WIN32) */
00090 }
00091 
00092 ACE_INLINE int
00093 ACE_OS::bind (ACE_HANDLE handle, struct sockaddr *addr, int addrlen)
00094 {
00095   ACE_OS_TRACE ("ACE_OS::bind");
00096   ACE_SOCKCALL_RETURN (::bind ((ACE_SOCKET) handle,
00097                                addr,
00098                                (ACE_SOCKET_LEN) addrlen), int, -1);
00099 }
00100 
00101 ACE_INLINE int
00102 ACE_OS::closesocket (ACE_HANDLE handle)
00103 {
00104   ACE_OS_TRACE ("ACE_OS::closesocket");
00105 #if defined (ACE_WIN32)
00106   ACE_OS::shutdown (handle, ACE_SHUTDOWN_WRITE);
00107   ACE_SOCKCALL_RETURN (::closesocket ((SOCKET) handle), int, -1);
00108 #else
00109   ACE_OSCALL_RETURN (::close (handle), int, -1);
00110 #endif /* ACE_WIN32 */
00111 }
00112 
00113 ACE_INLINE int
00114 ACE_OS::connect (ACE_HANDLE handle,
00115                  struct sockaddr *addr,
00116                  int addrlen)
00117 {
00118   ACE_OS_TRACE ("ACE_OS::connect");
00119   ACE_SOCKCALL_RETURN (::connect ((ACE_SOCKET) handle,
00120                                   addr,
00121                                   (ACE_SOCKET_LEN) addrlen), int, -1);
00122 }
00123 
00124 ACE_INLINE int
00125 ACE_OS::enum_protocols (int *protocols,
00126                         ACE_Protocol_Info *protocol_buffer,
00127                         u_long *buffer_length)
00128 {
00129 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00130 
00131   ACE_SOCKCALL_RETURN (::WSAEnumProtocols (protocols,
00132                                            protocol_buffer,
00133                                            buffer_length),
00134                        int,
00135                        SOCKET_ERROR);
00136 
00137 #else
00138   ACE_UNUSED_ARG (protocols);
00139   ACE_UNUSED_ARG (protocol_buffer);
00140   ACE_UNUSED_ARG (buffer_length);
00141   ACE_NOTSUP_RETURN (-1);
00142 #endif /* ACE_HAS_WINSOCK2 */
00143 }
00144 
00145 ACE_INLINE int
00146 ACE_OS::getpeername (ACE_HANDLE handle, struct sockaddr *addr,
00147                      int *addrlen)
00148 {
00149   ACE_OS_TRACE ("ACE_OS::getpeername");
00150 
00151 #if defined (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO) \
00152          && (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO == 1)
00153   int result;
00154   ACE_SOCKCALL (::getpeername ((ACE_SOCKET) handle,
00155                                addr,
00156                                (ACE_SOCKET_LEN *) addrlen),
00157                int,
00158                 -1,
00159                 result);
00160 
00161   // Some platforms, like older versions of the Linux kernel, do not
00162   // initialize the sin_zero field since that field is generally only
00163   // used for padding/alignment purposes.  On those platforms
00164   // memcmp()-based comparisons of the sockaddr_in structure, such as
00165   // the one in the ACE_INET_Addr equality operator, may fail due to
00166   // random bytes in the sin_zero field even though that field is
00167   // unused.  Prevent equality comparison of two different sockaddr_in
00168   // instances that refer to the same socket from failing by
00169   // explicitly initializing the sockaddr_in::sin_zero field to a
00170   // consistent value, e.g. zero.
00171   if (result != -1 && addr->sa_family == AF_INET)
00172     {
00173       ACE_OS::memset (reinterpret_cast<struct sockaddr_in *> (addr)->sin_zero,
00174                       0,
00175                       sizeof (reinterpret_cast<struct sockaddr_in *> (addr)->sin_zero));
00176     }
00177 
00178   return result;
00179 #else
00180   ACE_SOCKCALL_RETURN (::getpeername ((ACE_SOCKET) handle,
00181                                       addr,
00182                                       (ACE_SOCKET_LEN *) addrlen),
00183                        int,
00184                        -1);
00185 #endif /* ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO */
00186 }
00187 
00188 ACE_INLINE int
00189 ACE_OS::getsockname (ACE_HANDLE handle,
00190                      struct sockaddr *addr,
00191                      int *addrlen)
00192 {
00193   ACE_OS_TRACE ("ACE_OS::getsockname");
00194 #if defined (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO) \
00195          && (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO == 1)
00196   int result;
00197   ACE_SOCKCALL (::getsockname ((ACE_SOCKET) handle,
00198                                addr,
00199                                (ACE_SOCKET_LEN *) addrlen),
00200                int, -1, result);
00201 
00202   // Some platforms, like older versions of the Linux kernel, do not
00203   // initialize the sin_zero field since that field is generally only
00204   // used for padding/alignment purposes.  On those platforms
00205   // memcmp()-based comparisons of the sockaddr_in structure, such as
00206   // the one in the ACE_INET_Addr equality operator, may fail due to
00207   // random bytes in the sin_zero field even though that field is
00208   // unused.  Prevent equality comparison of two different sockaddr_in
00209   // instances that refer to the same socket from failing by
00210   // explicitly initializing the sockaddr_in::sin_zero field to a
00211   // consistent value, e.g. zero.
00212   if (result != -1 && addr->sa_family == AF_INET)
00213     {
00214       ACE_OS::memset (reinterpret_cast<struct sockaddr_in *> (addr)->sin_zero,
00215                       0,
00216                       sizeof (reinterpret_cast<struct sockaddr_in *> (addr)->sin_zero));
00217     }
00218 
00219   return result;
00220 #else
00221   ACE_SOCKCALL_RETURN (::getsockname ((ACE_SOCKET) handle,
00222                                       addr,
00223                                       (ACE_SOCKET_LEN *) addrlen),
00224                        int, -1);
00225 #endif /* ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO */
00226 }
00227 
00228 ACE_INLINE int
00229 ACE_OS::getsockopt (ACE_HANDLE handle,
00230                     int level,
00231                     int optname,
00232                     char *optval,
00233                     int *optlen)
00234 {
00235   ACE_OS_TRACE ("ACE_OS::getsockopt");
00236   ACE_SOCKCALL_RETURN (::getsockopt ((ACE_SOCKET) handle,
00237                                      level,
00238                                      optname,
00239                                      optval,
00240                                      (ACE_SOCKET_LEN *) optlen),
00241                        int,
00242                        -1);
00243 }
00244 
00245 ACE_INLINE int
00246 ACE_OS::listen (ACE_HANDLE handle, int backlog)
00247 {
00248   ACE_OS_TRACE ("ACE_OS::listen");
00249   ACE_SOCKCALL_RETURN (::listen ((ACE_SOCKET) handle, backlog), int, -1);
00250 }
00251 
00252 ACE_INLINE ssize_t
00253 ACE_OS::recv (ACE_HANDLE handle, char *buf, size_t len, int flags)
00254 {
00255   ACE_OS_TRACE ("ACE_OS::recv");
00256 
00257   // On UNIX, a non-blocking socket with no data to receive, this
00258   // system call will return EWOULDBLOCK or EAGAIN, depending on the
00259   // platform.  UNIX 98 allows either errno, and they may be the same
00260   // numeric value.  So to make life easier for upper ACE layers as
00261   // well as application programmers, always change EAGAIN to
00262   // EWOULDBLOCK.  Rather than hack the ACE_OSCALL_RETURN macro, it's
00263   // handled explicitly here.  If the ACE_OSCALL macro ever changes,
00264   // this function needs to be reviewed.  On Win32, the regular macros
00265   // can be used, as this is not an issue.
00266 #if defined (ACE_WIN32)
00267   ACE_SOCKCALL_RETURN (::recv ((ACE_SOCKET) handle, buf,
00268                                static_cast<int> (len), flags), ssize_t, -1);
00269 #else
00270   ssize_t ace_result_;
00271   ace_result_ = ::recv ((ACE_SOCKET) handle, buf, len, flags);
00272 
00273 # if !(defined (EAGAIN) && defined (EWOULDBLOCK) && EAGAIN == EWOULDBLOCK)
00274   // Optimize this code out if we can detect that EAGAIN ==
00275   // EWOULDBLOCK at compile time.  If we cannot detect equality at
00276   // compile-time (e.g. if EAGAIN or EWOULDBLOCK are not preprocessor
00277   // macros) perform the check at run-time.  The goal is to avoid two
00278   // TSS accesses in the _REENTRANT case when EAGAIN == EWOULDBLOCK.
00279   if (ace_result_ == -1
00280 #  if !defined (EAGAIN) || !defined (EWOULDBLOCK)
00281       && EAGAIN != EWOULDBLOCK
00282 #  endif  /* !EAGAIN || !EWOULDBLOCK */
00283       && errno == EAGAIN)
00284     {
00285       errno = EWOULDBLOCK;
00286     }
00287 # endif /* EAGAIN != EWOULDBLOCK*/
00288 
00289   return ace_result_;
00290 #endif /* defined (ACE_WIN32) */
00291 }
00292 
00293 ACE_INLINE ssize_t
00294 ACE_OS::recvfrom (ACE_HANDLE handle,
00295                   char *buf,
00296                   size_t len,
00297                   int flags,
00298                   struct sockaddr *addr,
00299                   int *addrlen)
00300 {
00301   ACE_OS_TRACE ("ACE_OS::recvfrom");
00302 #if defined (ACE_WIN32)
00303   int shortened_len = static_cast<int> (len);
00304   int result = ::recvfrom ((ACE_SOCKET) handle,
00305                            buf,
00306                            shortened_len,
00307                            flags,
00308                            addr,
00309                            (ACE_SOCKET_LEN *) addrlen);
00310   if (result == SOCKET_ERROR)
00311     {
00312       ACE_OS::set_errno_to_wsa_last_error ();
00313       if (errno == WSAEMSGSIZE &&
00314           ACE_BIT_ENABLED (flags, MSG_PEEK))
00315         return shortened_len;
00316       else
00317         return -1;
00318     }
00319   else
00320     return result;
00321 #else /* non Win32 */
00322   ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle,
00323                                    buf,
00324                                    len,
00325                                    flags,
00326                                    addr,
00327                                    (ACE_SOCKET_LEN *) addrlen),
00328                        ssize_t, -1);
00329 #endif /* defined (ACE_WIN32) */
00330 }
00331 
00332 ACE_INLINE ssize_t
00333 ACE_OS::recvfrom (ACE_HANDLE handle,
00334                   iovec *buffers,
00335                   int buffer_count,
00336                   size_t &number_of_bytes_recvd,
00337                   int &flags,
00338                   struct sockaddr *addr,
00339                   int *addrlen,
00340                   ACE_OVERLAPPED *overlapped,
00341                   ACE_OVERLAPPED_COMPLETION_FUNC func)
00342 {
00343   ACE_OS_TRACE ("ACE_OS::recvfrom");
00344 
00345 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00346   DWORD bytes_recvd;
00347   DWORD the_flags = flags;
00348   int result = ::WSARecvFrom ((SOCKET) handle,
00349                               (WSABUF*)buffers,
00350                               buffer_count,
00351                               &bytes_recvd,
00352                               &the_flags,
00353                               addr,
00354                               addrlen,
00355                               overlapped,
00356                               func);
00357   if (result != 0) {
00358     ACE_OS::set_errno_to_wsa_last_error ();
00359   }
00360   flags = the_flags;
00361   number_of_bytes_recvd = static_cast<size_t> (bytes_recvd);
00362   return result;
00363 #else
00364   ACE_UNUSED_ARG (handle);
00365   ACE_UNUSED_ARG (buffers);
00366   ACE_UNUSED_ARG (buffer_count);
00367   ACE_UNUSED_ARG (number_of_bytes_recvd);
00368   ACE_UNUSED_ARG (flags);
00369   ACE_UNUSED_ARG (addr);
00370   ACE_UNUSED_ARG (addrlen);
00371   ACE_UNUSED_ARG (overlapped);
00372   ACE_UNUSED_ARG (func);
00373   ACE_NOTSUP_RETURN (-1);
00374 #endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
00375 }
00376 
00377 ACE_INLINE ssize_t
00378 ACE_OS::recvmsg (ACE_HANDLE handle, struct msghdr *msg, int flags)
00379 {
00380   ACE_OS_TRACE ("ACE_OS::recvmsg");
00381 #if !defined (ACE_LACKS_RECVMSG)
00382 # if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00383   DWORD bytes_received = 0;
00384 
00385   int result = ::WSARecvFrom ((SOCKET) handle,
00386                               (WSABUF *) msg->msg_iov,
00387                               msg->msg_iovlen,
00388                               &bytes_received,
00389                               (DWORD *) &flags,
00390                               msg->msg_name,
00391                               &msg->msg_namelen,
00392                               0,
00393                               0);
00394 
00395   if (result != 0)
00396     {
00397       ACE_OS::set_errno_to_wsa_last_error ();
00398       return -1;
00399     }
00400   else
00401     return bytes_received;
00402 # else /* ACE_HAS_WINSOCK2 */
00403   ACE_SOCKCALL_RETURN (::recvmsg (handle, msg, flags), ssize_t, -1);
00404 # endif /* ACE_HAS_WINSOCK2 */
00405 #else
00406   ACE_UNUSED_ARG (flags);
00407   ACE_UNUSED_ARG (msg);
00408   ACE_UNUSED_ARG (handle);
00409 
00410   ACE_NOTSUP_RETURN (-1);
00411 #endif /* ACE_LACKS_RECVMSG */
00412 }
00413 
00414 ACE_INLINE ssize_t
00415 ACE_OS::recvv (ACE_HANDLE handle,
00416                iovec *buffers,
00417                int n)
00418 {
00419 #if defined (ACE_HAS_WINSOCK2)
00420 
00421   DWORD bytes_received = 0;
00422   int result = 1;
00423 
00424   // Winsock 2 has WSARecv and can do this directly, but Winsock 1 needs
00425   // to do the recvs piece-by-piece.
00426 
00427 # if (ACE_HAS_WINSOCK2 != 0)
00428   DWORD flags = 0;
00429   result = ::WSARecv ((SOCKET) handle,
00430                       (WSABUF *) buffers,
00431                       n,
00432                       &bytes_received,
00433                       &flags,
00434                       0,
00435                       0);
00436 # else
00437   int i, chunklen;
00438   char *chunkp = 0;
00439 
00440   // Step through the buffers requested by caller; for each one, cycle
00441   // through reads until it's filled or an error occurs.
00442   for (i = 0; i < n && result > 0; ++i)
00443     {
00444       chunkp = buffers[i].iov_base;     // Point to part of chunk being read
00445       chunklen = buffers[i].iov_len;    // Track how much to read to chunk
00446       while (chunklen > 0 && result > 0)
00447         {
00448           result = ::recv ((SOCKET) handle, chunkp, chunklen, 0);
00449           if (result > 0)
00450             {
00451               chunkp += result;
00452               chunklen -= result;
00453               bytes_received += result;
00454             }
00455         }
00456     }
00457 # endif /* ACE_HAS_WINSOCK2 != 0 */
00458 
00459   if (result == SOCKET_ERROR)
00460     {
00461       ACE_OS::set_errno_to_wsa_last_error ();
00462       return -1;
00463     }
00464   else
00465     return (ssize_t) bytes_received;
00466 #else
00467   return ACE_OS::readv (handle, buffers, n);
00468 #endif /* ACE_HAS_WINSOCK2 */
00469 }
00470 
00471 ACE_INLINE ssize_t
00472 ACE_OS::send (ACE_HANDLE handle, const char *buf, size_t len, int flags)
00473 {
00474   ACE_OS_TRACE ("ACE_OS::send");
00475 
00476   // On UNIX, a non-blocking socket with no data to receive, this
00477   // system call will return EWOULDBLOCK or EAGAIN, depending on the
00478   // platform.  UNIX 98 allows either errno, and they may be the same
00479   // numeric value.  So to make life easier for upper ACE layers as
00480   // well as application programmers, always change EAGAIN to
00481   // EWOULDBLOCK.  Rather than hack the ACE_OSCALL_RETURN macro, it's
00482   // handled explicitly here.  If the ACE_OSCALL macro ever changes,
00483   // this function needs to be reviewed.  On Win32, the regular macros
00484   // can be used, as this is not an issue.
00485 #if defined (ACE_WIN32)
00486   ACE_SOCKCALL_RETURN (::send ((ACE_SOCKET) handle,
00487                                buf,
00488                                static_cast<int> (len),
00489                                flags), ssize_t, -1);
00490 #else
00491   ssize_t const ace_result_ = ::send ((ACE_SOCKET) handle, buf, len, flags);
00492 
00493 # if !(defined (EAGAIN) && defined (EWOULDBLOCK) && EAGAIN == EWOULDBLOCK)
00494   // Optimize this code out if we can detect that EAGAIN ==
00495   // EWOULDBLOCK at compile time.  If we cannot detect equality at
00496   // compile-time (e.g. if EAGAIN or EWOULDBLOCK are not preprocessor
00497   // macros) perform the check at run-time.  The goal is to avoid two
00498   // TSS accesses in the _REENTRANT case when EAGAIN == EWOULDBLOCK.
00499   if (ace_result_ == -1
00500 #  if !defined (EAGAIN) || !defined (EWOULDBLOCK)
00501       && EAGAIN != EWOULDBLOCK
00502 #  endif  /* !EAGAIN || !EWOULDBLOCK */
00503       && errno == EAGAIN)
00504     {
00505       errno = EWOULDBLOCK;
00506     }
00507 # endif /* EAGAIN != EWOULDBLOCK*/
00508 
00509   return ace_result_;
00510 #endif /* defined (ACE_WIN32) */
00511 }
00512 
00513 ACE_INLINE ssize_t
00514 ACE_OS::sendmsg (ACE_HANDLE handle,
00515                  const struct msghdr *msg,
00516                  int flags)
00517 {
00518   ACE_OS_TRACE ("ACE_OS::sendmsg");
00519 #if !defined (ACE_LACKS_SENDMSG)
00520 # if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00521   DWORD bytes_sent = 0;
00522   int result = ::WSASendTo ((SOCKET) handle,
00523                             (WSABUF *) msg->msg_iov,
00524                             msg->msg_iovlen,
00525                             &bytes_sent,
00526                             flags,
00527                             msg->msg_name,
00528                             msg->msg_namelen,
00529                             0,
00530                             0);
00531 
00532   if (result != 0)
00533     {
00534       ACE_OS::set_errno_to_wsa_last_error ();
00535       return -1;
00536     }
00537   else
00538     return (ssize_t) bytes_sent;
00539 # elif defined (ACE_HAS_NONCONST_SENDMSG)
00540   ACE_SOCKCALL_RETURN (::sendmsg (handle,
00541                                   const_cast<struct msghdr *>(msg),
00542                                   flags), ssize_t, -1);
00543 # else
00544   ACE_SOCKCALL_RETURN (::sendmsg (handle, msg, flags), ssize_t, -1);
00545 # endif
00546 #else
00547   ACE_UNUSED_ARG (flags);
00548   ACE_UNUSED_ARG (msg);
00549   ACE_UNUSED_ARG (handle);
00550 
00551   ACE_NOTSUP_RETURN (-1);
00552 #endif /* ACE_LACKS_SENDMSG */
00553 }
00554 
00555 ACE_INLINE ssize_t
00556 ACE_OS::sendto (ACE_HANDLE handle,
00557                 const char *buf,
00558                 size_t len,
00559                 int flags,
00560                 const struct sockaddr *addr,
00561                 int addrlen)
00562 {
00563   ACE_OS_TRACE ("ACE_OS::sendto");
00564 #if defined (ACE_VXWORKS)
00565   ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle,
00566                                  const_cast <char *> (buf),
00567                                  len,
00568                                  flags,
00569                                  const_cast<struct sockaddr *> (addr),
00570                                  addrlen),
00571                        ssize_t, -1);
00572 #else
00573 #  if defined (ACE_WIN32)
00574   ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle,
00575                                  buf,
00576                                  static_cast<int> (len),
00577                                  flags,
00578                                  const_cast<struct sockaddr *> (addr),
00579                                  addrlen),
00580                        ssize_t, -1);
00581 #  else
00582   ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle,
00583                                  buf,
00584                                  len,
00585                                  flags,
00586                                  const_cast<struct sockaddr *> (addr),
00587                                  addrlen),
00588                        ssize_t, -1);
00589 #  endif /* ACE_WIN32 */
00590 #endif /* ACE_VXWORKS */
00591 }
00592 
00593 ACE_INLINE ssize_t
00594 ACE_OS::sendto (ACE_HANDLE handle,
00595                 const iovec *buffers,
00596                 int buffer_count,
00597                 size_t &number_of_bytes_sent,
00598                 int flags,
00599                 const struct sockaddr *addr,
00600                 int addrlen,
00601                 ACE_OVERLAPPED *overlapped,
00602                 ACE_OVERLAPPED_COMPLETION_FUNC func)
00603 {
00604   ACE_OS_TRACE ("ACE_OS::sendto");
00605 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00606   DWORD bytes_sent;
00607   int result = ::WSASendTo ((SOCKET) handle,
00608                             (WSABUF*)buffers,
00609                             buffer_count,
00610                             &bytes_sent,
00611                             flags,
00612                             addr,
00613                             addrlen,
00614                             overlapped,
00615                             func);
00616   if (result != 0) {
00617     ACE_OS::set_errno_to_wsa_last_error ();
00618   }
00619   number_of_bytes_sent = static_cast<size_t> (bytes_sent);
00620   return (ssize_t) result;
00621 #else
00622   ACE_UNUSED_ARG (overlapped);
00623   ACE_UNUSED_ARG (func);
00624 
00625   number_of_bytes_sent = 0;
00626 
00627   ssize_t result = 0;
00628 
00629   for (int i = 0; i < buffer_count; ++i)
00630     {
00631        result = ACE_OS::sendto (handle,
00632                                 reinterpret_cast<char *> (
00633                                                  buffers[i].iov_base),
00634                                 buffers[i].iov_len,
00635                                 flags,
00636                                 addr,
00637                                 addrlen);
00638        if (result == -1)
00639          break;
00640        number_of_bytes_sent += static_cast<size_t> (result);
00641     }
00642 
00643   return result;
00644 #endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
00645 }
00646 
00647 ACE_INLINE ssize_t
00648 ACE_OS::sendv (ACE_HANDLE handle,
00649                const iovec *buffers,
00650                int n)
00651 {
00652 #if defined (ACE_HAS_WINSOCK2)
00653   DWORD bytes_sent = 0;
00654   ssize_t result = 0;
00655 
00656   // Winsock 2 has WSASend and can do this directly, but Winsock 1
00657   // needs to do the sends one-by-one.
00658 # if (ACE_HAS_WINSOCK2 != 0)
00659   result = ::WSASend ((SOCKET) handle,
00660                       (WSABUF *) buffers,
00661                       n,
00662                       &bytes_sent,
00663                       0,
00664                       0,
00665                       0);
00666   if (result == SOCKET_ERROR)
00667     {
00668       ACE_OS::set_errno_to_wsa_last_error ();
00669       return -1;
00670     }
00671 # else
00672   for (int i = 0; i < n; ++i)
00673     {
00674       result = ::send ((SOCKET) handle,
00675                        buffers[i].iov_base,
00676                        buffers[i].iov_len,
00677                        0);
00678 
00679       if (result == SOCKET_ERROR)
00680         {
00681           // There is a subtle difference in behaviour depending on
00682           // whether or not any data was sent.  If no data was sent,
00683           // then always return -1.  Otherwise return bytes_sent.
00684           // This gives the caller an opportunity to keep track of
00685           // bytes that have already been sent.
00686           if (bytes_sent > 0)
00687             break;
00688           else
00689             {
00690               ACE_OS::set_errno_to_wsa_last_error ();
00691               return -1;
00692             }
00693         }
00694       else
00695         {
00696           // Gets ignored on error anyway
00697           bytes_sent += result;
00698 
00699           // If the transfer isn't complete just drop out of the loop.
00700           if (result < (int)buffers[i].iov_len)
00701             break;
00702         }
00703     }
00704 # endif /* ACE_HAS_WINSOCK2 != 0 */
00705 
00706   return (ssize_t) bytes_sent;
00707 
00708 #elif defined (ACE_HAS_SOCK_BUF_SIZE_MAX)
00709 
00710   // Platform limits the maximum socket message size.  Pare down the
00711   // iovec, if necessary, to obey the limit.
00712   iovec local_iov[ACE_IOV_MAX];
00713   long total = 0;
00714   long new_total = 0;
00715   for (int i = 0; i < n; i++)
00716     {
00717       local_iov[i].iov_base = buffers[i].iov_base;
00718       local_iov[i].iov_len  = buffers[i].iov_len;
00719 
00720       new_total = total + buffers[i].iov_len;
00721       if ( new_total >= SSIZE_MAX )
00722         {
00723           local_iov[i].iov_len = SSIZE_MAX - total;
00724           n = i+1;
00725           break;
00726         }
00727       total = new_total;
00728     }
00729   return ACE_OS::writev (handle, local_iov, n);
00730 
00731 #else
00732   return ACE_OS::writev (handle, buffers, n);
00733 #endif /* ACE_HAS_WINSOCK2 */
00734 }
00735 
00736 ACE_INLINE int
00737 ACE_OS::setsockopt (ACE_HANDLE handle,
00738                     int level,
00739                     int optname,
00740                     const char *optval,
00741                     int optlen)
00742 {
00743   ACE_OS_TRACE ("ACE_OS::setsockopt");
00744 
00745   #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && defined(SO_REUSEPORT)
00746   // To work around an inconsistency with Microsofts implementation of
00747   // sockets, we will check for SO_REUSEADDR, and ignore it. Winsock
00748   // always behaves as if SO_REUSEADDR=1. Some implementations have
00749   // the same behaviour as Winsock, but use a new name for
00750   // it. SO_REUSEPORT.  If you want the normal behaviour for
00751   // SO_REUSEADDR=0, then NT 4 sp4 and later supports
00752   // SO_EXCLUSIVEADDRUSE. This also requires using an updated Platform
00753   // SDK so it was decided to ignore the option for now. (Especially
00754   // since Windows always sets SO_REUSEADDR=1, which we can mimic by doing
00755   // nothing.)
00756   if (level == SOL_SOCKET) {
00757     if (optname == SO_REUSEADDR) {
00758       return 0; // Not supported by Winsock
00759     }
00760     if (optname == SO_REUSEPORT) {
00761       optname = SO_REUSEADDR;
00762     }
00763   }
00764   #endif /*ACE_HAS_WINSOCK2*/
00765 
00766   int result;
00767   ACE_SOCKCALL (::setsockopt ((ACE_SOCKET) handle,
00768                               level,
00769                               optname,
00770                               (ACE_SOCKOPT_TYPE1) optval,
00771                               optlen),
00772                 int,
00773                 -1,
00774                 result);
00775 #if defined (WSAEOPNOTSUPP)
00776   if (result == -1 && errno == WSAEOPNOTSUPP)
00777 #else
00778   if (result == -1)
00779 #endif /* WSAEOPNOTSUPP */
00780     errno = ENOTSUP;
00781   return result;
00782 }
00783 
00784 ACE_INLINE int
00785 ACE_OS::shutdown (ACE_HANDLE handle, int how)
00786 {
00787   ACE_OS_TRACE ("ACE_OS::shutdown");
00788   ACE_SOCKCALL_RETURN (::shutdown ((ACE_SOCKET) handle, how), int, -1);
00789 }
00790 
00791 ACE_INLINE ACE_HANDLE
00792 ACE_OS::socket (int domain,
00793                 int type,
00794                 int proto)
00795 {
00796   ACE_OS_TRACE ("ACE_OS::socket");
00797   ACE_SOCKCALL_RETURN (::socket (domain,
00798                                  type,
00799                                  proto),
00800                        ACE_HANDLE,
00801                        ACE_INVALID_HANDLE);
00802 }
00803 
00804 ACE_INLINE ACE_HANDLE
00805 ACE_OS::socket (int domain,
00806                 int type,
00807                 int proto,
00808                 ACE_Protocol_Info *protocolinfo,
00809                 ACE_SOCK_GROUP g,
00810                 u_long flags)
00811 {
00812   ACE_OS_TRACE ("ACE_OS::socket");
00813 
00814 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00815   ACE_SOCKCALL_RETURN (::WSASocket (domain,
00816                                     type,
00817                                     proto,
00818                                     protocolinfo,
00819                                     g,
00820                                     flags),
00821                        ACE_HANDLE,
00822                        ACE_INVALID_HANDLE);
00823 #else
00824   ACE_UNUSED_ARG (protocolinfo);
00825   ACE_UNUSED_ARG (g);
00826   ACE_UNUSED_ARG (flags);
00827 
00828   return ACE_OS::socket (domain,
00829                          type,
00830                          proto);
00831 #endif /* ACE_HAS_WINSOCK2 */
00832 }
00833 
00834 ACE_INLINE int
00835 ACE_OS::socketpair (int domain, int type,
00836                     int protocol, ACE_HANDLE sv[2])
00837 {
00838   ACE_OS_TRACE ("ACE_OS::socketpair");
00839 #if defined (ACE_LACKS_SOCKETPAIR)
00840   ACE_UNUSED_ARG (domain);
00841   ACE_UNUSED_ARG (type);
00842   ACE_UNUSED_ARG (protocol);
00843   ACE_UNUSED_ARG (sv);
00844 
00845   ACE_NOTSUP_RETURN (-1);
00846 #else
00847   ACE_OSCALL_RETURN (::socketpair (domain, type, protocol, sv),
00848                      int, -1);
00849 #endif /* ACE_LACKS_SOCKETPAIR */
00850 }
00851 
00852 #if defined (__linux__) && defined (ACE_HAS_IPV6)
00853 ACE_INLINE unsigned int
00854 ACE_OS::if_nametoindex (const char *ifname)
00855 {
00856   ACE_OS_TRACE ("ACE_OS::if_nametoindex");
00857   ACE_OSCALL_RETURN (::if_nametoindex (ifname), int, 0);
00858 }
00859 
00860 ACE_INLINE char *
00861 ACE_OS::if_indextoname (unsigned int ifindex, char *ifname)
00862 {
00863   ACE_OS_TRACE ("ACE_OS::if_indextoname");
00864   ACE_OSCALL_RETURN (::if_indextoname (ifindex, ifname), char *, 0);
00865 }
00866 
00867 ACE_INLINE struct if_nameindex *
00868 ACE_OS::if_nameindex (void)
00869 {
00870   ACE_OS_TRACE ("ACE_OS::if_nameindex");
00871   ACE_OSCALL_RETURN (::if_nameindex (), struct if_nameindex *, 0);
00872 }
00873 
00874 ACE_INLINE void
00875 ACE_OS::if_freenameindex (struct if_nameindex *ptr)
00876 {
00877   ACE_OS_TRACE ("ACE_OS::if_freenameindex");
00878   if (ptr != 0)
00879     ::if_freenameindex (ptr);
00880 }
00881 #endif /* __linux__ && ACE_HAS_IPV6 */
00882 
00883 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:58 2006 for ACE by doxygen 1.3.6