ACE.cpp

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

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