* autoload.cc (WSAIoctl): Reintroduce.
(WSASendMsg): Define. * fhandler.h (class fhandler_socket): Change definition of recv_internal and send_internal to take WSAMSG pointer as parameter. * fhandler_socket.cc (WSAID_WSARECVMSG): Define. (LPFN_WSARECVMSG): Define. (WSASendMsg): Declare. (get_ext_funcptr): New function to fetch address of WSARecvMsg. (fhandler_socket::recv_internal): Take just a LPWSAMSG parameter. Change code accordingly. If control information is requested, fetch address of WSARecvMsg and use that instead of WSARecvFrom. (fhandler_socket::recvfrom): Change return type to ssize_t as declared in fhandler.h. Accommodate changes to recv_internal. (fhandler_socket::recvmsg): Ditto. Make sure that control information is only requested if system, address family, and socket type support it. (fhandler_socket::send_internal): Take just a LPWSAMSG parameter and the flags. Change code accordingly. If control information is provided, use WSASendMsg instead of WSASendTo. (fhandler_socket::sendto): Drop useless comment. Accommodate changes to send_internal. (fhandler_socket::sendmsg): Ditto. Make sure that control information is only provided if system, address family, and socket type support it. * wincap.h (wincaps::has_recvmsg): New element. (wincaps::has_sendmsg): New element * wincap.cc: Implement above elements throughout. * include/cygwin/socket.h (CMSG_ALIGN): Phrase in terms of alignment of type struct cmsghdr.
This commit is contained in:
parent
2e287a6327
commit
3787b37ef2
@ -1,3 +1,33 @@
|
|||||||
|
2009-01-20 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (WSAIoctl): Reintroduce.
|
||||||
|
(WSASendMsg): Define.
|
||||||
|
* fhandler.h (class fhandler_socket): Change definition of recv_internal
|
||||||
|
and send_internal to take WSAMSG pointer as parameter.
|
||||||
|
* fhandler_socket.cc (WSAID_WSARECVMSG): Define.
|
||||||
|
(LPFN_WSARECVMSG): Define.
|
||||||
|
(WSASendMsg): Declare.
|
||||||
|
(get_ext_funcptr): New function to fetch address of WSARecvMsg.
|
||||||
|
(fhandler_socket::recv_internal): Take just a LPWSAMSG parameter.
|
||||||
|
Change code accordingly. If control information is requested,
|
||||||
|
fetch address of WSARecvMsg and use that instead of WSARecvFrom.
|
||||||
|
(fhandler_socket::recvfrom): Change return type to ssize_t as
|
||||||
|
declared in fhandler.h. Accommodate changes to recv_internal.
|
||||||
|
(fhandler_socket::recvmsg): Ditto. Make sure that control information
|
||||||
|
is only requested if system, address family, and socket type support it.
|
||||||
|
(fhandler_socket::send_internal): Take just a LPWSAMSG parameter
|
||||||
|
and the flags. Change code accordingly. If control information is
|
||||||
|
provided, use WSASendMsg instead of WSASendTo.
|
||||||
|
(fhandler_socket::sendto): Drop useless comment. Accommodate changes
|
||||||
|
to send_internal.
|
||||||
|
(fhandler_socket::sendmsg): Ditto. Make sure that control information
|
||||||
|
is only provided if system, address family, and socket type support it.
|
||||||
|
* wincap.h (wincaps::has_recvmsg): New element.
|
||||||
|
(wincaps::has_sendmsg): New element
|
||||||
|
* wincap.cc: Implement above elements throughout.
|
||||||
|
* include/cygwin/socket.h (CMSG_ALIGN): Phrase in terms of alignment
|
||||||
|
of type struct cmsghdr.
|
||||||
|
|
||||||
2009-01-17 Corinna Vinschen <corinna@vinschen.de>
|
2009-01-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* mmap.cc (mmap64): Fix condition checking if anonymous mapping beyond
|
* mmap.cc (mmap64): Fix condition checking if anonymous mapping beyond
|
||||||
|
@ -389,7 +389,9 @@ LoadDLLfunc (WSAAsyncSelect, 16, ws2_32)
|
|||||||
LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
|
LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
||||||
|
LoadDLLfunc (WSAIoctl, 36, ws2_32)
|
||||||
LoadDLLfunc (WSARecvFrom, 36, ws2_32)
|
LoadDLLfunc (WSARecvFrom, 36, ws2_32)
|
||||||
|
LoadDLLfunc (WSASendMsg, 24, ws2_32)
|
||||||
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
||||||
LoadDLLfunc (WSASetLastError, 4, ws2_32)
|
LoadDLLfunc (WSASetLastError, 4, ws2_32)
|
||||||
// LoadDLLfunc (WSAStartup, 8, ws2_32)
|
// LoadDLLfunc (WSAStartup, 8, ws2_32)
|
||||||
|
@ -483,16 +483,13 @@ class fhandler_socket: public fhandler_base
|
|||||||
|
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||||
inline ssize_t recv_internal (struct _WSABUF *wsabuf, DWORD wsacnt,
|
inline ssize_t recv_internal (struct _WSAMSG *wsamsg);
|
||||||
DWORD flags,
|
|
||||||
struct sockaddr *from, int *fromlen);
|
|
||||||
ssize_t recvfrom (void *ptr, size_t len, int flags,
|
ssize_t recvfrom (void *ptr, size_t len, int flags,
|
||||||
struct sockaddr *from, int *fromlen);
|
struct sockaddr *from, int *fromlen);
|
||||||
ssize_t recvmsg (struct msghdr *msg, int flags);
|
ssize_t recvmsg (struct msghdr *msg, int flags);
|
||||||
|
|
||||||
ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||||
inline ssize_t send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
|
inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
|
||||||
const struct sockaddr *to, int tolen);
|
|
||||||
ssize_t sendto (const void *ptr, size_t len, int flags,
|
ssize_t sendto (const void *ptr, size_t len, int flags,
|
||||||
const struct sockaddr *to, int tolen);
|
const struct sockaddr *to, int tolen);
|
||||||
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#define USE_SYS_TYPES_FD_SET
|
#define USE_SYS_TYPES_FD_SET
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <mswsock.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
@ -1277,16 +1278,52 @@ fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
|
|||||||
return recvmsg (&msg, 0);
|
return recvmsg (&msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#define WSAID_WSARECVMSG \
|
||||||
|
{0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}};
|
||||||
|
typedef int (WSAAPI *LPFN_WSARECVMSG)(SOCKET,LPWSAMSG,LPDWORD,LPWSAOVERLAPPED,
|
||||||
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||||
|
int WSAAPI WSASendMsg(SOCKET,LPWSAMSG,DWORD,LPDWORD, LPWSAOVERLAPPED,
|
||||||
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* There's no DLL which exports the symbol WSARecvMsg. One has to call
|
||||||
|
WSAIoctl as below to fetch the function pointer. Why on earth did the
|
||||||
|
MS developers decide not to export a normal symbol for these extension
|
||||||
|
functions? */
|
||||||
|
inline int
|
||||||
|
get_ext_funcptr (SOCKET sock, void *funcptr)
|
||||||
|
{
|
||||||
|
DWORD bret;
|
||||||
|
const GUID guid = WSAID_WSARECVMSG;
|
||||||
|
return WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||||
|
(void *) &guid, sizeof (GUID), funcptr, sizeof (void *),
|
||||||
|
&bret, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
inline ssize_t
|
inline ssize_t
|
||||||
fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
|
fhandler_socket::recv_internal (LPWSAMSG wsamsg)
|
||||||
struct sockaddr *from, int *fromlen)
|
|
||||||
{
|
{
|
||||||
ssize_t res = 0;
|
ssize_t res = 0;
|
||||||
DWORD ret = 0, wret;
|
DWORD ret = 0, wret;
|
||||||
int evt_mask = FD_READ | ((flags & MSG_OOB) ? FD_OOB : 0);
|
int evt_mask = FD_READ | ((wsamsg->dwFlags & MSG_OOB) ? FD_OOB : 0);
|
||||||
|
LPWSABUF wsabuf = wsamsg->lpBuffers;
|
||||||
|
ULONG wsacnt = wsamsg->dwBufferCount;
|
||||||
|
bool use_recvmsg = false;
|
||||||
|
static LPFN_WSARECVMSG WSARecvMsg;
|
||||||
|
|
||||||
bool waitall = (flags & MSG_WAITALL);
|
bool waitall = (wsamsg->dwFlags & MSG_WAITALL);
|
||||||
flags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
|
wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
|
||||||
|
if (wsamsg->Control.len > 0)
|
||||||
|
{
|
||||||
|
if (!WSARecvMsg
|
||||||
|
&& get_ext_funcptr (get_socket (), &WSARecvMsg) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
set_winsock_errno ();
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
use_recvmsg = true;
|
||||||
|
}
|
||||||
if (waitall)
|
if (waitall)
|
||||||
{
|
{
|
||||||
if (get_socket_type () != SOCK_STREAM)
|
if (get_socket_type () != SOCK_STREAM)
|
||||||
@ -1295,7 +1332,7 @@ fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
|
|||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
if (is_nonblocking () || (flags & (MSG_OOB | MSG_PEEK)))
|
if (is_nonblocking () || (wsamsg->dwFlags & (MSG_OOB | MSG_PEEK)))
|
||||||
waitall = false;
|
waitall = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1305,8 +1342,12 @@ fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
|
|||||||
while (!(res = wait_for_events (evt_mask | FD_CLOSE))
|
while (!(res = wait_for_events (evt_mask | FD_CLOSE))
|
||||||
|| saw_shutdown_read ())
|
|| saw_shutdown_read ())
|
||||||
{
|
{
|
||||||
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
|
if (use_recvmsg)
|
||||||
&flags, from, fromlen, NULL, NULL);
|
res = WSARecvMsg (get_socket (), wsamsg, &wret, NULL, NULL);
|
||||||
|
else
|
||||||
|
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
|
||||||
|
&wsamsg->dwFlags, wsamsg->name, &wsamsg->namelen,
|
||||||
|
NULL, NULL);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
ret += wret;
|
ret += wret;
|
||||||
@ -1353,32 +1394,34 @@ fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
||||||
struct sockaddr *from, int *fromlen)
|
struct sockaddr *from, int *fromlen)
|
||||||
{
|
{
|
||||||
WSABUF wsabuf = { len, (char *) ptr };
|
WSABUF wsabuf = { len, (char *) ptr };
|
||||||
return recv_internal (&wsabuf, 1, flags, from, fromlen);
|
WSAMSG wsamsg = { from, from && fromlen ? *fromlen : 0,
|
||||||
|
&wsabuf, 1,
|
||||||
|
{ 0, NULL},
|
||||||
|
flags };
|
||||||
|
ssize_t ret = recv_internal (&wsamsg);
|
||||||
|
if (fromlen)
|
||||||
|
*fromlen = wsamsg.namelen;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
|
/* TODO: Descriptor passing on AF_LOCAL sockets. */
|
||||||
((struct OLD_msghdr *) msg)->msg_accrightslen = 0;
|
|
||||||
else
|
/* Disappointing but true: Even if WSARecvMsg is supported, it's only
|
||||||
|
supported for datagram and raw sockets. */
|
||||||
|
if (!wincap.has_recvmsg () || get_socket_type () == SOCK_STREAM
|
||||||
|
|| get_addr_family () == AF_LOCAL)
|
||||||
{
|
{
|
||||||
msg->msg_controllen = 0;
|
msg->msg_controllen = 0;
|
||||||
msg->msg_flags = 0;
|
if (!CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
|
||||||
}
|
msg->msg_flags = 0;
|
||||||
if (get_addr_family () == AF_LOCAL)
|
|
||||||
{
|
|
||||||
/* On AF_LOCAL sockets the (fixed-size) name of the shared memory
|
|
||||||
area used for descriptor passing is transmitted first.
|
|
||||||
If this string is empty, no descriptors are passed and we can
|
|
||||||
go ahead recv'ing the normal data blocks. Otherwise start
|
|
||||||
special handling for descriptor passing. */
|
|
||||||
/*TODO*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WSABUF wsabuf[msg->msg_iovlen];
|
WSABUF wsabuf[msg->msg_iovlen];
|
||||||
@ -1389,11 +1432,19 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
|||||||
wsaptr->len = (--iovptr)->iov_len;
|
wsaptr->len = (--iovptr)->iov_len;
|
||||||
wsaptr->buf = (char *) iovptr->iov_base;
|
wsaptr->buf = (char *) iovptr->iov_base;
|
||||||
}
|
}
|
||||||
|
WSAMSG wsamsg = { (struct sockaddr *) msg->msg_name, msg->msg_namelen,
|
||||||
struct sockaddr *from = (struct sockaddr *) msg->msg_name;
|
wsabuf, msg->msg_iovlen,
|
||||||
int *fromlen = from ? &msg->msg_namelen : NULL;
|
{ msg->msg_controllen, (char *) msg->msg_control },
|
||||||
|
flags };
|
||||||
return recv_internal (wsabuf, msg->msg_iovlen, flags, from, fromlen);
|
ssize_t ret = recv_internal (&wsamsg);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
msg->msg_namelen = wsamsg.namelen;
|
||||||
|
msg->msg_controllen = wsamsg.Control.len;
|
||||||
|
if (!CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
|
||||||
|
msg->msg_flags = wsamsg.dwFlags;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1415,26 +1466,35 @@ fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t
|
inline ssize_t
|
||||||
fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
|
fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
|
||||||
const struct sockaddr *to, int tolen)
|
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
DWORD ret = 0, err = 0, sum = 0, off = 0;
|
DWORD ret = 0, err = 0, sum = 0, off = 0;
|
||||||
WSABUF buf;
|
WSABUF buf;
|
||||||
|
bool use_sendmsg = false;
|
||||||
|
|
||||||
for (DWORD i = 0; i < wsacnt; off >= wsabuf[i].len && (++i, off = 0))
|
if (wsamsg->Control.len > 0)
|
||||||
|
use_sendmsg = true;
|
||||||
|
for (DWORD i = 0; i < wsamsg->dwBufferCount;
|
||||||
|
off >= wsamsg->lpBuffers[i].len && (++i, off = 0))
|
||||||
{
|
{
|
||||||
buf.buf = wsabuf[i].buf + off;
|
buf.buf = wsamsg->lpBuffers[i].buf + off;
|
||||||
buf.len = wsabuf[i].len - off;
|
buf.len = wsamsg->lpBuffers[i].len - off;
|
||||||
if (buf.len > 65536) /* See KB 823764 */
|
if (buf.len > 65536) /* See KB 823764 */
|
||||||
buf.len = 65536;
|
buf.len = 65536;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((res = WSASendTo (get_socket (), &buf, 1, &ret,
|
if (use_sendmsg)
|
||||||
flags & (MSG_OOB | MSG_DONTROUTE), to, tolen,
|
res = WSASendMsg (get_socket (), wsamsg,
|
||||||
NULL, NULL))
|
flags & (MSG_OOB | MSG_DONTROUTE), &ret,
|
||||||
&& (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
|
NULL, NULL);
|
||||||
|
else
|
||||||
|
res = WSASendTo (get_socket (), &buf, 1, &ret,
|
||||||
|
flags & (MSG_OOB | MSG_DONTROUTE),
|
||||||
|
wsamsg->name, wsamsg->namelen,
|
||||||
|
NULL, NULL);
|
||||||
|
if (res && (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
|
||||||
{
|
{
|
||||||
LOCK_EVENTS;
|
LOCK_EVENTS;
|
||||||
wsock_events->events &= ~FD_WRITE;
|
wsock_events->events &= ~FD_WRITE;
|
||||||
@ -1467,7 +1527,7 @@ fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
|
|||||||
if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM)
|
if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM)
|
||||||
{
|
{
|
||||||
set_errno (EPIPE);
|
set_errno (EPIPE);
|
||||||
if (! (flags & MSG_NOSIGNAL))
|
if (!(flags & MSG_NOSIGNAL))
|
||||||
raise (SIGPIPE);
|
raise (SIGPIPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1484,28 +1544,18 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
|
|||||||
if (to && !get_inet_addr (to, tolen, &sst, &tolen))
|
if (to && !get_inet_addr (to, tolen, &sst, &tolen))
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
/* Never write more than 64K at once to workaround a problem with
|
|
||||||
Winsock, which creates a temporary buffer with the total incoming
|
|
||||||
buffer size and copies the whole content over, regardless of
|
|
||||||
the size of the internal send buffer. A buffer full condition
|
|
||||||
is only recognized in subsequent calls and, if len is big enough,
|
|
||||||
the call even might fail with an out-of-memory condition. */
|
|
||||||
WSABUF wsabuf = { len, (char *) ptr };
|
WSABUF wsabuf = { len, (char *) ptr };
|
||||||
return send_internal (&wsabuf, 1, flags,
|
WSAMSG wsamsg = { to ? (struct sockaddr *) &sst : NULL, tolen,
|
||||||
(to ? (const struct sockaddr *) &sst : NULL), tolen);
|
&wsabuf, 1,
|
||||||
|
{ 0, NULL},
|
||||||
|
0 };
|
||||||
|
return send_internal (&wsamsg, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
if (get_addr_family () == AF_LOCAL)
|
/* TODO: Descriptor passing on AF_LOCAL sockets. */
|
||||||
{
|
|
||||||
/* For AF_LOCAL/AF_UNIX sockets, if descriptors are given, start
|
|
||||||
the special handling for descriptor passing. Otherwise just
|
|
||||||
transmit an empty string to tell the receiver that no
|
|
||||||
descriptor passing is done. */
|
|
||||||
/*TODO*/
|
|
||||||
}
|
|
||||||
|
|
||||||
WSABUF wsabuf[msg->msg_iovlen];
|
WSABUF wsabuf[msg->msg_iovlen];
|
||||||
WSABUF *wsaptr = wsabuf;
|
WSABUF *wsaptr = wsabuf;
|
||||||
@ -1515,9 +1565,17 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
|||||||
wsaptr->len = iovptr->iov_len;
|
wsaptr->len = iovptr->iov_len;
|
||||||
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
||||||
}
|
}
|
||||||
|
WSAMSG wsamsg = { (struct sockaddr *) msg->msg_name, msg->msg_namelen,
|
||||||
return send_internal (wsabuf, msg->msg_iovlen, flags,
|
wsabuf, msg->msg_iovlen,
|
||||||
(struct sockaddr *) msg->msg_name, msg->msg_namelen);
|
/* Disappointing but true: Even if WSASendMsg is
|
||||||
|
supported, it's only supported for datagram and
|
||||||
|
raw sockets. */
|
||||||
|
{ !wincap.has_sendmsg ()
|
||||||
|
|| get_socket_type () == SOCK_STREAM
|
||||||
|
|| get_addr_family () == AF_LOCAL
|
||||||
|
? 0 : msg->msg_controllen, (char *) msg->msg_control },
|
||||||
|
0 };
|
||||||
|
return send_internal (&wsamsg, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -80,7 +80,8 @@ struct cmsghdr
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define CMSG_ALIGN(len) \
|
#define CMSG_ALIGN(len) \
|
||||||
(((len) + sizeof (size_t) - 1) & ~(sizeof (size_t) - 1))
|
(((len) + __alignof__ (struct cmsghdr) - 1) \
|
||||||
|
& ~(__alignof__ (struct cmsghdr) - 1))
|
||||||
#define CMSG_LEN(len) \
|
#define CMSG_LEN(len) \
|
||||||
(CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
|
(CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
|
||||||
#define CMSG_SPACE(len) \
|
#define CMSG_SPACE(len) \
|
||||||
|
@ -51,6 +51,8 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) =
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:false,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -84,6 +86,8 @@ wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:false,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -117,6 +121,8 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:false,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -150,6 +156,8 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:false,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -183,6 +191,8 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:false,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -216,6 +226,8 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:true,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -249,6 +261,8 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:true,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -282,6 +296,8 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:true,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -315,6 +331,8 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:true,
|
has_restricted_stack_args:true,
|
||||||
has_transactions:false,
|
has_transactions:false,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:true,
|
||||||
|
has_sendmsg:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -348,6 +366,8 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
has_transactions:true,
|
has_transactions:true,
|
||||||
ts_has_dep_problem:false,
|
ts_has_dep_problem:false,
|
||||||
|
has_recvmsg:true,
|
||||||
|
has_sendmsg:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
@ -43,6 +43,8 @@ struct wincaps
|
|||||||
unsigned has_restricted_stack_args : 1;
|
unsigned has_restricted_stack_args : 1;
|
||||||
unsigned has_transactions : 1;
|
unsigned has_transactions : 1;
|
||||||
unsigned ts_has_dep_problem : 1;
|
unsigned ts_has_dep_problem : 1;
|
||||||
|
unsigned has_recvmsg : 1;
|
||||||
|
unsigned has_sendmsg : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
@ -92,6 +94,8 @@ public:
|
|||||||
bool IMPLEMENT (has_restricted_stack_args)
|
bool IMPLEMENT (has_restricted_stack_args)
|
||||||
bool IMPLEMENT (has_transactions)
|
bool IMPLEMENT (has_transactions)
|
||||||
bool IMPLEMENT (ts_has_dep_problem)
|
bool IMPLEMENT (ts_has_dep_problem)
|
||||||
|
bool IMPLEMENT (has_recvmsg)
|
||||||
|
bool IMPLEMENT (has_sendmsg)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user