Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / OS_NS_sys_socket.cpp
blob0661b44b2b5c2ed5d0b511bed0a75690c8c95bb3
1 #include "ace/OS_NS_sys_socket.h"
3 #if !defined (ACE_HAS_INLINED_OSCALLS)
4 # include "ace/OS_NS_sys_socket.inl"
5 #endif /* ACE_HAS_INLINED_OSCALLS */
7 #include "ace/Containers_T.h"
9 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
11 #if defined (ACE_WIN32)
12 int ACE_OS::socket_initialized_;
13 #endif /* ACE_WIN32 */
15 ACE_HANDLE
16 ACE_OS::accept (ACE_HANDLE handle,
17 struct sockaddr *addr,
18 int *addrlen,
19 const ACE_Accept_QoS_Params &qos_params)
21 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
22 ACE_SOCKCALL_RETURN (::WSAAccept ((ACE_SOCKET) handle,
23 addr,
24 (ACE_SOCKET_LEN *) addrlen,
25 (LPCONDITIONPROC) qos_params.qos_condition_callback (),
26 qos_params.callback_data ()),
27 ACE_HANDLE,
28 ACE_INVALID_HANDLE);
29 # else
30 ACE_UNUSED_ARG (qos_params);
31 return ACE_OS::accept (handle,
32 addr,
33 addrlen);
34 # endif /* ACE_HAS_WINSOCK2 */
37 int
38 ACE_OS::connect (ACE_HANDLE handle,
39 const sockaddr *addr,
40 int addrlen,
41 const ACE_QoS_Params &qos_params)
43 ACE_OS_TRACE ("ACE_OS::connect");
44 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
45 ACE_SOCKCALL_RETURN (::WSAConnect ((ACE_SOCKET) handle,
46 (const sockaddr *) addr,
47 (ACE_SOCKET_LEN) addrlen,
48 (WSABUF *) qos_params.caller_data (),
49 (WSABUF *) qos_params.callee_data (),
50 (QOS *) qos_params.socket_qos (),
51 (QOS *) qos_params.group_socket_qos ()),
52 int, -1);
53 # else
54 ACE_UNUSED_ARG (qos_params);
55 return ACE_OS::connect (handle,
56 const_cast <sockaddr *> (addr),
57 addrlen);
58 # endif /* ACE_HAS_WINSOCK2 */
61 ACE_HANDLE
62 ACE_OS::join_leaf (ACE_HANDLE socket,
63 const sockaddr *name,
64 int namelen,
65 const ACE_QoS_Params &qos_params)
67 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
69 QOS qos;
70 // Construct the WinSock2 QOS structure.
72 qos.SendingFlowspec = *(qos_params.socket_qos ()->sending_flowspec ());
73 qos.ReceivingFlowspec = *(qos_params.socket_qos ()->receiving_flowspec ());
74 qos.ProviderSpecific = (WSABUF) qos_params.socket_qos ()->provider_specific ();
76 ACE_SOCKCALL_RETURN (::WSAJoinLeaf ((ACE_SOCKET) socket,
77 name,
78 namelen,
79 (WSABUF *) qos_params.caller_data (),
80 (WSABUF *) qos_params.callee_data (),
81 &qos,
82 (QOS *) qos_params.group_socket_qos (),
83 qos_params.flags ()),
84 ACE_HANDLE,
85 ACE_INVALID_HANDLE);
87 # else
88 ACE_UNUSED_ARG (socket);
89 ACE_UNUSED_ARG (name);
90 ACE_UNUSED_ARG (namelen);
91 ACE_UNUSED_ARG (qos_params);
92 ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE);
93 # endif /* ACE_HAS_WINSOCK2 */
96 int
97 ACE_OS::socket_init (int version_high, int version_low)
99 # if defined (ACE_WIN32) && !defined(ACE_DONT_INIT_WINSOCK)
100 if (ACE_OS::socket_initialized_ == 0)
102 WORD version_requested = MAKEWORD (version_high, version_low);
103 WSADATA wsa_data;
104 int error = WSAStartup (version_requested, &wsa_data);
106 if (error != 0)
108 ACE_OS::fprintf (stderr,
109 "ACE_OS::socket_init; WSAStartup failed, "
110 "WSAGetLastError returned %d\n",
111 error);
114 ACE_OS::socket_initialized_ = 1;
116 # else
117 ACE_UNUSED_ARG (version_high);
118 ACE_UNUSED_ARG (version_low);
119 # endif /* ACE_WIN32 */
120 return 0;
124 ACE_OS::socket_fini ()
126 # if defined (ACE_WIN32)
127 if (ACE_OS::socket_initialized_ != 0)
129 if (WSACleanup () != 0)
131 int error = ::WSAGetLastError ();
132 ACE_OS::fprintf (stderr,
133 "ACE_OS::socket_fini; WSACleanup failed, "
134 "WSAGetLastError returned %d\n",
135 error);
137 ACE_OS::socket_initialized_ = 0;
139 # endif /* ACE_WIN32 */
140 return 0;
143 ssize_t
144 ACE_OS::sendv_partial_i (ACE_HANDLE handle,
145 const iovec *buffers,
146 int n)
148 // the divide and conquer logic should remain consistent
149 // with send_partial_i
150 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
151 DWORD bytes_sent = 0;
152 int result = 1;
153 int simulated_n = n;
154 ACE_UINT64 buffer_size = 0;
155 ACE_Array<iovec> iovec_array(simulated_n);
156 int i = 0;
157 for ( ; i < simulated_n; ++i)
159 iovec_array[i].iov_base = buffers[i].iov_base;
160 iovec_array[i].iov_len = buffers[i].iov_len;
161 buffer_size += buffers[i].iov_len;
163 // keep dividing the current buffer_size in half and then
164 // attempt to send the modified iovec buffer until some
165 // data is sent, or we get an errno that is not ENOBUFS
166 while (true)
168 ACE_UINT64 remove_size = buffer_size / 2;
169 buffer_size -= remove_size;
170 for (i = simulated_n - 1; (i >= 0) && (remove_size > 0); --i)
172 // if the buffer division splits an iovec, we need
173 // to set its iov_len properly
174 if (iovec_array[i].iov_len > remove_size)
176 iovec_array[i].iov_len -= static_cast<u_long>(remove_size);
177 break;
179 remove_size -= iovec_array[i].iov_len;
182 simulated_n = i + 1;
184 result = ::WSASend ((SOCKET) handle,
185 (WSABUF *) &(iovec_array[0]),
186 simulated_n,
187 &bytes_sent,
191 if (result != SOCKET_ERROR)
192 break;
194 ACE_OS::set_errno_to_wsa_last_error ();
195 // if ENOBUFS is received, we apply a divide and
196 // conquer strategy, but if bytes are sent we
197 // cannot guarantee this is the same behavior
198 if ((errno != ENOBUFS) ||
199 (bytes_sent != 0))
201 return -1;
205 return (ssize_t) bytes_sent;
206 #else
207 ACE_UNUSED_ARG (handle);
208 ACE_UNUSED_ARG (buffers);
209 ACE_UNUSED_ARG (n);
210 ACE_NOTSUP_RETURN (-1);
211 #endif /* ACE_HAS_WINSOCK2 */
214 ssize_t
215 ACE_OS::send_partial_i (ACE_HANDLE handle,
216 const char *buf,
217 size_t len,
218 int flags)
220 // the divide and conquer logic should remain consistent
221 // with sendv_partial_i
222 #if !defined (ACE_LACKS_SEND) && defined (ACE_WIN32)
223 DWORD bytes_sent = 0;
224 ssize_t result = 1;
225 // keep dividing the current buffer_size in half and then
226 // attempt to send the modified buffer until some data is
227 // sent, or we get an errno that is not ENOBUFS
228 while (true)
230 len -= len / 2;
232 result = (ssize_t) ::send ((SOCKET) handle,
233 buf,
234 static_cast<int> (len),
235 flags);
236 if (result != SOCKET_ERROR)
237 break;
239 ACE_OS::set_errno_to_wsa_last_error ();
240 // if ENOBUFS is received, we apply a divide and
241 // conquer strategy, but if bytes are sent we
242 // cannot guarantee this is the same behavior
243 if ((errno != ENOBUFS) ||
244 (bytes_sent != 0))
246 return -1;
250 return result;
251 #else
252 ACE_UNUSED_ARG (handle);
253 ACE_UNUSED_ARG (buf);
254 ACE_UNUSED_ARG (len);
255 ACE_UNUSED_ARG (flags);
256 ACE_NOTSUP_RETURN (-1);
257 #endif /* ACE_LACKS_SEND && ACE_WIN32 */
260 #if !defined ACE_LACKS_RECVMSG && defined ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2
261 int ACE_OS::recvmsg_win32_i (ACE_HANDLE handle,
262 msghdr *msg,
263 int flags,
264 unsigned long &bytes_received)
266 static GUID wsaRcvMsgGuid = WSAID_WSARECVMSG;
267 LPFN_WSARECVMSG wsaRcvMsg = 0;
268 unsigned long ioctlN = 0;
269 SOCKET const sock = reinterpret_cast<SOCKET> (handle);
270 if (::WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
271 &wsaRcvMsgGuid, sizeof wsaRcvMsgGuid,
272 &wsaRcvMsg, sizeof wsaRcvMsg,
273 &ioctlN, 0, 0))
275 ACE_OS::set_errno_to_wsa_last_error ();
276 return -1;
279 if (!wsaRcvMsg)
280 ACE_NOTSUP_RETURN (-1);
282 WSAMSG wsaMsg =
284 msg->msg_name,
285 msg->msg_namelen,
286 reinterpret_cast<WSABUF *> (msg->msg_iov),
287 static_cast<unsigned long> (msg->msg_iovlen),
289 static_cast<unsigned long> (msg->msg_controllen),
290 static_cast<char *> (msg->msg_control),
292 static_cast<unsigned long> (flags),
295 if (wsaRcvMsg (sock, &wsaMsg, &bytes_received, 0, 0))
297 ACE_OS::set_errno_to_wsa_last_error ();
298 return -1;
301 msg->msg_namelen = wsaMsg.namelen;
302 msg->msg_controllen = static_cast<int> (wsaMsg.Control.len);
303 return 0;
306 int ACE_OS::sendmsg_win32_i (ACE_HANDLE handle,
307 msghdr const *msg,
308 int flags,
309 unsigned long &bytes_sent)
311 # if _WIN32_WINNT >= 0x0600
312 WSAMSG wsaMsg =
314 msg->msg_name,
315 msg->msg_namelen,
316 reinterpret_cast<WSABUF *> (msg->msg_iov),
317 static_cast<unsigned long> (msg->msg_iovlen),
319 static_cast<unsigned long> (msg->msg_controllen),
320 static_cast<char *> (msg->msg_control),
322 static_cast<unsigned long> (flags),
325 SOCKET const sock = reinterpret_cast<SOCKET> (handle);
326 if (::WSASendMsg (sock, &wsaMsg, wsaMsg.dwFlags, &bytes_sent, 0, 0))
328 ACE_OS::set_errno_to_wsa_last_error ();
329 return -1;
332 return 0;
333 # else
334 ACE_UNUSED_ARG (handle);
335 ACE_UNUSED_ARG (msg);
336 ACE_UNUSED_ARG (flags);
337 ACE_UNUSED_ARG (bytes_sent);
338 ACE_NOTSUP_RETURN (-1);
339 # endif
341 #endif
343 ACE_END_VERSIONED_NAMESPACE_DECL