OS_NS_sys_socket.inl

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

Generated on Sun Jan 27 12:05:33 2008 for ACE by doxygen 1.3.6