1 // $Id: OS_NS_sys_uio.cpp 81756 2008-05-22 09:47:33Z johnnyw $
3 #include "ace/OS_NS_sys_uio.h"
5 ACE_RCSID(ace
, OS_NS_sys_uio
, "$Id: OS_NS_sys_uio.cpp 81756 2008-05-22 09:47:33Z johnnyw $")
7 #if !defined (ACE_HAS_INLINED_OSCALLS)
8 # include "ace/OS_NS_sys_uio.inl"
9 #endif /* ACE_HAS_INLINED_OSCALLS */
11 #include "ace/OS_Memory.h"
12 #include "ace/OS_NS_string.h"
13 #include "ace/OS_NS_unistd.h"
15 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 # if defined (ACE_LACKS_READV)
19 // "Fake" readv for operating systems without it. Note that this is
23 ACE_OS::readv_emulation (ACE_HANDLE handle
,
27 ACE_OS_TRACE ("ACE_OS::readv_emulation");
29 // In case there's a single element, skip the memcpy.
31 return ACE_OS::read (handle
, iov
[0].iov_base
, iov
[0].iov_len
);
36 for (i
= 0; i
< n
; ++i
)
37 if (static_cast<int> (iov
[i
].iov_len
) < 0)
40 length
+= iov
[i
].iov_len
;
43 # if defined (ACE_HAS_ALLOCA)
44 buf
= (char *) alloca (length
);
49 # endif /* !defined (ACE_HAS_ALLOCA) */
51 length
= ACE_OS::read (handle
, buf
, length
);
56 ssize_t copyn
= length
;
62 ACE_OS::memcpy (iov
[i
].iov_base
, ptr
,
63 // iov_len is int on some platforms, size_t on others
64 copyn
> (int) iov
[i
].iov_len
65 ? (size_t) iov
[i
].iov_len
67 ptr
+= iov
[i
].iov_len
;
68 copyn
-= iov
[i
].iov_len
;
72 # if !defined (ACE_HAS_ALLOCA)
74 # endif /* !defined (ACE_HAS_ALLOCA) */
77 # endif /* ACE_LACKS_READV */
79 # if defined (ACE_LACKS_WRITEV)
81 // "Fake" writev for operating systems without it. Note that this is
85 ACE_OS::writev_emulation (ACE_HANDLE handle
, const iovec
*iov
, int n
)
87 ACE_OS_TRACE ("ACE_OS::writev_emulation");
89 // To avoid having to allocate a temporary buffer to which all of
90 // the data will be copied and then written, this implementation
91 // performs incremental writes.
93 ssize_t bytes_sent
= 0;
95 for (int i
= 0; i
< n
; ++i
)
97 ssize_t
const result
=
98 ACE_OS::write (handle
, iov
[i
].iov_base
, iov
[i
].iov_len
);
102 // There is a subtle difference in behaviour depending on
103 // whether or not any data was sent. If no data was sent,
104 // then always return -1. Otherwise return bytes_sent.
105 // This gives the caller an opportunity to keep track of
106 // bytes that have already been sent.
114 bytes_sent
+= result
;
116 // Do not continue on to the next loop iteration if the
117 // amount of data sent was less than the amount data given.
118 // This avoids a subtle problem where "holes" in the data
119 // stream would occur if partial sends of a given buffer in
120 // the iovec array occured.
121 if (static_cast<size_t> (result
) < iov
[i
].iov_len
)
128 # endif /* ACE_LACKS_WRITEV */
130 ACE_END_VERSIONED_NAMESPACE_DECL