ACE.cpp

Go to the documentation of this file.
00001 // ACE.cpp,v 4.396 2006/05/30 10:18:12 jwillemsen Exp
00002 
00003 #include "ace/ACE.h"
00004 
00005 #include "ace/Basic_Types.h"
00006 #include "ace/Handle_Set.h"
00007 #include "ace/Auto_Ptr.h"
00008 #include "ace/SString.h"
00009 #include "ace/Version.h"
00010 #include "ace/Message_Block.h"
00011 #include "ace/Log_Msg.h"
00012 #include "ace/OS_NS_sys_select.h"
00013 #include "ace/OS_NS_string.h"
00014 #include "ace/OS_NS_strings.h"
00015 #include "ace/OS_NS_signal.h"
00016 #include "ace/OS_NS_stdio.h"
00017 #include "ace/OS_NS_sys_resource.h"
00018 #include "ace/OS_NS_sys_wait.h"
00019 #include "ace/OS_NS_sys_time.h"
00020 #include "ace/OS_NS_time.h"
00021 #include "ace/OS_NS_sys_uio.h"
00022 #include "ace/OS_NS_sys_stat.h"
00023 #include "ace/OS_NS_ctype.h"
00024 #include "ace/OS_TLI.h"
00025 
00026 #if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620)
00027 extern "C" int maxFiles;
00028 #endif /* ACE_VXWORKS */
00029 
00030 #if !defined (__ACE_INLINE__)
00031 #include "ace/ACE.inl"
00032 #endif /* __ACE_INLINE__ */
00033 
00034 #if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
00035 #  include "ace/OS_NS_poll.h"
00036 #endif /* ACE_HAS_POLL  && ACE_HAS_LIMITED_SELECT */
00037 
00038 
00039 ACE_RCSID (ace,
00040            ACE,
00041            "ACE.cpp,v 4.396 2006/05/30 10:18:12 jwillemsen Exp")
00042 
00043 
00044 // Open versioned namespace, if enabled by the user.
00045   ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00046 
00047 namespace ACE
00048 {
00049   // private:
00050   //  Used internally so not exported.
00051 
00052   // Size of allocation granularity.
00053   size_t allocation_granularity_ = 0;
00054 
00055   // Size of a VM page.
00056   size_t pagesize_ = 0;
00057 
00058   // Are we debugging ACE?
00059   // Keeps track of whether we're in some global debug mode.
00060   char debug_;
00061 }
00062 
00063 
00064 int
00065 ACE::out_of_handles (int error)
00066 {
00067   // EMFILE is common to all platforms.
00068   if (error == EMFILE ||
00069 #if defined (ACE_WIN32)
00070       // On Win32, we need to check for ENOBUFS also.
00071       error == ENOBUFS ||
00072 #elif defined (HPUX)
00073       // On HPUX, we need to check for EADDRNOTAVAIL also.
00074       error == EADDRNOTAVAIL ||
00075 #elif defined (linux)
00076       // On linux, we need to check for ENOENT also.
00077       error == ENOENT ||
00078       // For RedHat5.2, need to check for EINVAL too.
00079       error == EINVAL ||
00080       // Without threads check for EOPNOTSUPP
00081       error == EOPNOTSUPP ||
00082 #elif defined (sun)
00083       // On sun, we need to check for ENOSR also.
00084       error == ENOSR ||
00085       // Without threads check for ENOTSUP
00086       error == ENOTSUP ||
00087 #elif defined (__FreeBSD__)
00088       // On FreeBSD we need to check for EOPNOTSUPP (LinuxThreads) or
00089       // ENOSYS (libc_r threads) also.
00090       error == EOPNOTSUPP ||
00091       error == ENOSYS ||
00092 #elif defined (__OpenBSD__)
00093       // OpenBSD appears to return EBADF.
00094       error == EBADF ||
00095 #elif defined (__sgi) // irix
00096       error == ENOTSUP ||
00097 #elif defined (DIGITAL_UNIX) // osf1
00098       error == ENOTSUP ||
00099 #endif /* ACE_WIN32 */
00100       error == ENFILE)
00101     return 1;
00102   else
00103     return 0;
00104 }
00105 
00106 u_int
00107 ACE::major_version (void)
00108 {
00109   return ACE_MAJOR_VERSION;
00110 }
00111 
00112 u_int
00113 ACE::minor_version (void)
00114 {
00115   return ACE_MINOR_VERSION;
00116 }
00117 
00118 u_int
00119 ACE::beta_version (void)
00120 {
00121   return ACE_BETA_VERSION;
00122 }
00123 
00124 const ACE_TCHAR *
00125 ACE::compiler_name (void)
00126 {
00127 #ifdef ACE_CC_NAME
00128   return ACE_CC_NAME;
00129 #else
00130   return ACE_LIB_TEXT ("");
00131 #endif
00132 }
00133 
00134 u_int
00135 ACE::compiler_major_version (void)
00136 {
00137 #ifdef ACE_CC_MAJOR_VERSION
00138   return ACE_CC_MAJOR_VERSION;
00139 #else
00140   return 0;
00141 #endif
00142 }
00143 
00144 u_int
00145 ACE::compiler_minor_version (void)
00146 {
00147 #ifdef ACE_CC_MINOR_VERSION
00148   return ACE_CC_MINOR_VERSION;
00149 #else
00150   return 0;
00151 #endif
00152 }
00153 
00154 u_int
00155 ACE::compiler_beta_version (void)
00156 {
00157 #ifdef ACE_CC_BETA_VERSION
00158   return ACE_CC_BETA_VERSION;
00159 #else
00160   return 0;
00161 #endif
00162 }
00163 
00164 char
00165 ACE::debug (void)
00166 {
00167   static const char* debug = ACE_OS::getenv ("ACE_DEBUG");
00168   return ACE::debug_ != 0 ? ACE::debug_ : (debug != 0 ? (*debug - '0'): 0);
00169 }
00170 
00171 void
00172 ACE::debug (char c)
00173 {
00174   ACE::debug_ = c;
00175 }
00176 
00177 int
00178 ACE::select (int width,
00179              ACE_Handle_Set *readfds,
00180              ACE_Handle_Set *writefds,
00181              ACE_Handle_Set *exceptfds,
00182              const ACE_Time_Value *timeout)
00183 {
00184   int result = ACE_OS::select (width,
00185                                readfds ? readfds->fdset () : 0,
00186                                writefds ? writefds->fdset () : 0,
00187                                exceptfds ? exceptfds->fdset () : 0,
00188                                timeout);
00189   if (result > 0)
00190     {
00191 # if !defined (ACE_WIN32)
00192       // This isn't needed for Windows... it's a no-op anyway.
00193       if (readfds)
00194         readfds->sync ((ACE_HANDLE) width);
00195       if (writefds)
00196         writefds->sync ((ACE_HANDLE) width);
00197       if (exceptfds)
00198         exceptfds->sync ((ACE_HANDLE) width);
00199 #endif /* ACE_WIN32 */
00200     }
00201   return result;
00202 }
00203 
00204 int
00205 ACE::select (int width,
00206              ACE_Handle_Set &readfds,
00207              const ACE_Time_Value *timeout)
00208 {
00209   int result = ACE_OS::select (width,
00210                                readfds.fdset (),
00211                                0,
00212                                0,
00213                                timeout);
00214 
00215 #if !defined (ACE_WIN32)
00216   if (result > 0)
00217     readfds.sync ((ACE_HANDLE) width);
00218 #endif /* ACE_WIN32 */
00219   return result;
00220 }
00221 
00222 int
00223 ACE::terminate_process (pid_t pid)
00224 {
00225 #if defined (ACE_HAS_PHARLAP)
00226   ACE_UNUSED_ARG (pid);
00227   ACE_NOTSUP_RETURN (-1);
00228 #elif defined (ACE_WIN32)
00229   // Create a handle for the given process id.
00230   ACE_HANDLE process_handle =
00231     ::OpenProcess (PROCESS_TERMINATE,
00232                    FALSE, // New handle is not inheritable.
00233                    pid);
00234 
00235   if (process_handle == ACE_INVALID_HANDLE
00236       || process_handle == 0)
00237     return -1;
00238   else
00239     {
00240       // Kill the process associated with process_handle.
00241       BOOL terminate_result =
00242         ::TerminateProcess (process_handle, 0);
00243       // Free up the kernel resources.
00244       ACE_OS::close (process_handle);
00245       return terminate_result ? 0 : -1;
00246     }
00247 #else
00248   return ACE_OS::kill (pid, 9);
00249 #endif /* ACE_HAS_PHARLAP */
00250 }
00251 
00252 int
00253 ACE::process_active (pid_t pid)
00254 {
00255 #if !defined(ACE_WIN32)
00256   int retval = ACE_OS::kill (pid, 0);
00257 
00258   if (retval == 0)
00259     return 1;
00260   else if (errno == ESRCH)
00261     return 0;
00262   else
00263     return -1;
00264 #else
00265   // Create a handle for the given process id.
00266   ACE_HANDLE process_handle =
00267     ::OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
00268   if (process_handle == ACE_INVALID_HANDLE
00269       || process_handle == 0)
00270     return 0;
00271   else
00272     {
00273       DWORD status;
00274       int result = 1;
00275       if (::GetExitCodeProcess (process_handle,
00276                                 &status) == 0
00277           || status != STILL_ACTIVE)
00278         result = 0;
00279 
00280       ::CloseHandle (process_handle);
00281       return result;
00282     }
00283 #endif /* !ACE_WIN32 */
00284 }
00285 
00286 const ACE_TCHAR *
00287 ACE::execname (const ACE_TCHAR *old_name)
00288 {
00289 #if defined (ACE_WIN32)
00290   const ACE_TCHAR *suffix = ACE_OS::strrchr (old_name, ACE_LIB_TEXT ('.'));
00291   if (suffix == 0 || ACE_OS::strcasecmp (suffix, ACE_LIB_TEXT (".exe")) != 0)
00292     {
00293       ACE_TCHAR *new_name;
00294 
00295       size_t size =
00296         ACE_OS::strlen (old_name)
00297         + ACE_OS::strlen (ACE_LIB_TEXT (".exe"))
00298         + 1;
00299 
00300       ACE_NEW_RETURN (new_name,
00301                       ACE_TCHAR[size],
00302                       0);
00303       ACE_TCHAR *end = new_name;
00304 
00305       end = ACE_OS::strecpy (new_name, old_name);
00306 
00307       // Concatenate the .exe suffix onto the end of the executable.
00308       // end points _after_ the terminating nul.
00309       ACE_OS::strcpy (end - 1, ACE_LIB_TEXT (".exe"));
00310 
00311       return new_name;
00312     }
00313 #endif /* ACE_WIN32 */
00314   return old_name;
00315 }
00316 
00317 u_long
00318 ACE::hash_pjw (const char *str, size_t len)
00319 {
00320   u_long hash = 0;
00321 
00322   for (size_t i = 0; i < len; i++)
00323     {
00324       const char temp = str[i];
00325       hash = (hash << 4) + (temp * 13);
00326 
00327       u_long g = hash & 0xf0000000;
00328 
00329       if (g)
00330         {
00331           hash ^= (g >> 24);
00332           hash ^= g;
00333         }
00334     }
00335 
00336   return hash;
00337 }
00338 
00339 u_long
00340 ACE::hash_pjw (const char *str)
00341 {
00342   return ACE::hash_pjw (str, ACE_OS::strlen (str));
00343 }
00344 
00345 #if defined (ACE_HAS_WCHAR)
00346 u_long
00347 ACE::hash_pjw (const wchar_t *str, size_t len)
00348 {
00349   u_long hash = 0;
00350 
00351   for (size_t i = 0; i < len; i++)
00352     {
00353       // @@ UNICODE: Does this function do the correct thing with wchar's?
00354 
00355       const wchar_t temp = str[i];
00356       hash = (hash << 4) + (temp * 13);
00357 
00358       u_long g = hash & 0xf0000000;
00359 
00360       if (g)
00361         {
00362           hash ^= (g >> 24);
00363           hash ^= g;
00364         }
00365     }
00366 
00367   return hash;
00368 }
00369 
00370 u_long
00371 ACE::hash_pjw (const wchar_t *str)
00372 {
00373   return ACE::hash_pjw (str, ACE_OS::strlen (str));
00374 }
00375 #endif /* ACE_HAS_WCHAR */
00376 
00377 #if !defined (ACE_HAS_WINCE)
00378 ACE_TCHAR *
00379 ACE::strenvdup (const ACE_TCHAR *str)
00380 {
00381   ACE_TRACE ("ACE::strenvdup");
00382 
00383   return ACE_OS::strenvdup (str);
00384 }
00385 #endif /* ACE_HAS_WINCE */
00386 
00387 /*
00388 
00389 Examples:
00390 
00391 Source               NT                    UNIX
00392 ==================================================================
00393 netsvc               netsvc.dll            libnetsvc.so
00394 (PATH will be         (LD_LIBRARY_PATH
00395 evaluated)            evaluated)
00396 
00397 libnetsvc.dll        libnetsvc.dll         libnetsvc.dll + warning
00398 netsvc.so            netsvc.so + warning   libnetsvc.so
00399 
00400 ..\../libs/netsvc    ..\..\libs\netsvc.dll ../../libs/netsvc.so
00401 (absolute path used)  (absolute path used)
00402 
00403 */
00404 
00405 const ACE_TCHAR *
00406 ACE::basename (const ACE_TCHAR *pathname, ACE_TCHAR delim)
00407 {
00408   ACE_TRACE ("ACE::basename");
00409   const ACE_TCHAR *temp = ACE_OS::strrchr (pathname, delim);
00410 
00411   if (temp == 0)
00412     return pathname;
00413   else
00414     return temp + 1;
00415 }
00416 
00417 const ACE_TCHAR *
00418 ACE::dirname (const ACE_TCHAR *pathname, ACE_TCHAR delim)
00419 {
00420   ACE_TRACE ("ACE::dirname");
00421   static ACE_TCHAR return_dirname[MAXPATHLEN + 1];
00422 
00423   const ACE_TCHAR *temp = ACE_OS::strrchr (pathname, delim);
00424 
00425   if (temp == 0)
00426     {
00427       return_dirname[0] = '.';
00428       return_dirname[1] = '\0';
00429 
00430       return return_dirname;
00431     }
00432   else
00433     {
00434       // When the len is truncated, there are problems!  This should
00435       // not happen in normal circomstances
00436       size_t len = temp - pathname + 1;
00437       if (len > (sizeof return_dirname / sizeof (ACE_TCHAR)))
00438         len = sizeof return_dirname / sizeof (ACE_TCHAR);
00439 
00440       ACE_OS::strsncpy (return_dirname,
00441                         pathname,
00442                         len);
00443       return return_dirname;
00444     }
00445 }
00446 
00447 ssize_t
00448 ACE::recv (ACE_HANDLE handle,
00449            void *buf,
00450            size_t len,
00451            int flags,
00452            const ACE_Time_Value *timeout)
00453 {
00454   if (timeout == 0)
00455     return ACE_OS::recv (handle, (char *) buf, len, flags);
00456   else
00457     {
00458 #if defined (ACE_HAS_RECV_TIMEDWAIT)
00459       ACE_Time_Value copy = *timeout;
00460       copy += ACE_OS::gettimeofday ();
00461       timespec_t ts = copy;
00462       return ::recv_timedwait (handle, buf, len, flags, &ts);
00463 #else
00464       int val = 0;
00465       if (ACE::enter_recv_timedwait (handle, timeout, val) ==-1)
00466         return -1;
00467       else
00468         {
00469           ssize_t bytes_transferred =
00470             ACE_OS::recv (handle, (char *) buf, len, flags);
00471           ACE::restore_non_blocking_mode (handle, val);
00472           return bytes_transferred;
00473         }
00474 #endif /* ACE_HAS_RECV_TIMEDWAIT */
00475     }
00476 }
00477 
00478 #if defined (ACE_HAS_TLI)
00479 
00480 ssize_t
00481 ACE::t_rcv (ACE_HANDLE handle,
00482             void *buf,
00483             size_t len,
00484             int *flags,
00485             const ACE_Time_Value *timeout)
00486 {
00487   if (timeout == 0)
00488     return ACE_OS::t_rcv (handle, (char *) buf, len, flags);
00489   else
00490     {
00491       int val = 0;
00492       if (ACE::enter_recv_timedwait (handle, timeout, val) ==-1)
00493         return -1;
00494       else
00495         {
00496           ssize_t bytes_transferred =
00497             ACE_OS::t_rcv (handle, (char *) buf, len, flags);
00498           ACE::restore_non_blocking_mode (handle, val);
00499           return bytes_transferred;
00500         }
00501     }
00502 }
00503 
00504 #endif /* ACE_HAS_TLI */
00505 
00506 ssize_t
00507 ACE::recv (ACE_HANDLE handle,
00508            void *buf,
00509            size_t n,
00510            const ACE_Time_Value *timeout)
00511 {
00512   if (timeout == 0)
00513     return ACE::recv_i (handle, buf, n);
00514   else
00515     {
00516 #if defined (ACE_HAS_READ_TIMEDWAIT)
00517       ACE_Time_Value copy = *timeout;
00518       copy += ACE_OS::gettimeofday ();
00519       timespec_t ts = copy;
00520       return ::read_timedwait (handle, buf, n, &ts);
00521 #else
00522       int val = 0;
00523       if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
00524         return -1;
00525       else
00526         {
00527           ssize_t bytes_transferred = ACE::recv_i (handle, buf, n);
00528           ACE::restore_non_blocking_mode (handle, val);
00529           return bytes_transferred;
00530         }
00531 #endif /* ACE_HAS_READ_TIMEDWAIT */
00532     }
00533 }
00534 
00535 ssize_t
00536 ACE::recvmsg (ACE_HANDLE handle,
00537               struct msghdr *msg,
00538               int flags,
00539               const ACE_Time_Value *timeout)
00540 {
00541   if (timeout == 0)
00542     return ACE_OS::recvmsg (handle, msg, flags);
00543   else
00544     {
00545 #if defined (ACE_HAS_RECVMSG_TIMEDWAIT)
00546       ACE_Time_Value copy = *timeout;
00547       copy += ACE_OS::gettimeofday ();
00548       timespec_t ts = copy;
00549       return ::recvmsg_timedwait (handle, msg, flags, &ts);
00550 #else
00551       int val = 0;
00552       if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
00553         return -1;
00554       else
00555         {
00556           ssize_t bytes_transferred = ACE_OS::recvmsg (handle, msg, flags);
00557           ACE::restore_non_blocking_mode (handle, val);
00558           return bytes_transferred;
00559         }
00560 #endif /* ACE_HAS_RECVMSG_TIMEDWAIT */
00561     }
00562 }
00563 
00564 ssize_t
00565 ACE::recvfrom (ACE_HANDLE handle,
00566                char *buf,
00567                int len,
00568                int flags,
00569                struct sockaddr *addr,
00570                int *addrlen,
00571                const ACE_Time_Value *timeout)
00572 {
00573   if (timeout == 0)
00574     return ACE_OS::recvfrom (handle, buf, len, flags, addr, addrlen);
00575   else
00576     {
00577 #if defined (ACE_HAS_RECVFROM_TIMEDWAIT)
00578       ACE_Time_Value copy = *timeout;
00579       copy += ACE_OS::gettimeofday ();
00580       timespec_t ts = copy;
00581       return ::recvfrom_timedwait (handle, buf, len, flags, addr, addrlen, &ts);
00582 #else
00583       int val = 0;
00584       if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
00585         return -1;
00586       else
00587         {
00588           ssize_t bytes_transferred =
00589             ACE_OS::recvfrom (handle, buf, len, flags, addr, addrlen);
00590           ACE::restore_non_blocking_mode (handle, val);
00591           return bytes_transferred;
00592         }
00593 #endif /* ACE_HAS_RECVFROM_TIMEDWAIT */
00594     }
00595 }
00596 
00597 ssize_t
00598 ACE::recv_n_i (ACE_HANDLE handle,
00599                void *buf,
00600                size_t len,
00601                int flags,
00602                size_t *bt)
00603 {
00604   size_t temp;
00605   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00606   ssize_t n;
00607 
00608   for (bytes_transferred = 0;
00609        bytes_transferred < len;
00610        bytes_transferred += n)
00611     {
00612       // Try to transfer as much of the remaining data as possible.
00613       n = ACE_OS::recv (handle,
00614                         static_cast <char *> (buf) + bytes_transferred,
00615                         len - bytes_transferred,
00616                         flags);
00617       // Check EOF.
00618       if (n == 0)
00619         return 0;
00620 
00621       // Check for other errors.
00622       if (n == -1)
00623         {
00624           // Check for possible blocking.
00625           if (errno == EWOULDBLOCK)
00626             {
00627               // Wait for the blocking to subside.
00628               int result = ACE::handle_read_ready (handle,
00629                                                    0);
00630 
00631               // Did select() succeed?
00632               if (result != -1)
00633                 {
00634                   // Blocking subsided.  Continue data transfer.
00635                   n = 0;
00636                   continue;
00637                 }
00638             }
00639 
00640           // Other data transfer or select() failures.
00641           return -1;
00642         }
00643     }
00644 
00645   return static_cast<ssize_t> (bytes_transferred);
00646 }
00647 
00648 ssize_t
00649 ACE::recv_n_i (ACE_HANDLE handle,
00650                void *buf,
00651                size_t len,
00652                int flags,
00653                const ACE_Time_Value *timeout,
00654                size_t *bt)
00655 {
00656   size_t temp;
00657   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00658   ssize_t n;
00659   ssize_t result = 0;
00660   int error = 0;
00661 
00662   int val = 0;
00663   ACE::record_and_set_non_blocking_mode (handle, val);
00664 
00665   for (bytes_transferred = 0;
00666        bytes_transferred < len;
00667        bytes_transferred += n)
00668     {
00669       // Try to transfer as much of the remaining data as possible.
00670       // Since the socket is in non-blocking mode, this call will not
00671       // block.
00672       n = ACE_OS::recv (handle,
00673                         static_cast <char *> (buf) + bytes_transferred,
00674                         len - bytes_transferred,
00675                         flags);
00676 
00677       // Check for errors.
00678       if (n == 0 ||
00679           n == -1)
00680         {
00681           // Check for possible blocking.
00682           if (n == -1 &&
00683               errno == EWOULDBLOCK)
00684             {
00685               // Wait upto <timeout> for the blocking to subside.
00686               int rtn = ACE::handle_read_ready (handle,
00687                                                 timeout);
00688 
00689               // Did select() succeed?
00690               if (rtn != -1)
00691                 {
00692                   // Blocking subsided in <timeout> period.  Continue
00693                   // data transfer.
00694                   n = 0;
00695                   continue;
00696                 }
00697             }
00698 
00699           // Wait in select() timed out or other data transfer or
00700           // select() failures.
00701           error = 1;
00702           result = n;
00703           break;
00704         }
00705     }
00706 
00707   ACE::restore_non_blocking_mode (handle, val);
00708 
00709   if (error)
00710     return result;
00711   else
00712     return static_cast<ssize_t> (bytes_transferred);
00713 }
00714 
00715 #if defined (ACE_HAS_TLI)
00716 
00717 ssize_t
00718 ACE::t_rcv_n_i (ACE_HANDLE handle,
00719                 void *buf,
00720                 size_t len,
00721                 int *flags,
00722                 size_t *bt)
00723 {
00724   size_t temp;
00725   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00726   ssize_t n;
00727 
00728   for (bytes_transferred = 0;
00729        bytes_transferred < len;
00730        bytes_transferred += n)
00731     {
00732       // Try to transfer as much of the remaining data as possible.
00733       n = ACE_OS::t_rcv (handle,
00734                          (char *) buf + bytes_transferred,
00735                          len - bytes_transferred,
00736                          flags);
00737       // Check EOF.
00738       if (n == 0)
00739         return 0;
00740 
00741       // Check for other errors.
00742       if (n == -1)
00743         {
00744           // Check for possible blocking.
00745           if (errno == EWOULDBLOCK)
00746             {
00747               // Wait for the blocking to subside.
00748               int result = ACE::handle_read_ready (handle,
00749                                                    0);
00750 
00751               // Did select() succeed?
00752               if (result != -1)
00753                 {
00754                   // Blocking subsided.  Continue data transfer.
00755                   n = 0;
00756                   continue;
00757                 }
00758             }
00759 
00760           // Other data transfer or select() failures.
00761           return -1;
00762         }
00763     }
00764 
00765   return bytes_transferred;
00766 }
00767 
00768 ssize_t
00769 ACE::t_rcv_n_i (ACE_HANDLE handle,
00770                 void *buf,
00771                 size_t len,
00772                 int *flags,
00773                 const ACE_Time_Value *timeout,
00774                 size_t *bt)
00775 {
00776   size_t temp;
00777   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00778   ssize_t n;
00779   ssize_t result = 0;
00780   int error = 0;
00781 
00782   int val = 0;
00783   ACE::record_and_set_non_blocking_mode (handle, val);
00784 
00785   for (bytes_transferred = 0;
00786        bytes_transferred < len;
00787        bytes_transferred += n)
00788     {
00789       // Try to transfer as much of the remaining data as possible.
00790       // Since the socket is in non-blocking mode, this call will not
00791       // block.
00792       n = ACE_OS::t_rcv (handle,
00793                          (char *) buf + bytes_transferred,
00794                          len - bytes_transferred,
00795                          flags);
00796 
00797       // Check for errors.
00798       if (n == 0 ||
00799           n == -1)
00800         {
00801           // Check for possible blocking.
00802           if (n == -1 &&
00803               errno == EWOULDBLOCK)
00804             {
00805               // Wait upto <timeout> for the blocking to subside.
00806               int rtn = ACE::handle_read_ready (handle,
00807                                                 timeout);
00808 
00809               // Did select() succeed?
00810               if (rtn != -1)
00811                 {
00812                   // Blocking subsided in <timeout> period.  Continue
00813                   // data transfer.
00814                   n = 0;
00815                   continue;
00816                 }
00817             }
00818 
00819           // Wait in select() timed out or other data transfer or
00820           // select() failures.
00821           error = 1;
00822           result = n;
00823           break;
00824         }
00825     }
00826 
00827   ACE::restore_non_blocking_mode (handle, val);
00828 
00829   if (error)
00830     return result;
00831   else
00832     return bytes_transferred;
00833 }
00834 
00835 #endif /* ACE_HAS_TLI */
00836 
00837 ssize_t
00838 ACE::recv_n_i (ACE_HANDLE handle,
00839                void *buf,
00840                size_t len,
00841                size_t *bt)
00842 {
00843   size_t temp;
00844   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00845   ssize_t n;
00846 
00847   for (bytes_transferred = 0;
00848        bytes_transferred < len;
00849        bytes_transferred += n)
00850     {
00851       // Try to transfer as much of the remaining data as possible.
00852       n = ACE::recv_i (handle,
00853                        static_cast <char *> (buf) + bytes_transferred,
00854                        len - bytes_transferred);
00855       // Check EOF.
00856       if (n == 0)
00857         {
00858           return 0;
00859         }
00860       // Check for other errors.
00861       if (n == -1)
00862         {
00863           // Check for possible blocking.
00864           if (errno == EWOULDBLOCK)
00865             {
00866               // Wait for the blocking to subside.
00867               int result = ACE::handle_read_ready (handle,
00868                                                    0);
00869 
00870               // Did select() succeed?
00871               if (result != -1)
00872                 {
00873                   // Blocking subsided.  Continue data transfer.
00874                   n = 0;
00875                   continue;
00876                 }
00877             }
00878 
00879           // Other data transfer or select() failures.
00880           return -1;
00881         }
00882     }
00883 
00884   return static_cast<ssize_t> (bytes_transferred);
00885 }
00886 
00887 ssize_t
00888 ACE::recv_n_i (ACE_HANDLE handle,
00889                void *buf,
00890                size_t len,
00891                const ACE_Time_Value *timeout,
00892                size_t *bt)
00893 {
00894   size_t temp;
00895   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00896   ssize_t n;
00897   ssize_t result = 0;
00898   int error = 0;
00899 
00900   int val = 0;
00901   ACE::record_and_set_non_blocking_mode (handle, val);
00902 
00903   for (bytes_transferred = 0;
00904        bytes_transferred < len;
00905        bytes_transferred += n)
00906     {
00907       // Try to transfer as much of the remaining data as possible.
00908       // Since the socket is in non-blocking mode, this call will not
00909       // block.
00910       n = ACE::recv_i (handle,
00911                        static_cast <char *> (buf) + bytes_transferred,
00912                        len - bytes_transferred);
00913 
00914       // Check for errors.
00915       if (n == 0 ||
00916           n == -1)
00917         {
00918           // Check for possible blocking.
00919           if (n == -1 &&
00920               errno == EWOULDBLOCK)
00921             {
00922               // Wait upto <timeout> for the blocking to subside.
00923               int rtn = ACE::handle_read_ready (handle,
00924                                                 timeout);
00925 
00926               // Did select() succeed?
00927               if (rtn != -1)
00928                 {
00929                   // Blocking subsided in <timeout> period.  Continue
00930                   // data transfer.
00931                   n = 0;
00932                   continue;
00933                 }
00934             }
00935 
00936           // Wait in select() timed out or other data transfer or
00937           // select() failures.
00938           error = 1;
00939           result = n;
00940           break;
00941         }
00942     }
00943 
00944   ACE::restore_non_blocking_mode (handle, val);
00945 
00946   if (error)
00947     return result;
00948   else
00949     return static_cast<ssize_t> (bytes_transferred);
00950 }
00951 
00952 // This is basically an interface to ACE_OS::readv, that doesn't use
00953 // the struct iovec explicitly.  The ... can be passed as an arbitrary
00954 // number of (char *ptr, int len) tuples.  However, the count N is the
00955 // *total* number of trailing arguments, *not* a couple of the number
00956 // of tuple pairs!
00957 
00958 ssize_t
00959 ACE::recv (ACE_HANDLE handle, size_t n, ...)
00960 {
00961   va_list argp;
00962   int total_tuples = static_cast<int> (n / 2);
00963   iovec *iovp;
00964 #if defined (ACE_HAS_ALLOCA)
00965   iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
00966 #else
00967   ACE_NEW_RETURN (iovp,
00968                   iovec[total_tuples],
00969                   -1);
00970 #endif /* !defined (ACE_HAS_ALLOCA) */
00971 
00972   va_start (argp, n);
00973 
00974   for (int i = 0; i < total_tuples; i++)
00975     {
00976       iovp[i].iov_base = va_arg (argp, char *);
00977       iovp[i].iov_len = va_arg (argp, int);
00978     }
00979 
00980   ssize_t result = ACE_OS::recvv (handle, iovp, total_tuples);
00981 #if !defined (ACE_HAS_ALLOCA)
00982   delete [] iovp;
00983 #endif /* !defined (ACE_HAS_ALLOCA) */
00984   va_end (argp);
00985   return result;
00986 }
00987 
00988 ssize_t
00989 ACE::recvv (ACE_HANDLE handle,
00990             iovec *iov,
00991             int iovcnt,
00992             const ACE_Time_Value *timeout)
00993 {
00994   if (timeout == 0)
00995     return ACE_OS::recvv (handle, iov, iovcnt);
00996   else
00997     {
00998 #if defined (ACE_HAS_READV_TIMEDWAIT)
00999       ACE_Time_Value copy = *timeout;
01000       copy += ACE_OS::gettimeofday ();
01001       timespec_t ts = copy;
01002       return ::readv_timedwait (handle, iov, iovcnt, &ts);
01003 #else
01004       int val = 0;
01005       if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
01006         return -1;
01007       else
01008         {
01009           ssize_t bytes_transferred = ACE_OS::recvv (handle, iov, iovcnt);
01010           ACE::restore_non_blocking_mode (handle, val);
01011           return bytes_transferred;
01012         }
01013 #endif /* ACE_HAS_READV_TIMEDWAIT */
01014     }
01015 }
01016 
01017 ssize_t
01018 ACE::recvv_n_i (ACE_HANDLE handle,
01019                 iovec *iov,
01020                 int iovcnt,
01021                 size_t *bt)
01022 {
01023   size_t temp;
01024   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01025   bytes_transferred = 0;
01026 
01027   for (int s = 0;
01028        s < iovcnt;
01029        )
01030     {
01031       // Try to transfer as much of the remaining data as possible.
01032       ssize_t n = ACE_OS::recvv (handle,
01033                                  iov + s,
01034                                  iovcnt - s);
01035       // Check EOF.
01036       if (n == 0)
01037         return 0;
01038 
01039       // Check for other errors.
01040       if (n == -1)
01041         {
01042           // Check for possible blocking.
01043           if (errno == EWOULDBLOCK)
01044             {
01045               // Wait for the blocking to subside.
01046               int result = ACE::handle_read_ready (handle,
01047                                                    0);
01048 
01049               // Did select() succeed?
01050               if (result != -1)
01051                 {
01052                   // Blocking subsided.  Continue data transfer.
01053                   n = 0;
01054                   continue;
01055                 }
01056             }
01057 
01058           // Other data transfer or select() failures.
01059           return -1;
01060         }
01061 
01062       for (bytes_transferred += n;
01063            s < iovcnt
01064              && n >= static_cast<ssize_t> (iov[s].iov_len);
01065            s++)
01066         n -= iov[s].iov_len;
01067 
01068       if (n != 0)
01069         {
01070           char *base = static_cast<char *> (iov[s].iov_base);
01071           iov[s].iov_base = base + n;
01072           iov[s].iov_len = iov[s].iov_len - n;
01073         }
01074     }
01075 
01076   return bytes_transferred;
01077 }
01078 
01079 ssize_t
01080 ACE::recvv_n_i (ACE_HANDLE handle,
01081                 iovec *iov,
01082                 int iovcnt,
01083                 const ACE_Time_Value *timeout,
01084                 size_t *bt)
01085 {
01086   size_t temp;
01087   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01088   bytes_transferred = 0;
01089   ssize_t result = 0;
01090   int error = 0;
01091 
01092   int val = 0;
01093   ACE::record_and_set_non_blocking_mode (handle, val);
01094 
01095   for (int s = 0;
01096        s < iovcnt;
01097        )
01098     {
01099       // Try to transfer as much of the remaining data as possible.
01100       // Since the socket is in non-blocking mode, this call will not
01101       // block.
01102       ssize_t n = ACE_OS::recvv (handle,
01103                                  iov + s,
01104                                  iovcnt - s);
01105 
01106       // Check for errors.
01107       if (n == 0 ||
01108           n == -1)
01109         {
01110           // Check for possible blocking.
01111           if (n == -1 &&
01112               errno == EWOULDBLOCK)
01113             {
01114               // Wait upto <timeout> for the blocking to subside.
01115               int rtn = ACE::handle_read_ready (handle,
01116                                                 timeout);
01117 
01118               // Did select() succeed?
01119               if (rtn != -1)
01120                 {
01121                   // Blocking subsided in <timeout> period.  Continue
01122                   // data transfer.
01123                   n = 0;
01124                   continue;
01125                 }
01126             }
01127 
01128           // Wait in select() timed out or other data transfer or
01129           // select() failures.
01130           error = 1;
01131           result = n;
01132           break;
01133         }
01134 
01135       for (bytes_transferred += n;
01136            s < iovcnt
01137              && n >= static_cast<ssize_t> (iov[s].iov_len);
01138            s++)
01139         n -= iov[s].iov_len;
01140 
01141       if (n != 0)
01142         {
01143           char *base = reinterpret_cast<char *> (iov[s].iov_base);
01144           iov[s].iov_base = base + n;
01145           iov[s].iov_len = iov[s].iov_len - n;
01146         }
01147     }
01148 
01149   ACE::restore_non_blocking_mode (handle, val);
01150 
01151   if (error)
01152     return result;
01153   else
01154     return bytes_transferred;
01155 }
01156 
01157 ssize_t
01158 ACE::recv_n (ACE_HANDLE handle,
01159              ACE_Message_Block *message_block,
01160              const ACE_Time_Value *timeout,
01161              size_t *bt)
01162 {
01163   size_t temp;
01164   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01165   bytes_transferred = 0;
01166 
01167   iovec iov[ACE_IOV_MAX];
01168   int iovcnt = 0;
01169 
01170   while (message_block != 0)
01171     {
01172       // Our current message block chain.
01173       const ACE_Message_Block *current_message_block = message_block;
01174 
01175       while (current_message_block != 0)
01176         {
01177           size_t current_message_block_length =
01178             current_message_block->length ();
01179           char *this_rd_ptr = current_message_block->rd_ptr ();
01180 
01181           // Check if this block has any space for incoming data.
01182           while (current_message_block_length > 0)
01183             {
01184               u_long this_chunk_length;
01185               if (current_message_block_length > ULONG_MAX)
01186                 this_chunk_length = ULONG_MAX;
01187               else
01188                 this_chunk_length =
01189                   static_cast<u_long> (current_message_block_length);
01190               // Collect the data in the iovec.
01191               iov[iovcnt].iov_base = this_rd_ptr;
01192               iov[iovcnt].iov_len  = this_chunk_length;
01193               current_message_block_length -= this_chunk_length;
01194               this_rd_ptr += this_chunk_length;
01195 
01196               // Increment iovec counter.
01197               ++iovcnt;
01198 
01199               // The buffer is full make a OS call.  @@ TODO find a way to
01200               // find ACE_IOV_MAX for platforms that do not define it rather
01201               // than simply setting ACE_IOV_MAX to some arbitrary value such
01202               // as 16.
01203               if (iovcnt == ACE_IOV_MAX)
01204                 {
01205                   size_t current_transfer = 0;
01206 
01207                   ssize_t result = ACE::recvv_n (handle,
01208                                                  iov,
01209                                                  iovcnt,
01210                                                  timeout,
01211                                                  &current_transfer);
01212 
01213                   // Add to total bytes transferred.
01214                   bytes_transferred += current_transfer;
01215 
01216                   // Errors.
01217                   if (result == -1 || result == 0)
01218                     return result;
01219 
01220                   // Reset iovec counter.
01221                   iovcnt = 0;
01222                 }
01223             }
01224 
01225           // Select the next message block in the chain.
01226           current_message_block = current_message_block->cont ();
01227         }
01228 
01229       // Selection of the next message block chain.
01230       message_block = message_block->next ();
01231     }
01232 
01233   // Check for remaining buffers to be sent.  This will happen when
01234   // ACE_IOV_MAX is not a multiple of the number of message blocks.
01235   if (iovcnt != 0)
01236     {
01237       size_t current_transfer = 0;
01238 
01239       ssize_t result = ACE::recvv_n (handle,
01240                                      iov,
01241                                      iovcnt,
01242                                      timeout,
01243                                      &current_transfer);
01244 
01245       // Add to total bytes transferred.
01246       bytes_transferred += current_transfer;
01247 
01248       // Errors.
01249       if (result == -1 || result == 0)
01250         return result;
01251     }
01252 
01253   // Return total bytes transferred.
01254   return bytes_transferred;
01255 }
01256 
01257 ssize_t
01258 ACE::send (ACE_HANDLE handle,
01259            const void *buf,
01260            size_t n,
01261            int flags,
01262            const ACE_Time_Value *timeout)
01263 {
01264   if (timeout == 0)
01265     return ACE_OS::send (handle, (const char *) buf, n, flags);
01266   else
01267     {
01268 #if defined (ACE_HAS_SEND_TIMEDWAIT)
01269       ACE_Time_Value copy = *timeout;
01270       copy += ACE_OS::gettimeofday();
01271       timespec_t ts = copy;
01272       return ::send_timedwait (handle, buf, n, flags, &ts);
01273 #else
01274       int val = 0;
01275       if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
01276         return -1;
01277       else
01278         {
01279           ssize_t bytes_transferred = ACE_OS::send (handle, (const char *) buf, n, flags);
01280           ACE::restore_non_blocking_mode (handle, val);
01281           return bytes_transferred;
01282         }
01283 #endif /* ACE_HAS_SEND_TIMEDWAIT */
01284     }
01285 }
01286 
01287 #if defined (ACE_HAS_TLI)
01288 
01289 ssize_t
01290 ACE::t_snd (ACE_HANDLE handle,
01291             const void *buf,
01292             size_t n,
01293             int flags,
01294             const ACE_Time_Value *timeout)
01295 {
01296   if (timeout == 0)
01297     return ACE_OS::t_snd (handle, (const char *) buf, n, flags);
01298   else
01299     {
01300       int val = 0;
01301       if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
01302         return -1;
01303       else
01304         {
01305           ssize_t bytes_transferred = ACE_OS::t_snd (handle, (const char *) buf, n, flags);
01306           ACE::restore_non_blocking_mode (handle, val);
01307           return bytes_transferred;
01308         }
01309     }
01310 }
01311 
01312 #endif /* ACE_HAS_TLI */
01313 
01314 ssize_t
01315 ACE::send (ACE_HANDLE handle,
01316            const void *buf,
01317            size_t n,
01318            const ACE_Time_Value *timeout)
01319 {
01320   if (timeout == 0)
01321     return ACE::send_i (handle, buf, n);
01322   else
01323     {
01324 #if defined (ACE_HAS_WRITE_TIMEDWAIT)
01325       ACE_Time_Value copy = *timeout;
01326       copy += ACE_OS::gettimeofday ();
01327       timespec_t ts = copy;
01328       return ::write_timedwait (handle, buf, n, &ts);
01329 #else
01330       int val = 0;
01331       if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
01332         return -1;
01333       else
01334         {
01335           ssize_t bytes_transferred = ACE::send_i (handle, buf, n);
01336           ACE::restore_non_blocking_mode (handle, val);
01337           return bytes_transferred;
01338         }
01339 #endif /* ACE_HAS_WRITE_TIMEDWAIT */
01340     }
01341 }
01342 
01343 ssize_t
01344 ACE::sendmsg (ACE_HANDLE handle,
01345               const struct msghdr *msg,
01346               int flags,
01347               const ACE_Time_Value *timeout)
01348 {
01349   if (timeout == 0)
01350     return ACE_OS::sendmsg (handle, msg, flags);
01351   else
01352     {
01353 #if defined (ACE_HAS_SENDMSG_TIMEDWAIT)
01354       ACE_Time_Value copy = *timeout;
01355       copy += ACE_OS::gettimeofday ();
01356       timespec_t ts = copy;
01357       return ::sendmsg_timedwait (handle, msg, flags, &ts);
01358 #else
01359       int val = 0;
01360       if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
01361         return -1;
01362       else
01363         {
01364           ssize_t bytes_transferred = ACE_OS::sendmsg (handle, msg, flags);
01365           ACE::restore_non_blocking_mode (handle, val);
01366           return bytes_transferred;
01367         }
01368 #endif /* ACE_HAS_SENDMSG_TIMEDWAIT */
01369     }
01370 }
01371 
01372 ssize_t
01373 ACE::sendto (ACE_HANDLE handle,
01374              const char *buf,
01375              int len,
01376              int flags,
01377              const struct sockaddr *addr,
01378              int addrlen,
01379              const ACE_Time_Value *timeout)
01380 {
01381   if (timeout == 0)
01382     return ACE_OS::sendto (handle, buf, len, flags, addr, addrlen);
01383   else
01384     {
01385 #if defined (ACE_HAS_SENDTO_TIMEDWAIT)
01386       ACE_Time_Value copy = *timeout;
01387       copy += ACE_OS::gettimeofday ();
01388       timespec_t ts = copy;
01389       return ::sendto_timedwait (handle, buf, len, flags, addr, addrlen, ts);
01390 #else
01391       int val = 0;
01392       if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
01393         return -1;
01394       else
01395         {
01396           ssize_t bytes_transferred =
01397             ACE_OS::sendto (handle, buf, len, flags, addr, addrlen);
01398           ACE::restore_non_blocking_mode (handle, val);
01399           return bytes_transferred;
01400         }
01401 #endif /* ACE_HAS_SENDTO_TIMEDWAIT */
01402     }
01403 }
01404 
01405 ssize_t
01406 ACE::send_n_i (ACE_HANDLE handle,
01407                const void *buf,
01408                size_t len,
01409                int flags,
01410                size_t *bt)
01411 {
01412   size_t temp;
01413   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01414   ssize_t n;
01415 
01416   for (bytes_transferred = 0;
01417        bytes_transferred < len;
01418        bytes_transferred += n)
01419     {
01420       // Try to transfer as much of the remaining data as possible.
01421       n = ACE_OS::send (handle,
01422                         (char *) buf + bytes_transferred,
01423                         len - bytes_transferred,
01424                         flags);
01425       // Check EOF.
01426       if (n == 0)
01427         return 0;
01428 
01429       // Check for other errors.
01430       if (n == -1)
01431         {
01432           // Check for possible blocking.
01433           if (errno == EWOULDBLOCK || errno == ENOBUFS)
01434             {
01435               // Wait for the blocking to subside.
01436               int result = ACE::handle_write_ready (handle,
01437                                                     0);
01438 
01439               // Did select() succeed?
01440               if (result != -1)
01441                 {
01442                   // Blocking subsided.  Continue data transfer.
01443                   n = 0;
01444                   continue;
01445                 }
01446             }
01447 
01448           // Other data transfer or select() failures.
01449           return -1;
01450         }
01451     }
01452 
01453   return bytes_transferred;
01454 }
01455 
01456 ssize_t
01457 ACE::send_n_i (ACE_HANDLE handle,
01458                const void *buf,
01459                size_t len,
01460                int flags,
01461                const ACE_Time_Value *timeout,
01462                size_t *bt)
01463 {
01464   size_t temp;
01465   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01466   ssize_t n;
01467   ssize_t result = 0;
01468   int error = 0;
01469 
01470   int val = 0;
01471   ACE::record_and_set_non_blocking_mode (handle, val);
01472 
01473   for (bytes_transferred = 0;
01474        bytes_transferred < len;
01475        bytes_transferred += n)
01476     {
01477       // Try to transfer as much of the remaining data as possible.
01478       // Since the socket is in non-blocking mode, this call will not
01479       // block.
01480       n = ACE_OS::send (handle,
01481                         (char *) buf + bytes_transferred,
01482                         len - bytes_transferred,
01483                         flags);
01484 
01485       // Check for errors.
01486       if (n == 0 ||
01487           n == -1)
01488         {
01489           // Check for possible blocking.
01490           if (n == -1 &&
01491               errno == EWOULDBLOCK || errno == ENOBUFS)
01492             {
01493               // Wait upto <timeout> for the blocking to subside.
01494               int rtn = ACE::handle_write_ready (handle,
01495                                                  timeout);
01496 
01497               // Did select() succeed?
01498               if (rtn != -1)
01499                 {
01500                   // Blocking subsided in <timeout> period.  Continue
01501                   // data transfer.
01502                   n = 0;
01503                   continue;
01504                 }
01505             }
01506 
01507           // Wait in select() timed out or other data transfer or
01508           // select() failures.
01509           error = 1;
01510           result = n;
01511           break;
01512         }
01513     }
01514 
01515   ACE::restore_non_blocking_mode (handle, val);
01516 
01517   if (error)
01518     return result;
01519   else
01520     return bytes_transferred;
01521 }
01522 
01523 #if defined (ACE_HAS_TLI)
01524 
01525 ssize_t
01526 ACE::t_snd_n_i (ACE_HANDLE handle,
01527                 const void *buf,
01528                 size_t len,
01529                 int flags,
01530                 size_t *bt)
01531 {
01532   size_t temp;
01533   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01534   ssize_t n;
01535 
01536   for (bytes_transferred = 0;
01537        bytes_transferred < len;
01538        bytes_transferred += n)
01539     {
01540       // Try to transfer as much of the remaining data as possible.
01541       n = ACE_OS::t_snd (handle,
01542                          (char *) buf + bytes_transferred,
01543                          len - bytes_transferred,
01544                          flags);
01545       // Check EOF.
01546       if (n == 0)
01547         return 0;
01548 
01549       // Check for other errors.
01550       if (n == -1)
01551         {
01552           // Check for possible blocking.
01553           if (errno == EWOULDBLOCK || errno == ENOBUFS)
01554             {
01555               // Wait for the blocking to subside.
01556               int result = ACE::handle_write_ready (handle,
01557                                                     0);
01558 
01559               // Did select() succeed?
01560               if (result != -1)
01561                 {
01562                   // Blocking subsided.  Continue data transfer.
01563                   n = 0;
01564                   continue;
01565                 }
01566             }
01567 
01568           // Other data transfer or select() failures.
01569           return -1;
01570         }
01571     }
01572 
01573   return bytes_transferred;
01574 }
01575 
01576 ssize_t
01577 ACE::t_snd_n_i (ACE_HANDLE handle,
01578                 const void *buf,
01579                 size_t len,
01580                 int flags,
01581                 const ACE_Time_Value *timeout,
01582                 size_t *bt)
01583 {
01584   size_t temp;
01585   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01586   ssize_t n;
01587   ssize_t result = 0;
01588   int error = 0;
01589 
01590   int val = 0;
01591   ACE::record_and_set_non_blocking_mode (handle, val);
01592 
01593   for (bytes_transferred = 0;
01594        bytes_transferred < len;
01595        bytes_transferred += n)
01596     {
01597       // Try to transfer as much of the remaining data as possible.
01598       // Since the socket is in non-blocking mode, this call will not
01599       // block.
01600       n = ACE_OS::t_snd (handle,
01601                          (char *) buf + bytes_transferred,
01602                          len - bytes_transferred,
01603                          flags);
01604 
01605       // Check for errors.
01606       if (n == 0 ||
01607           n == -1)
01608         {
01609           // Check for possible blocking.
01610           if (n == -1 &&
01611               errno == EWOULDBLOCK || errno == ENOBUFS)
01612             {
01613               // Wait upto <timeout> for the blocking to subside.
01614               int rtn = ACE::handle_write_ready (handle,
01615                                                  timeout);
01616 
01617               // Did select() succeed?
01618               if (rtn != -1)
01619                 {
01620                   // Blocking subsided in <timeout> period.  Continue
01621                   // data transfer.
01622                   n = 0;
01623                   continue;
01624                 }
01625             }
01626 
01627           // Wait in select() timed out or other data transfer or
01628           // select() failures.
01629           error = 1;
01630           result = n;
01631           break;
01632         }
01633     }
01634 
01635   ACE::restore_non_blocking_mode (handle, val);
01636 
01637   if (error)
01638     return result;
01639   else
01640     return bytes_transferred;
01641 }
01642 
01643 #endif /* ACE_HAS_TLI */
01644 
01645 ssize_t
01646 ACE::send_n_i (ACE_HANDLE handle,
01647                const void *buf,
01648                size_t len,
01649                size_t *bt)
01650 {
01651   size_t temp;
01652   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01653   ssize_t n;
01654 
01655   for (bytes_transferred = 0;
01656        bytes_transferred < len;
01657        bytes_transferred += n)
01658     {
01659       // Try to transfer as much of the remaining data as possible.
01660       n = ACE::send_i (handle,
01661                        (char *) buf + bytes_transferred,
01662                        len - bytes_transferred);
01663       // Check EOF.
01664       if (n == 0)
01665         return 0;
01666 
01667       // Check for other errors.
01668       if (n == -1)
01669         {
01670           // Check for possible blocking.
01671           if (errno == EWOULDBLOCK || errno == ENOBUFS)
01672             {
01673               // Wait for the blocking to subside.
01674               int result = ACE::handle_write_ready (handle,
01675                                                     0);
01676 
01677               // Did select() succeed?
01678               if (result != -1)
01679                 {
01680                   // Blocking subsided.  Continue data transfer.
01681                   n = 0;
01682                   continue;
01683                 }
01684             }
01685 
01686           // Other data transfer or select() failures.
01687           return -1;
01688         }
01689     }
01690 
01691   return bytes_transferred;
01692 }
01693 
01694 ssize_t
01695 ACE::send_n_i (ACE_HANDLE handle,
01696                const void *buf,
01697                size_t len,
01698                const ACE_Time_Value *timeout,
01699                size_t *bt)
01700 {
01701   size_t temp;
01702   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01703   ssize_t n;
01704   ssize_t result = 0;
01705   int error = 0;
01706 
01707   int val = 0;
01708   ACE::record_and_set_non_blocking_mode (handle, val);
01709 
01710   for (bytes_transferred = 0;
01711        bytes_transferred < len;
01712        bytes_transferred += n)
01713     {
01714       // Try to transfer as much of the remaining data as possible.
01715       // Since the socket is in non-blocking mode, this call will not
01716       // block.
01717       n = ACE::send_i (handle,
01718                        (char *) buf + bytes_transferred,
01719                        len - bytes_transferred);
01720 
01721       // Check for errors.
01722       if (n == 0 ||
01723           n == -1)
01724         {
01725           // Check for possible blocking.
01726           if (n == -1 &&
01727               errno == EWOULDBLOCK || errno == ENOBUFS)
01728             {
01729               // Wait upto <timeout> for the blocking to subside.
01730               int rtn = ACE::handle_write_ready (handle,
01731                                                  timeout);
01732 
01733               // Did select() succeed?
01734               if (rtn != -1)
01735                 {
01736                   // Blocking subsided in <timeout> period.  Continue
01737                   // data transfer.
01738                   n = 0;
01739                   continue;
01740                 }
01741             }
01742 
01743           // Wait in select() timed out or other data transfer or
01744           // select() failures.
01745           error = 1;
01746           result = n;
01747           break;
01748         }
01749     }
01750 
01751   ACE::restore_non_blocking_mode (handle, val);
01752 
01753   if (error)
01754     return result;
01755   else
01756     return bytes_transferred;
01757 }
01758 
01759 // Send N char *ptrs and int lengths.  Note that the char *'s precede
01760 // the ints (basically, an varargs version of writev).  The count N is
01761 // the *total* number of trailing arguments, *not* a couple of the
01762 // number of tuple pairs!
01763 
01764 ssize_t
01765 ACE::send (ACE_HANDLE handle, size_t n, ...)
01766 {
01767   va_list argp;
01768   int total_tuples = static_cast<int> (n / 2);
01769   iovec *iovp;
01770 #if defined (ACE_HAS_ALLOCA)
01771   iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
01772 #else
01773   ACE_NEW_RETURN (iovp,
01774                   iovec[total_tuples],
01775                   -1);
01776 #endif /* !defined (ACE_HAS_ALLOCA) */
01777 
01778   va_start (argp, n);
01779 
01780   for (int i = 0; i < total_tuples; i++)
01781     {
01782       iovp[i].iov_base = va_arg (argp, char *);
01783       iovp[i].iov_len = va_arg (argp, int);
01784     }
01785 
01786   ssize_t result = ACE_OS::sendv (handle, iovp, total_tuples);
01787 #if !defined (ACE_HAS_ALLOCA)
01788   delete [] iovp;
01789 #endif /* !defined (ACE_HAS_ALLOCA) */
01790   va_end (argp);
01791   return result;
01792 }
01793 
01794 ssize_t
01795 ACE::sendv (ACE_HANDLE handle,
01796             const iovec *iov,
01797             int iovcnt,
01798             const ACE_Time_Value *timeout)
01799 {
01800   if (timeout == 0)
01801     return ACE_OS::sendv (handle, iov, iovcnt);
01802   else
01803     {
01804 #if defined (ACE_HAS_WRITEV_TIMEDWAIT)
01805       ACE_Time_Value copy = *timeout;
01806       copy += ACE_OS::gettimeofday ();
01807       timespec_t ts = copy;
01808       return ::sendv_timedwait (handle, iov, iovcnt, &ts);
01809 #else
01810       int val = 0;
01811       if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
01812         return -1;
01813       else
01814         {
01815           ssize_t bytes_transferred = ACE_OS::sendv (handle, iov, iovcnt);
01816           ACE::restore_non_blocking_mode (handle, val);
01817           return bytes_transferred;
01818         }
01819 #endif /* ACE_HAS_WRITEV_TIMEDWAIT */
01820     }
01821 }
01822 
01823 ssize_t
01824 ACE::sendv_n_i (ACE_HANDLE handle,
01825                 const iovec *i,
01826                 int iovcnt,
01827                 size_t *bt)
01828 {
01829   size_t temp;
01830   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01831   bytes_transferred = 0;
01832 
01833   iovec *iov = const_cast<iovec *> (i);
01834 
01835   for (int s = 0;
01836        s < iovcnt;
01837        )
01838     {
01839       // Try to transfer as much of the remaining data as possible.
01840       ssize_t n = ACE_OS::sendv (handle,
01841                                  iov + s,
01842                                  iovcnt - s);
01843       // Check EOF.
01844       if (n == 0)
01845         return 0;
01846 
01847       // Check for other errors.
01848       if (n == -1)
01849         {
01850           // Check for possible blocking.
01851           if (errno == EWOULDBLOCK || errno == ENOBUFS)
01852             {
01853               // Wait for the blocking to subside.
01854               int result = ACE::handle_write_ready (handle,
01855                                                     0);
01856 
01857               // Did select() succeed?
01858               if (result != -1)
01859                 {
01860                   // Blocking subsided.  Continue data transfer.
01861                   n = 0;
01862                   continue;
01863                 }
01864             }
01865 
01866           // Other data transfer or select() failures.
01867           return -1;
01868         }
01869 
01870       for (bytes_transferred += n;
01871            s < iovcnt
01872              && n >= static_cast<ssize_t> (iov[s].iov_len);
01873            s++)
01874         n -= iov[s].iov_len;
01875 
01876       if (n != 0)
01877         {
01878           char *base = reinterpret_cast<char *> (iov[s].iov_base);
01879           iov[s].iov_base = base + n;
01880           iov[s].iov_len = iov[s].iov_len - n;
01881         }
01882     }
01883 
01884   return bytes_transferred;
01885 }
01886 
01887 ssize_t
01888 ACE::sendv_n_i (ACE_HANDLE handle,
01889                 const iovec *i,
01890                 int iovcnt,
01891                 const ACE_Time_Value *timeout,
01892                 size_t *bt)
01893 {
01894   size_t temp;
01895   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01896   bytes_transferred = 0;
01897   ssize_t result = 0;
01898   int error = 0;
01899 
01900   int val = 0;
01901   ACE::record_and_set_non_blocking_mode (handle, val);
01902 
01903   iovec *iov = const_cast<iovec *> (i);
01904 
01905   for (int s = 0;
01906        s < iovcnt;
01907        )
01908     {
01909       // Try to transfer as much of the remaining data as possible.
01910       // Since the socket is in non-blocking mode, this call will not
01911       // block.
01912       ssize_t n = ACE_OS::sendv (handle,
01913                                  iov + s,
01914                                  iovcnt - s);
01915 
01916       // Check for errors.
01917       if (n == 0 ||
01918           n == -1)
01919         {
01920           // Check for possible blocking.
01921           if (n == -1 &&
01922               errno == EWOULDBLOCK || errno == ENOBUFS)
01923             {
01924               // Wait upto <timeout> for the blocking to subside.
01925               int rtn = ACE::handle_write_ready (handle,
01926                                                  timeout);
01927 
01928               // Did select() succeed?
01929               if (rtn != -1)
01930                 {
01931                   // Blocking subsided in <timeout> period.  Continue
01932                   // data transfer.
01933                   n = 0;
01934                   continue;
01935                 }
01936             }
01937 
01938           // Wait in select() timed out or other data transfer or
01939           // select() failures.
01940           error = 1;
01941           result = n;
01942           break;
01943         }
01944 
01945       for (bytes_transferred += n;
01946            s < iovcnt
01947              && n >= static_cast<ssize_t> (iov[s].iov_len);
01948            s++)
01949         n -= iov[s].iov_len;
01950 
01951       if (n != 0)
01952         {
01953           char *base = reinterpret_cast<char *> (iov[s].iov_base);
01954           iov[s].iov_base = base + n;
01955           iov[s].iov_len = iov[s].iov_len - n;
01956         }
01957     }
01958 
01959   ACE::restore_non_blocking_mode (handle, val);
01960 
01961   if (error)
01962     return result;
01963   else
01964     return bytes_transferred;
01965 }
01966 
01967 ssize_t
01968 ACE::write_n (ACE_HANDLE handle,
01969               const ACE_Message_Block *message_block,
01970               size_t *bt)
01971 {
01972   size_t temp;
01973   size_t &bytes_transferred = bt == 0 ? temp : *bt;
01974   bytes_transferred = 0;
01975 
01976   iovec iov[ACE_IOV_MAX];
01977   int iovcnt = 0;
01978 
01979   while (message_block != 0)
01980     {
01981       // Our current message block chain.
01982       const ACE_Message_Block *current_message_block = message_block;
01983 
01984       while (current_message_block != 0)
01985         {
01986           size_t current_message_block_length =
01987             current_message_block->length ();
01988           char *this_block_ptr = current_message_block->rd_ptr ();
01989 
01990           // Check if this block has any data to be sent.
01991           while (current_message_block_length > 0)
01992             {
01993               u_long this_chunk_length;
01994               if (current_message_block_length > ULONG_MAX)
01995                 this_chunk_length = ULONG_MAX;
01996               else
01997                 this_chunk_length =
01998                   static_cast<u_long> (current_message_block_length);
01999               // Collect the data in the iovec.
02000               iov[iovcnt].iov_base = this_block_ptr;
02001               iov[iovcnt].iov_len  = this_chunk_length;
02002               current_message_block_length -= this_chunk_length;
02003               this_block_ptr += this_chunk_length;
02004 
02005               // Increment iovec counter.
02006               ++iovcnt;
02007 
02008               // The buffer is full make a OS call.  @@ TODO find a way to
02009               // find ACE_IOV_MAX for platforms that do not define it rather
02010               // than simply setting ACE_IOV_MAX to some arbitrary value such
02011               // as 16.
02012               if (iovcnt == ACE_IOV_MAX)
02013                 {
02014                   size_t current_transfer = 0;
02015 
02016                   ssize_t result = ACE::writev_n (handle,
02017                                                   iov,
02018                                                   iovcnt,
02019                                                   &current_transfer);
02020 
02021                   // Add to total bytes transferred.
02022                   bytes_transferred += current_transfer;
02023 
02024                   // Errors.
02025                   if (result == -1 || result == 0)
02026                     return result;
02027 
02028                   // Reset iovec counter.
02029                   iovcnt = 0;
02030                 }
02031             }
02032 
02033           // Select the next message block in the chain.
02034           current_message_block = current_message_block->cont ();
02035         }
02036 
02037       // Selection of the next message block chain.
02038       message_block = message_block->next ();
02039     }
02040 
02041   // Check for remaining buffers to be sent.  This will happen when
02042   // ACE_IOV_MAX is not a multiple of the number of message blocks.
02043   if (iovcnt != 0)
02044     {
02045       size_t current_transfer = 0;
02046 
02047       ssize_t result = ACE::writev_n (handle,
02048                                       iov,
02049                                       iovcnt,
02050                                       &current_transfer);
02051 
02052       // Add to total bytes transferred.
02053       bytes_transferred += current_transfer;
02054 
02055       // Errors.
02056       if (result == -1 || result == 0)
02057         return result;
02058     }
02059 
02060   // Return total bytes transferred.
02061   return bytes_transferred;
02062 }
02063 
02064 ssize_t
02065 ACE::send_n (ACE_HANDLE handle,
02066              const ACE_Message_Block *message_block,
02067              const ACE_Time_Value *timeout,
02068              size_t *bt)
02069 {
02070   size_t temp;
02071   size_t &bytes_transferred = bt == 0 ? temp : *bt;
02072   bytes_transferred = 0;
02073 
02074   iovec iov[ACE_IOV_MAX];
02075   int iovcnt = 0;
02076 
02077   while (message_block != 0)
02078     {
02079       // Our current message block chain.
02080       const ACE_Message_Block *current_message_block = message_block;
02081 
02082       while (current_message_block != 0)
02083         {
02084           char *this_block_ptr = current_message_block->rd_ptr ();
02085           size_t current_message_block_length =
02086             current_message_block->length ();
02087 
02088           // Check if this block has any data to be sent.
02089           while (current_message_block_length > 0)
02090             {
02091               u_long this_chunk_length;
02092               if (current_message_block_length > ULONG_MAX)
02093                 this_chunk_length = ULONG_MAX;
02094               else
02095                 this_chunk_length =
02096                   static_cast<u_long> (current_message_block_length);
02097               // Collect the data in the iovec.
02098               iov[iovcnt].iov_base = this_block_ptr;
02099               iov[iovcnt].iov_len  = this_chunk_length;
02100               current_message_block_length -= this_chunk_length;
02101               this_block_ptr += this_chunk_length;
02102 
02103               // Increment iovec counter.
02104               ++iovcnt;
02105 
02106               // The buffer is full make a OS call.  @@ TODO find a way to
02107               // find ACE_IOV_MAX for platforms that do not define it rather
02108               // than simply setting ACE_IOV_MAX to some arbitrary value such
02109               // as 16.
02110               if (iovcnt == ACE_IOV_MAX)
02111                 {
02112                   size_t current_transfer = 0;
02113 
02114                   ssize_t result = ACE::sendv_n (handle,
02115                                                  iov,
02116                                                  iovcnt,
02117                                                  timeout,
02118                                                  &current_transfer);
02119 
02120                   // Add to total bytes transferred.
02121                   bytes_transferred += current_transfer;
02122 
02123                   // Errors.
02124                   if (result == -1 || result == 0)
02125                     return result;
02126 
02127                   // Reset iovec counter.
02128                   iovcnt = 0;
02129                 }
02130             }
02131 
02132           // Select the next message block in the chain.
02133           current_message_block = current_message_block->cont ();
02134         }
02135 
02136       // Selection of the next message block chain.
02137       message_block = message_block->next ();
02138     }
02139 
02140   // Check for remaining buffers to be sent.  This will happen when
02141   // ACE_IOV_MAX is not a multiple of the number of message blocks.
02142   if (iovcnt != 0)
02143     {
02144       size_t current_transfer = 0;
02145 
02146       ssize_t result = ACE::sendv_n (handle,
02147                                      iov,
02148                                      iovcnt,
02149                                      timeout,
02150                                      &current_transfer);
02151 
02152       // Add to total bytes transferred.
02153       bytes_transferred += current_transfer;
02154 
02155       // Errors.
02156       if (result == -1 || result == 0)
02157         return result;
02158     }
02159 
02160   // Return total bytes transferred.
02161   return bytes_transferred;
02162 }
02163 
02164 ssize_t
02165 ACE::readv_n (ACE_HANDLE handle,
02166               iovec *iov,
02167               int iovcnt,
02168               size_t *bt)
02169 {
02170   size_t temp;
02171   size_t &bytes_transferred = bt == 0 ? temp : *bt;
02172   bytes_transferred = 0;
02173 
02174   for (int s = 0;
02175        s < iovcnt;
02176        )
02177     {
02178       ssize_t n = ACE_OS::readv (handle,
02179                                  iov + s,
02180                                  iovcnt - s);
02181 
02182       if (n == -1 || n == 0)
02183         return n;
02184 
02185       for (bytes_transferred += n;
02186            s < iovcnt
02187              && n >= static_cast<ssize_t> (iov[s].iov_len);
02188            s++)
02189         n -= iov[s].iov_len;
02190 
02191       if (n != 0)
02192         {
02193           char *base = reinterpret_cast<char *> (iov[s].iov_base);
02194           iov[s].iov_base = base + n;
02195           iov[s].iov_len = iov[s].iov_len - n;
02196         }
02197     }
02198 
02199   return bytes_transferred;
02200 }
02201 
02202 ssize_t
02203 ACE::writev_n (ACE_HANDLE handle,
02204                const iovec *i,
02205                int iovcnt,
02206                size_t *bt)
02207 {
02208   size_t temp;
02209   size_t &bytes_transferred = bt == 0 ? temp : *bt;
02210   bytes_transferred = 0;
02211 
02212   iovec *iov = const_cast<iovec *> (i);
02213 
02214   for (int s = 0;
02215        s < iovcnt;
02216        )
02217     {
02218       ssize_t n = ACE_OS::writev (handle,
02219                                   iov + s,
02220                                   iovcnt - s);
02221       if (n == -1 || n == 0)
02222         return n;
02223 
02224       for (bytes_transferred += n;
02225            s < iovcnt
02226              && n >= static_cast<ssize_t> (iov[s].iov_len);
02227            s++)
02228         n -= iov[s].iov_len;
02229 
02230       if (n != 0)
02231         {
02232           char *base = reinterpret_cast<char *> (iov[s].iov_base);
02233           iov[s].iov_base = base + n;
02234           iov[s].iov_len = iov[s].iov_len - n;
02235         }
02236     }
02237 
02238   return bytes_transferred;
02239 }
02240 
02241 int
02242 ACE::handle_ready (ACE_HANDLE handle,
02243                    const ACE_Time_Value *timeout,
02244                    int read_ready,
02245                    int write_ready,
02246                    int exception_ready)
02247 {
02248 #if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02249   ACE_UNUSED_ARG (write_ready);
02250   ACE_UNUSED_ARG (exception_ready);
02251 
02252   struct pollfd fds;
02253 
02254   fds.fd = handle;
02255   fds.events = read_ready ? POLLIN : POLLOUT;
02256   fds.revents = 0;
02257 
02258   int result = ACE_OS::poll (&fds, 1, timeout);
02259 #else
02260   ACE_Handle_Set handle_set;
02261   handle_set.set_bit (handle);
02262 
02263   // Wait for data or for the timeout to elapse.
02264   int select_width;
02265 #  if defined (ACE_WIN32)
02266   // This arg is ignored on Windows and causes pointer truncation
02267   // warnings on 64-bit compiles.
02268   select_width = 0;
02269 #  else
02270   select_width = int (handle) + 1;
02271 #  endif /* ACE_WIN64 */
02272   int result = ACE_OS::select (select_width,
02273                                read_ready ? handle_set.fdset () : 0, // read_fds.
02274                                write_ready ? handle_set.fdset () : 0, // write_fds.
02275                                exception_ready ? handle_set.fdset () : 0, // exception_fds.
02276                                timeout);
02277 
02278 #endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02279 
02280   switch (result)
02281     {
02282     case 0:  // Timer expired.
02283       errno = ETIME;
02284       /* FALLTHRU */
02285     case -1: // we got here directly - select() returned -1.
02286       return -1;
02287     case 1: // Handle has data.
02288       /* FALLTHRU */
02289     default: // default is case result > 0; return a
02290       // ACE_ASSERT (result == 1);
02291       return result;
02292     }
02293 }
02294 
02295 int
02296 ACE::enter_recv_timedwait (ACE_HANDLE handle,
02297                            const ACE_Time_Value *timeout,
02298                            int &val)
02299 {
02300   int result = ACE::handle_read_ready (handle,
02301                                        timeout);
02302 
02303   if (result == -1)
02304     return -1;
02305 
02306   ACE::record_and_set_non_blocking_mode (handle,
02307                                          val);
02308 
02309   return result;
02310 }
02311 
02312 int
02313 ACE::enter_send_timedwait (ACE_HANDLE handle,
02314                            const ACE_Time_Value *timeout,
02315                            int &val)
02316 {
02317   int result = ACE::handle_write_ready (handle,
02318                                         timeout);
02319 
02320   if (result == -1)
02321     return -1;
02322 
02323   ACE::record_and_set_non_blocking_mode (handle,
02324                                          val);
02325 
02326   return result;
02327 }
02328 
02329 void
02330 ACE::record_and_set_non_blocking_mode (ACE_HANDLE handle,
02331                                        int &val)
02332 {
02333   // We need to record whether we are already *in* nonblocking mode,
02334   // so that we can correctly reset the state when we're done.
02335   val = ACE::get_flags (handle);
02336 
02337   if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
02338     // Set the handle into non-blocking mode if it's not already in
02339     // it.
02340     ACE::set_flags (handle, ACE_NONBLOCK);
02341 }
02342 
02343 void
02344 ACE::restore_non_blocking_mode (ACE_HANDLE handle,
02345                                 int val)
02346 {
02347   if (ACE_BIT_DISABLED (val,
02348                         ACE_NONBLOCK))
02349     {
02350       // Save/restore errno.
02351       ACE_Errno_Guard error (errno);
02352       // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
02353       // originally.
02354       ACE::clr_flags (handle, ACE_NONBLOCK);
02355     }
02356 }
02357 
02358 
02359 // Format buffer into printable format.  This is useful for debugging.
02360 // Portions taken from mdump by J.P. Knight (J.P.Knight@lut.ac.uk)
02361 // Modifications by Todd Montgomery.
02362 
02363 size_t
02364 ACE::format_hexdump (const char *buffer,
02365                      size_t size,
02366                      ACE_TCHAR *obuf,
02367                      size_t obuf_sz)
02368 {
02369   ACE_TRACE ("ACE::format_hexdump");
02370 
02371   u_char c;
02372   ACE_TCHAR textver[16 + 1];
02373 
02374   // We can fit 16 bytes output in text mode per line, 4 chars per byte.
02375   size_t maxlen = (obuf_sz / 68) * 16;
02376 
02377   if (size > maxlen)
02378     size = maxlen;
02379 
02380   size_t i;
02381 
02382   size_t lines = size / 16;
02383   for (i = 0; i < lines; i++)
02384     {
02385       size_t j;
02386 
02387       for (j = 0 ; j < 16; j++)
02388         {
02389           c = (u_char) buffer[(i << 4) + j];    // or, buffer[i*16+j]
02390           ACE_OS::sprintf (obuf,
02391                            ACE_LIB_TEXT ("%02x "),
02392                            c);
02393           obuf += 3;
02394           if (j == 7)
02395             {
02396               ACE_OS::sprintf (obuf,
02397                                ACE_LIB_TEXT (" "));
02398               ++obuf;
02399             }
02400           textver[j] = ACE_OS::ace_isprint (c) ? c : '.';
02401         }
02402 
02403       textver[j] = 0;
02404 
02405       ACE_OS::sprintf (obuf,
02406                        ACE_LIB_TEXT ("  %s\n"),
02407                        textver);
02408 
02409       while (*obuf != '\0')
02410         obuf++;
02411     }
02412 
02413   if (size % 16)
02414     {
02415       for (i = 0 ; i < size % 16; i++)
02416         {
02417           c = (u_char) buffer[size - size % 16 + i];
02418           ACE_OS::sprintf (obuf,
02419                            ACE_LIB_TEXT ("%02x "),
02420                            c);
02421           obuf += 3;
02422           if (i == 7)
02423             {
02424               ACE_OS::sprintf (obuf,
02425                                ACE_LIB_TEXT (" "));
02426               ++obuf;
02427             }
02428           textver[i] = ACE_OS::ace_isprint (c) ? c : '.';
02429         }
02430 
02431       for (i = size % 16; i < 16; i++)
02432         {
02433           ACE_OS::sprintf (obuf,
02434                            ACE_LIB_TEXT ("   "));
02435           obuf += 3;
02436           if (i == 7)
02437             {
02438               ACE_OS::sprintf (obuf,
02439                                ACE_LIB_TEXT (" "));
02440               obuf++;
02441             }
02442           textver[i] = ' ';
02443         }
02444 
02445       textver[i] = 0;
02446       ACE_OS::sprintf (obuf,
02447                        ACE_LIB_TEXT ("  %s\n"),
02448                        textver);
02449     }
02450   return size;
02451 }
02452 
02453 // Returns the current timestamp in the form
02454 // "hour:minute:second:microsecond."  The month, day, and year are
02455 // also stored in the beginning of the date_and_time array.
02456 
02457 ACE_TCHAR *
02458 ACE::timestamp (ACE_TCHAR date_and_time[],
02459                 int date_and_timelen,
02460                 int return_pointer_to_first_digit)
02461 {
02462   //ACE_TRACE ("ACE::timestamp");
02463 
02464   if (date_and_timelen < 35)
02465     {
02466       errno = EINVAL;
02467       return 0;
02468     }
02469 
02470 #if defined (WIN32)
02471   // Emulate Unix.  Win32 does NOT support all the UNIX versions
02472   // below, so DO we need this ifdef.
02473   static const ACE_TCHAR *day_of_week_name[] =
02474     {
02475       ACE_LIB_TEXT ("Sun"),
02476       ACE_LIB_TEXT ("Mon"),
02477       ACE_LIB_TEXT ("Tue"),
02478       ACE_LIB_TEXT ("Wed"),
02479       ACE_LIB_TEXT ("Thu"),
02480       ACE_LIB_TEXT ("Fri"),
02481       ACE_LIB_TEXT ("Sat")
02482     };
02483 
02484   static const ACE_TCHAR *month_name[] =
02485     {
02486       ACE_LIB_TEXT ("Jan"),
02487       ACE_LIB_TEXT ("Feb"),
02488       ACE_LIB_TEXT ("Mar"),
02489       ACE_LIB_TEXT ("Apr"),
02490       ACE_LIB_TEXT ("May"),
02491       ACE_LIB_TEXT ("Jun"),
02492       ACE_LIB_TEXT ("Jul"),
02493       ACE_LIB_TEXT ("Aug"),
02494       ACE_LIB_TEXT ("Sep"),
02495       ACE_LIB_TEXT ("Oct"),
02496       ACE_LIB_TEXT ("Nov"),
02497       ACE_LIB_TEXT ("Dec")
02498     };
02499 
02500   SYSTEMTIME local;
02501   ::GetLocalTime (&local);
02502 
02503   ACE_OS::sprintf (date_and_time,
02504                    ACE_LIB_TEXT ("%3s %3s %2d %04d %02d:%02d:%02d.%06d"),
02505                    day_of_week_name[local.wDayOfWeek],
02506                    month_name[local.wMonth - 1],
02507                    (int) local.wDay,
02508                    (int) local.wYear,
02509                    (int) local.wHour,
02510                    (int) local.wMinute,
02511                    (int) local.wSecond,
02512                    (int) (local.wMilliseconds * 1000));
02513   return &date_and_time[15 + (return_pointer_to_first_digit != 0)];
02514 #else  /* UNIX */
02515   ACE_TCHAR timebuf[26]; // This magic number is based on the ctime(3c) man page.
02516   ACE_Time_Value cur_time = ACE_OS::gettimeofday ();
02517   time_t secs = cur_time.sec ();
02518 
02519   ACE_OS::ctime_r (&secs,
02520                    timebuf,
02521                    sizeof timebuf);
02522   // date_and_timelen > sizeof timebuf!
02523   ACE_OS::strsncpy (date_and_time,
02524                     timebuf,
02525                     date_and_timelen);
02526   ACE_TCHAR yeartmp[5];
02527   ACE_OS::strsncpy (yeartmp,
02528                     &date_and_time[20],
02529                     5);
02530   ACE_TCHAR timetmp[9];
02531   ACE_OS::strsncpy (timetmp,
02532                     &date_and_time[11],
02533                     9);
02534   ACE_OS::sprintf (&date_and_time[11],
02535 #  if defined (ACE_USES_WCHAR)
02536                    ACE_LIB_TEXT ("%ls %ls.%06ld"),
02537 #  else
02538                    ACE_LIB_TEXT ("%s %s.%06ld"),
02539 #  endif /* ACE_USES_WCHAR */
02540                    yeartmp,
02541                    timetmp,
02542                    cur_time.usec ());
02543   date_and_time[33] = '\0';
02544   return &date_and_time[15 + (return_pointer_to_first_digit != 0)];
02545 #endif /* WIN32 */
02546 }
02547 
02548 // This function rounds the request to a multiple of the page size.
02549 
02550 size_t
02551 ACE::round_to_pagesize (off_t len)
02552 {
02553   ACE_TRACE ("ACE::round_to_pagesize");
02554 
02555   if (ACE::pagesize_ == 0)
02556     ACE::pagesize_ = ACE_OS::getpagesize ();
02557 
02558   return (len + (ACE::pagesize_ - 1)) & ~(ACE::pagesize_ - 1);
02559 }
02560 
02561 size_t
02562 ACE::round_to_allocation_granularity (off_t len)
02563 {
02564   ACE_TRACE ("ACE::round_to_allocation_granularity");
02565 
02566   if (ACE::allocation_granularity_ == 0)
02567     ACE::allocation_granularity_ = ACE_OS::allocation_granularity ();
02568 
02569   return (len + (ACE::allocation_granularity_ - 1)) & ~(ACE::allocation_granularity_ - 1);
02570 }
02571 
02572 ACE_HANDLE
02573 ACE::handle_timed_complete (ACE_HANDLE h,
02574                             const ACE_Time_Value *timeout,
02575                             int is_tli)
02576 {
02577   ACE_TRACE ("ACE::handle_timed_complete");
02578 
02579 #if !defined (ACE_WIN32) && defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02580 
02581   struct pollfd fds;
02582 
02583   fds.fd = h;
02584   fds.events = POLLIN | POLLOUT;
02585   fds.revents = 0;
02586 
02587 #else
02588   ACE_Handle_Set rd_handles;
02589   ACE_Handle_Set wr_handles;
02590 
02591   rd_handles.set_bit (h);
02592   wr_handles.set_bit (h);
02593 #endif /* !ACE_WIN32 && ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02594 
02595 #if defined (ACE_WIN32)
02596   // Winsock is different - it sets the exception bit for failed connect,
02597   // unlike other platforms, where the read bit is set.
02598   ACE_Handle_Set ex_handles;
02599   ex_handles.set_bit (h);
02600 #endif /* ACE_WIN32 */
02601 
02602   int need_to_check = 0;
02603   int known_failure = 0;
02604 
02605 #if defined (ACE_WIN32)
02606   int n = ACE_OS::select (0,    // Ignored on Windows: int (h) + 1,
02607                           0,
02608                           wr_handles,
02609                           ex_handles,
02610                           timeout);
02611 #else
02612 # if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02613 
02614   int n = ACE_OS::poll (&fds, 1, timeout);
02615 
02616 # else
02617   int n = ACE_OS::select (int (h) + 1,
02618                           rd_handles,
02619                           wr_handles,
02620                           0,
02621                           timeout);
02622 # endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02623 #endif /* ACE_WIN32 */
02624 
02625   // If we failed to connect within the time period allocated by the
02626   // caller, then we fail (e.g., the remote host might have been too
02627   // busy to accept our call).
02628   if (n <= 0)
02629     {
02630       if (n == 0 && timeout != 0)
02631         errno = ETIME;
02632       return ACE_INVALID_HANDLE;
02633     }
02634 
02635   // Usually, a ready-for-write handle is successfully connected, and
02636   // ready-for-read (exception on Win32) is a failure. On fails, we
02637   // need to grab the error code via getsockopt. On possible success for
02638   // any platform where we can't tell just from select() (e.g. AIX),
02639   // we also need to check for success/fail.
02640 #if defined (ACE_WIN32)
02641   ACE_UNUSED_ARG (is_tli);
02642 
02643   // On Win32, ex_handle set indicates a failure. We'll do the check
02644   // to try and get an errno value, but the connect failed regardless of
02645   // what getsockopt says about the error.
02646   if (ex_handles.is_set (h))
02647     {
02648       need_to_check = 1;
02649       known_failure = 1;
02650     }
02651 #elif defined (ACE_VXWORKS)
02652   ACE_UNUSED_ARG (is_tli);
02653 
02654   // Force the check on VxWorks.  The read handle for "h" is not set,
02655   // so "need_to_check" is false at this point.  The write handle is
02656   // set, for what it's worth.
02657   need_to_check = 1;
02658 #else
02659   if (is_tli)
02660 
02661 # if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02662     need_to_check = (fds.revents & POLLIN) && !(fds.revents & POLLOUT);
02663 # else
02664   need_to_check = rd_handles.is_set (h) && !wr_handles.is_set (h);
02665 # endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02666 
02667   else
02668 #if defined(AIX)
02669     // AIX is broken... both success and failed connect will set the
02670     // write handle only, so always check.
02671     need_to_check = 1;
02672 #else
02673 # if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02674   need_to_check = (fds.revents & POLLIN);
02675 # else
02676   need_to_check = rd_handles.is_set (h);
02677 # endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02678 #endif /* AIX */
02679 #endif /* ACE_WIN32 */
02680 
02681   if (need_to_check)
02682     {
02683 #if defined (SOL_SOCKET) && defined (SO_ERROR)
02684       int sock_err = 0;
02685       int sock_err_len = sizeof (sock_err);
02686       int sockopt_ret = ACE_OS::getsockopt (h, SOL_SOCKET, SO_ERROR,
02687                                             (char *)&sock_err, &sock_err_len);
02688       if (sockopt_ret < 0)
02689         {
02690           h = ACE_INVALID_HANDLE;
02691         }
02692 
02693       if (sock_err != 0 || known_failure)
02694         {
02695           h = ACE_INVALID_HANDLE;
02696           errno = sock_err;
02697         }
02698 #else
02699       char dummy;
02700 
02701       // The following recv() won't block provided that the
02702       // ACE_NONBLOCK flag has not been turned off .
02703       n = ACE::recv (h, &dummy, 1, MSG_PEEK);
02704 
02705       // If no data was read/peeked at, check to see if it's because
02706       // of a non-connected socket (and therefore an error) or there's
02707       // just no data yet.
02708       if (n <= 0)
02709         {
02710           if (n == 0)
02711             {
02712               errno = ECONNREFUSED;
02713               h = ACE_INVALID_HANDLE;
02714             }
02715           else if (errno != EWOULDBLOCK && errno != EAGAIN)
02716             h = ACE_INVALID_HANDLE;
02717         }
02718 #endif
02719     }
02720 
02721   // 1. The HANDLE is ready for writing and doesn't need to be checked or
02722   // 2. recv() returned an indication of the state of the socket - if there is
02723   // either data present, or a recv is legit but there's no data yet,
02724   // the connection was successfully established.
02725   return h;
02726 }
02727 
02728 // Wait up to <timeout> amount of time to accept a connection.
02729 
02730 int
02731 ACE::handle_timed_accept (ACE_HANDLE listener,
02732                           ACE_Time_Value *timeout,
02733                           int restart)
02734 {
02735   ACE_TRACE ("ACE::handle_timed_accept");
02736   // Make sure we don't bomb out on erroneous values.
02737   if (listener == ACE_INVALID_HANDLE)
02738     return -1;
02739 
02740 #if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02741 
02742   struct pollfd fds;
02743 
02744   fds.fd = listener;
02745   fds.events = POLLIN;
02746   fds.revents = 0;
02747 
02748 #else
02749   // Use the select() implementation rather than poll().
02750   ACE_Handle_Set rd_handle;
02751   rd_handle.set_bit (listener);
02752 #endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02753 
02754   // We need a loop here if <restart> is enabled.
02755 
02756   for (;;)
02757     {
02758 #if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
02759 
02760       int n = ACE_OS::poll (&fds, 1, timeout);
02761 
02762 #else
02763       int select_width;
02764 #  if defined (ACE_WIN32)
02765       // This arg is ignored on Windows and causes pointer truncation
02766       // warnings on 64-bit compiles.
02767       select_width = 0;
02768 #  else
02769       select_width = int (listener) + 1;
02770 #  endif /* ACE_WIN32 */
02771       int n = ACE_OS::select (select_width,
02772                               rd_handle, 0, 0,
02773                               timeout);
02774 #endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
02775 
02776       switch (n)
02777         {
02778         case -1:
02779           if (errno == EINTR && restart)
02780             continue;
02781           else
02782             return -1;
02783           /* NOTREACHED */
02784         case 0:
02785           if (timeout != 0
02786               && timeout->sec () == 0
02787               && timeout->usec () == 0)
02788             errno = EWOULDBLOCK;
02789           else
02790             errno = ETIMEDOUT;
02791           return -1;
02792           /* NOTREACHED */
02793         case 1:
02794           return 0;
02795           /* NOTREACHED */
02796         default:
02797           errno = EINVAL;
02798           return -1;
02799           /* NOTREACHED */
02800         }
02801     }
02802 }
02803 
02804 // Make the current process a UNIX daemon.  This is based on Stevens
02805 // code from APUE.
02806 
02807 int
02808 ACE::daemonize (const ACE_TCHAR pathname[],
02809                 int close_all_handles,
02810                 const ACE_TCHAR program_name[])
02811 {
02812   ACE_TRACE ("ACE::daemonize");
02813 #if !defined (ACE_LACKS_FORK)
02814   pid_t pid = ACE_OS::fork ();
02815 
02816   if (pid == -1)
02817     return -1;
02818   else if (pid != 0)
02819     ACE_OS::exit (0); // Parent exits.
02820 
02821   // 1st child continues.
02822   ACE_OS::setsid (); // Become session leader.
02823 
02824   ACE_OS::signal (SIGHUP, SIG_IGN);
02825 
02826   pid = ACE_OS::fork (program_name);
02827 
02828   if (pid != 0)
02829     ACE_OS::exit (0); // First child terminates.
02830 
02831   // Second child continues.
02832 
02833   if (pathname != 0)
02834     // change working directory.
02835     ACE_OS::chdir (pathname);
02836 
02837   ACE_OS::umask (0); // clear our file mode creation mask.
02838 
02839   // Close down the I/O handles.
02840   if (close_all_handles)
02841     for (int i = ACE::max_handles () - 1; i >= 0; i--)
02842       ACE_OS::close (i);
02843 
02844   return 0;
02845 #else
02846   ACE_UNUSED_ARG (pathname);
02847   ACE_UNUSED_ARG (close_all_handles);
02848   ACE_UNUSED_ARG (program_name);
02849 
02850   ACE_NOTSUP_RETURN (-1);
02851 #endif /* ACE_LACKS_FORK */
02852 }
02853 
02854 pid_t
02855 ACE::fork (const ACE_TCHAR *program_name,
02856            int avoid_zombies)
02857 {
02858   if (avoid_zombies == 0)
02859     return ACE_OS::fork (program_name);
02860   else
02861     {
02862       // This algorithm is adapted from an example in the Stevens book
02863       // "Advanced Programming in the Unix Environment" and an item in
02864       // Andrew Gierth's Unix Programming FAQ.  It creates an orphan
02865       // process that's inherited by the init process; init cleans up
02866       // when the orphan process terminates.
02867       //
02868       // Another way to avoid zombies is to ignore or catch the
02869       // SIGCHLD signal; we don't use that approach here.
02870 
02871       pid_t pid = ACE_OS::fork ();
02872       if (pid == 0)
02873         {
02874           // The child process forks again to create a grandchild.
02875           switch (ACE_OS::fork (program_name))
02876             {
02877             case 0: // grandchild returns 0.
02878               return 0;
02879             case -1: // assumes all errnos are < 256
02880               ACE_OS::_exit (errno);
02881             default:  // child terminates, orphaning grandchild
02882               ACE_OS::_exit (0);
02883             }
02884         }
02885 
02886       // Parent process waits for child to terminate.
02887 #if defined (ACE_HAS_UNION_WAIT)
02888       union wait status;
02889       if (pid < 0 || ACE_OS::waitpid (pid, &(status.w_status), 0) < 0)
02890 #else
02891         ACE_exitcode status;
02892       if (pid < 0 || ACE_OS::waitpid (pid, &status, 0) < 0)
02893 #endif /* ACE_HAS_UNION_WAIT */
02894         return -1;
02895 
02896       // child terminated by calling exit()?
02897       if (WIFEXITED ((status)))
02898         {
02899           // child terminated normally?
02900           if (WEXITSTATUS ((status)) == 0)
02901             return 1;
02902           else
02903             errno = WEXITSTATUS ((status));
02904         }
02905       else
02906         // child didn't call exit(); perhaps it received a signal?
02907         errno = EINTR;
02908 
02909       return -1;
02910     }
02911 }
02912 
02913 int
02914 ACE::max_handles (void)
02915 {
02916   ACE_TRACE ("ACE::max_handles");
02917 #if defined (RLIMIT_NOFILE) && !defined (ACE_LACKS_RLIMIT)
02918   rlimit rl;
02919   int r = ACE_OS::getrlimit (RLIMIT_NOFILE, &rl);
02920 # if !defined (RLIM_INFINITY)
02921   if (r == 0)
02922     return rl.rlim_cur;
02923 #else
02924   if (r == 0 && rl.rlim_cur != RLIM_INFINITY)
02925     return rl.rlim_cur;
02926   // If == RLIM_INFINITY, fall through to the ACE_LACKS_RLIMIT sections
02927 # endif /* RLIM_INFINITY */
02928 #endif /* RLIMIT_NOFILE && !ACE_LACKS_RLIMIT */
02929 
02930 #if defined (_SC_OPEN_MAX)
02931   return ACE_OS::sysconf (_SC_OPEN_MAX);
02932 #elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620)
02933   return maxFiles;
02934 #elif defined (FD_SETSIZE)
02935   return FD_SETSIZE;
02936 #else
02937   ACE_NOTSUP_RETURN (-1);
02938 #endif /* _SC_OPEN_MAX */
02939 }
02940 
02941 // Set the number of currently open handles in the process.
02942 //
02943 // If NEW_LIMIT == -1 set the limit to the maximum allowable.
02944 // Otherwise, set it to be the value of NEW_LIMIT.
02945 
02946 int
02947 ACE::set_handle_limit (int new_limit,
02948                        int increase_limit_only)
02949 {
02950   ACE_TRACE ("ACE::set_handle_limit");
02951   int cur_limit = ACE::max_handles ();
02952   int max_limit = cur_limit;
02953 
02954   if (cur_limit == -1)
02955     return -1;
02956 
02957 #if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE)
02958   struct rlimit rl;
02959 
02960   ACE_OS::memset ((void *) &rl, 0, sizeof rl);
02961   int r = ACE_OS::getrlimit (RLIMIT_NOFILE, &rl);
02962   if (r == 0)
02963     max_limit = rl.rlim_max;
02964 #endif /* ACE_LACKS_RLIMIT */
02965 
02966   if (new_limit == -1)
02967     new_limit = max_limit;
02968 
02969   if (new_limit < 0)
02970     {
02971       errno = EINVAL;
02972       return -1;
02973     }
02974   else if (new_limit > cur_limit)
02975     {
02976       // Increase the limit.
02977 #if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE)
02978       rl.rlim_cur = new_limit;
02979       return ACE_OS::setrlimit (RLIMIT_NOFILE, &rl);
02980 #else
02981       // Must return EINVAL errno.
02982       ACE_NOTSUP_RETURN (-1);
02983 #endif /* ACE_LACKS_RLIMIT */
02984     }
02985   else if (increase_limit_only == 0)
02986     {
02987       // Decrease the limit.
02988 #if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE)
02989       rl.rlim_cur = new_limit;
02990       return ACE_OS::setrlimit (RLIMIT_NOFILE, &rl);
02991 #else
02992       // We give a chance to platforms without RLIMIT to work.
02993       // Instead of ACE_NOTSUP_RETURN (0), just return 0 because
02994       // new_limit is <= cur_limit, so it's a no-op.
02995       return 0;
02996 #endif /* ACE_LACKS_RLIMIT */
02997     }
02998 
02999   return 0;
03000 }
03001 
03002 int
03003 ACE::map_errno (int error)
03004 {
03005   switch (error)
03006     {
03007 #if defined (ACE_WIN32)
03008     case WSAEWOULDBLOCK:
03009       return EAGAIN; // Same as UNIX errno EWOULDBLOCK.
03010 #endif /* ACE_WIN32 */
03011     }
03012 
03013   return error;
03014 }
03015 
03016 // Euclid's greatest common divisor algorithm.
03017 u_long
03018 ACE::gcd (u_long x, u_long y)
03019 {
03020   while (y != 0)
03021     {
03022       u_long r = x % y;
03023       x = y;
03024       y = r;
03025     }
03026 
03027   return x;
03028 }
03029 
03030 
03031 // Calculates the minimum enclosing frame size for the given values.
03032 u_long
03033 ACE::minimum_frame_size (u_long period1, u_long period2)
03034 {
03035   // if one of the periods is zero, treat it as though it as
03036   // uninitialized and return the other period as the frame size
03037   if (0 == period1)
03038     {
03039       return period2;
03040     }
03041   if (0 == period2)
03042     {
03043       return period1;
03044     }
03045 
03046   // if neither is zero, find the greatest common divisor of the two periods
03047   u_long greatest_common_divisor = ACE::gcd (period1, period2);
03048 
03049   // explicitly consider cases to reduce risk of possible overflow errors
03050   if (greatest_common_divisor == 1)
03051     {
03052       // periods are relative primes: just multiply them together
03053       return period1 * period2;
03054     }
03055   else if (greatest_common_divisor == period1)
03056     {
03057       // the first period divides the second: return the second
03058       return period2;
03059     }
03060   else if (greatest_common_divisor == period2)
03061     {
03062       // the second period divides the first: return the first
03063       return period1;
03064     }
03065   else
03066     {
03067       // the current frame size and the entry's effective period
03068       // have a non-trivial greatest common divisor: return the
03069       // product of factors divided by those in their gcd.
03070       return (period1 * period2) / greatest_common_divisor;
03071     }
03072 }
03073 
03074 
03075 u_long
03076 ACE::is_prime (const u_long n,
03077                const u_long min_factor,
03078                const u_long max_factor)
03079 {
03080   if (n > 3)
03081     for (u_long factor = min_factor;
03082          factor <= max_factor;
03083          ++factor)
03084       if (n / factor * factor == n)
03085         return factor;
03086 
03087   return 0;
03088 }
03089 
03090 const ACE_TCHAR *
03091 ACE::sock_error (int error)
03092 {
03093 #if defined (ACE_WIN32)
03094   static ACE_TCHAR unknown_msg[64];
03095 
03096   switch (error)
03097     {
03098     case WSAVERNOTSUPPORTED:
03099       return ACE_LIB_TEXT ("version of WinSock not supported");
03100       /* NOTREACHED */
03101     case WSASYSNOTREADY:
03102       return ACE_LIB_TEXT ("WinSock not present or not responding");
03103       /* NOTREACHED */
03104     case WSAEINVAL:
03105       return ACE_LIB_TEXT ("app version not supported by DLL");
03106       /* NOTREACHED */
03107     case WSAHOST_NOT_FOUND:
03108       return ACE_LIB_TEXT ("Authoritive: Host not found");
03109       /* NOTREACHED */
03110     case WSATRY_AGAIN:
03111       return ACE_LIB_TEXT ("Non-authoritive: host not found or server failure");
03112       /* NOTREACHED */
03113     case WSANO_RECOVERY:
03114       return ACE_LIB_TEXT ("Non-recoverable: refused or not implemented");
03115       /* NOTREACHED */
03116     case WSANO_DATA:
03117       return ACE_LIB_TEXT ("Valid name, no data record for type");
03118       /* NOTREACHED */
03119       /*
03120         case WSANO_ADDRESS:
03121         return "Valid name, no MX record";
03122       */
03123     case WSANOTINITIALISED:
03124       return ACE_LIB_TEXT ("WSA Startup not initialized");
03125       /* NOTREACHED */
03126     case WSAENETDOWN:
03127       return ACE_LIB_TEXT ("Network subsystem failed");
03128       /* NOTREACHED */
03129     case WSAEINPROGRESS:
03130       return ACE_LIB_TEXT ("Blocking operation in progress");
03131       /* NOTREACHED */
03132     case WSAEINTR:
03133       return ACE_LIB_TEXT ("Blocking call cancelled");
03134       /* NOTREACHED */
03135     case WSAEAFNOSUPPORT:
03136       return ACE_LIB_TEXT ("address family not supported");
03137       /* NOTREACHED */
03138     case WSAEMFILE:
03139       return ACE_LIB_TEXT ("no file handles available");
03140       /* NOTREACHED */
03141     case WSAENOBUFS:
03142       return ACE_LIB_TEXT ("no buffer space available");
03143       /* NOTREACHED */
03144     case WSAEPROTONOSUPPORT:
03145       return ACE_LIB_TEXT ("specified protocol not supported");
03146       /* NOTREACHED */
03147     case WSAEPROTOTYPE:
03148       return ACE_LIB_TEXT ("protocol wrong type for this socket");
03149       /* NOTREACHED */
03150     case WSAESOCKTNOSUPPORT:
03151       return ACE_LIB_TEXT ("socket type not supported for address family");
03152       /* NOTREACHED */
03153     case WSAENOTSOCK:
03154       return ACE_LIB_TEXT ("handle is not a socket");
03155       /* NOTREACHED */
03156     case WSAEWOULDBLOCK:
03157       return ACE_LIB_TEXT ("resource temporarily unavailable");
03158       /* NOTREACHED */
03159     case WSAEADDRINUSE:
03160       return ACE_LIB_TEXT ("address already in use");
03161       /* NOTREACHED */
03162     case WSAECONNABORTED:
03163       return ACE_LIB_TEXT ("connection aborted");
03164       /* NOTREACHED */
03165     case WSAECONNRESET:
03166       return ACE_LIB_TEXT ("connection reset");
03167       /* NOTREACHED */
03168     case WSAENOTCONN:
03169       return ACE_LIB_TEXT ("not connected");
03170       /* NOTREACHED */
03171     case WSAETIMEDOUT:
03172       return ACE_LIB_TEXT ("connection timed out");
03173       /* NOTREACHED */
03174     case WSAECONNREFUSED:
03175       return ACE_LIB_TEXT ("connection refused");
03176       /* NOTREACHED */
03177     case WSAEHOSTDOWN:
03178       return ACE_LIB_TEXT ("host down");
03179       /* NOTREACHED */
03180     case WSAEHOSTUNREACH:
03181       return ACE_LIB_TEXT ("host unreachable");
03182       /* NOTREACHED */
03183     case WSAEADDRNOTAVAIL:
03184       return ACE_LIB_TEXT ("address not available");
03185       /* NOTREACHED */
03186     case WSAEISCONN:
03187       return ACE_LIB_TEXT ("socket is already connected");
03188       /* NOTREACHED */
03189     case WSAENETRESET:
03190       return ACE_LIB_TEXT ("network dropped connection on reset");
03191       /* NOTREACHED */
03192     case WSAEMSGSIZE:
03193       return ACE_LIB_TEXT ("message too long");
03194       /* NOTREACHED */
03195     case WSAENETUNREACH:
03196       return ACE_LIB_TEXT ("network is unreachable");
03197       /* NOTREACHED */
03198     case WSAEFAULT:
03199       return ACE_LIB_TEXT ("bad address");
03200       /* NOTREACHED */
03201     case WSAEDISCON:
03202       return ACE_LIB_TEXT ("graceful shutdown in progress");
03203       /* NOTREACHED */
03204     case WSAEACCES:
03205       return ACE_LIB_TEXT ("permission denied");
03206       /* NOTREACHED */
03207     case WSAESHUTDOWN:
03208       return ACE_LIB_TEXT ("cannot send after socket shutdown");
03209       /* NOTREACHED */
03210     case WSAEPROCLIM:
03211       return ACE_LIB_TEXT ("too many processes");
03212       /* NOTREACHED */
03213     case WSAEALREADY:
03214       return ACE_LIB_TEXT ("operation already in progress");
03215       /* NOTREACHED */
03216     case WSAEPFNOSUPPORT:
03217       return ACE_LIB_TEXT ("protocol family not supported");
03218       /* NOTREACHED */
03219     case WSAENOPROTOOPT:
03220       return ACE_LIB_TEXT ("bad protocol option");
03221       /* NOTREACHED */
03222     case WSATYPE_NOT_FOUND:
03223       return ACE_LIB_TEXT ("class type not found");
03224       /* NOTREACHED */
03225     case WSAEOPNOTSUPP:
03226       return ACE_LIB_TEXT ("operation not supported");
03227       /* NOTREACHED */
03228     case WSAEDESTADDRREQ:
03229       return ACE_LIB_TEXT ("destination address required");
03230       /* NOTREACHED */
03231     default:
03232       ACE_OS::sprintf (unknown_msg, ACE_LIB_TEXT ("unknown error: %d"), error);
03233       return unknown_msg;
03234       /* NOTREACHED */
03235     }
03236 #else
03237   ACE_UNUSED_ARG (error);
03238   ACE_NOTSUP_RETURN (0);
03239 #endif /* ACE_WIN32 */
03240 }
03241 
03242 bool
03243 ACE::is_sock_error (int error)
03244 {
03245 #if defined (ACE_WIN32)
03246   switch (error)
03247     {
03248     case WSAVERNOTSUPPORTED:
03249     case WSASYSNOTREADY:
03250     case WSAEINVAL:
03251     case WSAHOST_NOT_FOUND:
03252     case WSATRY_AGAIN:
03253     case WSANO_RECOVERY:
03254     case WSANO_DATA:
03255       /*
03256         case WSANO_ADDRESS:
03257       */
03258     case WSANOTINITIALISED:
03259     case WSAENETDOWN:
03260     case WSAEINPROGRESS:
03261     case WSAEINTR:
03262     case WSAEAFNOSUPPORT:
03263     case WSAEMFILE:
03264     case WSAENOBUFS:
03265     case WSAEPROTONOSUPPORT:
03266     case WSAEPROTOTYPE:
03267     case WSAESOCKTNOSUPPORT:
03268     case WSAENOTSOCK:
03269     case WSAEWOULDBLOCK:
03270     case WSAEADDRINUSE:
03271     case WSAECONNABORTED:
03272     case WSAECONNRESET:
03273     case WSAENOTCONN:
03274     case WSAETIMEDOUT:
03275     case WSAECONNREFUSED:
03276     case WSAEHOSTDOWN:
03277     case WSAEHOSTUNREACH:
03278     case WSAEADDRNOTAVAIL:
03279     case WSAEISCONN:
03280     case WSAENETRESET:
03281     case WSAEMSGSIZE:
03282     case WSAENETUNREACH:
03283     case WSAEFAULT:
03284     case WSAEDISCON:
03285     case WSAEACCES:
03286     case WSAESHUTDOWN:
03287     case WSAEPROCLIM:
03288     case WSAEALREADY:
03289     case WSAEPFNOSUPPORT:
03290     case WSAENOPROTOOPT:
03291     case WSATYPE_NOT_FOUND:
03292     case WSAEOPNOTSUPP:
03293       return true;
03294     }
03295 #else
03296   ACE_UNUSED_ARG (error);
03297 #endif /* ACE_WIN32 */
03298   return false;
03299 }
03300 
03301 char *
03302 ACE::strndup (const char *str, size_t n)
03303 {
03304   const char *t = str;
03305   size_t len;
03306 
03307   // Figure out how long this string is (remember, it might not be
03308   // NUL-terminated).
03309 
03310   for (len = 0;
03311        len < n && *t++ != '\0';
03312        len++)
03313     continue;
03314 
03315   char *s;
03316   ACE_ALLOCATOR_RETURN (s,
03317                         (char *) ACE_OS::malloc (len + 1),
03318                         0);
03319   return ACE_OS::strsncpy (s, str, len + 1);
03320 }
03321 
03322 #if defined (ACE_HAS_WCHAR)
03323 wchar_t *
03324 ACE::strndup (const wchar_t *str, size_t n)
03325 {
03326   const wchar_t *t = str;
03327   size_t len;
03328 
03329   // Figure out how long this string is (remember, it might not be
03330   // NUL-terminated).
03331 
03332   for (len = 0;
03333        len < n && *t++ != '\0';
03334        len++)
03335     continue;
03336 
03337   wchar_t *s;
03338   ACE_ALLOCATOR_RETURN (s,
03339                         static_cast<wchar_t *> (
03340             ACE_OS::malloc ((len + 1) * sizeof (wchar_t))),
03341                         0);
03342   return ACE_OS::strsncpy (s, str, len + 1);
03343 }
03344 #endif /* ACE_HAS_WCHAR */
03345 
03346 char *
03347 ACE::strnnew (const char *str, size_t n)
03348 {
03349   const char *t = str;
03350   size_t len;
03351 
03352   // Figure out how long this string is (remember, it might not be
03353   // NUL-terminated).
03354 
03355   for (len = 0;
03356        len < n && *t++ != L'\0';
03357        len++)
03358     continue;
03359 
03360   char *s;
03361   ACE_NEW_RETURN (s,
03362                   char[len + 1],
03363                   0);
03364   return ACE_OS::strsncpy (s, str, len + 1);
03365 }
03366 
03367 #if defined (ACE_HAS_WCHAR)
03368 wchar_t *
03369 ACE::strnnew (const wchar_t *str, size_t n)
03370 {
03371   const wchar_t *t = str;
03372   size_t len;
03373 
03374   // Figure out how long this string is (remember, it might not be
03375   // NUL-terminated).
03376 
03377   for (len = 0;
03378        len < n && *t++ != ACE_TEXT_WIDE ('\0');
03379        len++)
03380     continue;
03381 
03382   wchar_t *s;
03383   ACE_NEW_RETURN (s,
03384                   wchar_t[len + 1],
03385                   0);
03386   return ACE_OS::strsncpy (s, str, len + 1);
03387 }
03388 #endif /* ACE_HAS_WCHAR */
03389 
03390 const char *
03391 ACE::strend (const char *s)
03392 {
03393   while (*s++ != '\0')
03394     continue;
03395 
03396   return s;
03397 }
03398 
03399 #if defined ACE_HAS_WCHAR
03400 const wchar_t *
03401 ACE::strend (const wchar_t *s)
03402 {
03403   while (*s++ != ACE_TEXT_WIDE ('\0'))
03404     continue;
03405 
03406   return s;
03407 }
03408 #endif
03409 
03410 char *
03411 ACE::strnew (const char *s)
03412 {
03413   if (s == 0)
03414     return 0;
03415   char *t = 0;
03416   ACE_NEW_RETURN (t,
03417                   char [::strlen (s) + 1],
03418                   0);
03419   if (t == 0)
03420     return 0;
03421   else
03422     return ACE_OS::strcpy (t, s);
03423 }
03424 
03425 #if defined (ACE_HAS_WCHAR)
03426 wchar_t *
03427 ACE::strnew (const wchar_t *s)
03428 {
03429   if (s == 0)
03430     return 0;
03431   wchar_t *t = 0;
03432   ACE_NEW_RETURN (t,
03433                   wchar_t[ACE_OS::strlen (s) + 1],
03434                   0);
03435   if (t == 0)
03436     return 0;
03437   else
03438     return ACE_OS::strcpy (t, s);
03439 }
03440 #endif /* ACE_HAS_WCHAR */
03441 
03442 inline static bool equal_char(char a, char b, bool case_sensitive)
03443 {
03444   if (case_sensitive)
03445     return a == b;
03446   return ACE_OS::ace_tolower(a) == ACE_OS::ace_tolower(b);
03447 }
03448 
03449 bool
03450 ACE::wild_match(const char* str, const char* pat, bool case_sensitive)
03451 {
03452   if (str == pat)
03453     return true;
03454   if (pat == 0 || str == 0)
03455     return false;
03456 
03457   bool star = false;
03458   const char* s = str;
03459   const char* p = pat;
03460   while (*s != '\0')
03461     {
03462       if (*p == '*')
03463   {
03464     star = true;
03465     pat = p;
03466     while (*++pat == '*');
03467 
03468     if (*pat == '\0')
03469       return true;
03470     p = pat;
03471   }
03472       else if (*p == '?')
03473   {
03474     ++s;
03475     ++p;
03476   }
03477       else if (! equal_char(*s, *p, case_sensitive))
03478   {
03479     if (!star)
03480       return false;
03481     s = ++str;
03482     p = pat;
03483   }
03484       else
03485   {
03486     ++s;
03487     ++p;
03488   }
03489     }
03490   if (*p == '*')
03491     while (*++p == '*');
03492 
03493   return *p == '\0';
03494 }
03495 
03496 // Close versioned namespace, if enabled by the user.
03497 ACE_END_VERSIONED_NAMESPACE_DECL

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