OS_NS_sys_socket.inl

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

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7