ACE.cpp

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

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