Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE.cpp

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

Generated on Mon Jun 16 11:19:01 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002