OS_NS_sys_uio.cpp

Go to the documentation of this file.
00001 // OS_NS_sys_uio.cpp,v 1.9 2005/10/28 16:14:54 ossama Exp
00002 
00003 #include "ace/OS_NS_sys_uio.h"
00004 
00005 ACE_RCSID(ace, OS_NS_sys_uio, "OS_NS_sys_uio.cpp,v 1.9 2005/10/28 16:14:54 ossama Exp")
00006 
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_sys_uio.inl"
00009 #endif /* ACE_HAS_INLINED_OS_CALLS */
00010 
00011 #include "ace/OS_Memory.h"
00012 #include "ace/OS_NS_string.h"
00013 #include "ace/OS_NS_unistd.h"
00014 
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 # if defined (ACE_LACKS_READV)
00018 
00019 // "Fake" readv for operating systems without it.  Note that this is
00020 // thread-safe.
00021 
00022 ssize_t
00023 ACE_OS::readv_emulation (ACE_HANDLE handle,
00024                          const iovec *iov,
00025                          int n)
00026 {
00027   ACE_OS_TRACE ("ACE_OS::readv_emulation");
00028 
00029   // In case there's a single element, skip the memcpy.
00030   if (1 == n)
00031     return ACE_OS::read (handle, iov[0].iov_base, iov[0].iov_len);
00032 
00033   ssize_t length = 0;
00034   int i;
00035 
00036   for (i = 0; i < n; ++i)
00037     if (static_cast<int> (iov[i].iov_len) < 0)
00038       return -1;
00039     else
00040       length += iov[i].iov_len;
00041 
00042   char *buf;
00043 #   if defined (ACE_HAS_ALLOCA)
00044   buf = (char *) alloca (length);
00045 #   else
00046   ACE_NEW_RETURN (buf,
00047                   char[length],
00048                   -1);
00049 #   endif /* !defined (ACE_HAS_ALLOCA) */
00050 
00051   length = ACE_OS::read (handle, buf, length);
00052 
00053   if (length != -1)
00054     {
00055       char *ptr = buf;
00056       ssize_t copyn = length;
00057 
00058       for (i = 0;
00059            i < n && copyn > 0;
00060            ++i)
00061         {
00062           ACE_OS::memcpy (iov[i].iov_base, ptr,
00063                           // iov_len is int on some platforms, size_t on others
00064                           copyn > (int) iov[i].iov_len
00065                             ? (size_t) iov[i].iov_len
00066                             : (size_t) copyn);
00067           ptr += iov[i].iov_len;
00068           copyn -= iov[i].iov_len;
00069         }
00070     }
00071 
00072 #   if !defined (ACE_HAS_ALLOCA)
00073   delete [] buf;
00074 #   endif /* !defined (ACE_HAS_ALLOCA) */
00075   return length;
00076 }
00077 # endif /* ACE_LACKS_READV */
00078 
00079 # if defined (ACE_LACKS_WRITEV)
00080 
00081 // "Fake" writev for operating systems without it.  Note that this is
00082 // thread-safe.
00083 
00084 ssize_t
00085 ACE_OS::writev_emulation (ACE_HANDLE handle, const iovec *iov, int n)
00086 {
00087   ACE_OS_TRACE ("ACE_OS::writev_emulation");
00088 
00089   // To avoid having to allocate a temporary buffer to which all of
00090   // the data will be copied and then written, this implementation
00091   // performs incremental writes.
00092 
00093   ssize_t bytes_sent = 0;
00094 
00095   for (int i = 0; i < n; ++i)
00096     {
00097       const ssize_t result =
00098         ACE_OS::write (handle, iov[i].iov_base, iov[i].iov_len);
00099 
00100       if (result == -1)
00101         {
00102           // There is a subtle difference in behaviour depending on
00103           // whether or not any data was sent.  If no data was sent,
00104           // then always return -1.  Otherwise return bytes_sent.
00105           // This gives the caller an opportunity to keep track of
00106           // bytes that have already been sent.
00107           if (bytes_sent > 0)
00108             break;
00109           else
00110             return -1;
00111         }
00112       else
00113         {
00114           bytes_sent += result;
00115 
00116           // Do not continue on to the next loop iteration if the
00117           // amount of data sent was less than the amount data given.
00118           // This avoids a subtle problem where "holes" in the data
00119           // stream would occur if partial sends of a given buffer in
00120           // the iovec array occured.
00121           if (static_cast<size_t> (result) < iov[i].iov_len)
00122             break;
00123         }
00124     }
00125 
00126   return bytes_sent;
00127 }
00128 # endif /* ACE_LACKS_WRITEV */
00129 
00130 ACE_END_VERSIONED_NAMESPACE_DECL

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