* autoload.cc: Never load wsock32.dll. Load all wsock32 function
from ws2_32. Rearrange symbol order accordingly. None of the ws2_32 functions is optional right now. (wsadata): Move from net.cc here. Define NO_COPY. (wsock_init): Drop unused symbols ws2_32_handle and wsock32_handle. (load_wsock32): Remove. (WSACleanup): Remove. * fhandler_socket.cc: Drop Winsock 1 accommodations throughout. (fhandler_socket::readv): Accomodate new POSIX style struct msghdr. (fhandler_socket::writev): Ditto. (fhandler_socket::recvmsg): Ditto. Handle "old" applications using former struct msghdr correctly. * net.cc: Drop Winsock 1 accommodations throughout. (wsadata): Move definition to autoload.cc. (set_socket_inheritance): Remove. (convert_ws1_ip_optname): New static function to convert Winsock1 IPPROTO_IP option values into Winsock2 IPPROTO_IP option values. (cygwin_setsockopt): Remove wrong and incomplete cleartext printing of optname. For "old" applications, convert optname from Winsock1 to Winsock2 values before using them. Add comment to describe the IP_TOS weirdness on W2K and above. (cygwin_getsockopt): Remove wrong and incomplete cleartext printing of optname. For "old" applications, convert optname from Winsock1 to Winsock2 values before using them. * select.cc (start_thread_socket): Forget about winsock2_active. * winsup.h (wsock32_handle): Remove declaration. (ws2_32_handle): Ditto. (netapi32_handle): Ditto. (wsadata): Ditto. (winsock2_active): Remove definition. * include/cygwin/socket.h: Change formatting slightly. (socklen_t): Move definition up in file. (struct msghdr): Convert to POSIX style. (struct cmsghdr): New type. (CMSG_ALIGN): New macro. (CMSG_LEN): Ditto. (CMSG_SPACE): Ditto. (CMSG_FIRSTHDR): Ditto. (CMSG_NXTHDR): Ditto. (CMSG_DATA): Ditto. (SCM_RIGHTS): Ditto. (struct OLD_msghdr): Define old msghdr structure for Cygwin internal purposes. (MSG_TRUNC): New macro. (MSG_CTRUNC): Ditto. (IP_OPTIONS): Redefine IPPROTO_IP option values to Winsock2 values. Keep Winsock1 values for Cygwin internal purposes. * include/cygwin/version.h: Bump API minor version. (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR): Define to check for applications using old struct msghdr. (CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES): Define to check for applications using old Winsock1 IPPROTO_IP values.
This commit is contained in:
parent
9276ec15a7
commit
8b00a766ff
|
@ -1,3 +1,58 @@
|
|||
2005-10-17 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* autoload.cc: Never load wsock32.dll. Load all wsock32 function
|
||||
from ws2_32. Rearrange symbol order accordingly. None of the ws2_32
|
||||
functions is optional right now.
|
||||
(wsadata): Move from net.cc here. Define NO_COPY.
|
||||
(wsock_init): Drop unused symbols ws2_32_handle and wsock32_handle.
|
||||
(load_wsock32): Remove.
|
||||
(WSACleanup): Remove.
|
||||
* fhandler_socket.cc: Drop Winsock 1 accommodations throughout.
|
||||
(fhandler_socket::readv): Accomodate new POSIX style struct msghdr.
|
||||
(fhandler_socket::writev): Ditto.
|
||||
(fhandler_socket::recvmsg): Ditto. Handle "old" applications using
|
||||
former struct msghdr correctly.
|
||||
* net.cc: Drop Winsock 1 accommodations throughout.
|
||||
(wsadata): Move definition to autoload.cc.
|
||||
(set_socket_inheritance): Remove.
|
||||
(convert_ws1_ip_optname): New static function to convert Winsock1
|
||||
IPPROTO_IP option values into Winsock2 IPPROTO_IP option values.
|
||||
(cygwin_setsockopt): Remove wrong and incomplete cleartext printing
|
||||
of optname. For "old" applications, convert optname from Winsock1
|
||||
to Winsock2 values before using them. Add comment to describe the
|
||||
IP_TOS weirdness on W2K and above.
|
||||
(cygwin_getsockopt): Remove wrong and incomplete cleartext printing
|
||||
of optname. For "old" applications, convert optname from Winsock1
|
||||
to Winsock2 values before using them.
|
||||
* select.cc (start_thread_socket): Forget about winsock2_active.
|
||||
* winsup.h (wsock32_handle): Remove declaration.
|
||||
(ws2_32_handle): Ditto.
|
||||
(netapi32_handle): Ditto.
|
||||
(wsadata): Ditto.
|
||||
(winsock2_active): Remove definition.
|
||||
* include/cygwin/socket.h: Change formatting slightly.
|
||||
(socklen_t): Move definition up in file.
|
||||
(struct msghdr): Convert to POSIX style.
|
||||
(struct cmsghdr): New type.
|
||||
(CMSG_ALIGN): New macro.
|
||||
(CMSG_LEN): Ditto.
|
||||
(CMSG_SPACE): Ditto.
|
||||
(CMSG_FIRSTHDR): Ditto.
|
||||
(CMSG_NXTHDR): Ditto.
|
||||
(CMSG_DATA): Ditto.
|
||||
(SCM_RIGHTS): Ditto.
|
||||
(struct OLD_msghdr): Define old msghdr structure for Cygwin internal
|
||||
purposes.
|
||||
(MSG_TRUNC): New macro.
|
||||
(MSG_CTRUNC): Ditto.
|
||||
(IP_OPTIONS): Redefine IPPROTO_IP option values to Winsock2 values.
|
||||
Keep Winsock1 values for Cygwin internal purposes.
|
||||
* include/cygwin/version.h: Bump API minor version.
|
||||
(CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR): Define to check for
|
||||
applications using old struct msghdr.
|
||||
(CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES): Define to check for
|
||||
applications using old Winsock1 IPPROTO_IP values.
|
||||
|
||||
2005-10-13 David Rothenberger <daveroth@acm.org>
|
||||
Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
|
|
|
@ -244,6 +244,7 @@ std_dll_init ()
|
|||
|
||||
/* Initialization function for winsock stuff. */
|
||||
bool NO_COPY wsock_started = 0;
|
||||
WSADATA NO_COPY wsadata;
|
||||
__attribute__ ((used, noinline, regparm(1))) static long long
|
||||
wsock_init ()
|
||||
{
|
||||
|
@ -251,16 +252,6 @@ wsock_init ()
|
|||
struct func_info *func = (struct func_info *) __builtin_return_address (0);
|
||||
struct dll_info *dll = func->dll;
|
||||
|
||||
__asm__ (" \n\
|
||||
.section .ws2_32_info \n\
|
||||
.equ _ws2_32_handle,.ws2_32_info + 4 \n\
|
||||
.global _ws2_32_handle \n\
|
||||
.section .wsock32_info \n\
|
||||
.equ _wsock32_handle,.wsock32_info + 4 \n\
|
||||
.global _wsock32_handle \n\
|
||||
.text \n\
|
||||
");
|
||||
|
||||
while (InterlockedIncrement (&here))
|
||||
{
|
||||
InterlockedDecrement (&here);
|
||||
|
@ -305,7 +296,6 @@ wsock_init ()
|
|||
return ret.ll;
|
||||
}
|
||||
|
||||
LoadDLLprime (wsock32, _wsock_init)
|
||||
LoadDLLprime (ws2_32, _wsock_init)
|
||||
|
||||
LoadDLLfunc (AccessCheck, 32, advapi32)
|
||||
|
@ -452,57 +442,54 @@ LoadDLLfunc (SetProcessWindowStation, 4, user32)
|
|||
LoadDLLfunc (SetTimer, 16, user32)
|
||||
LoadDLLfunc (SetUserObjectSecurity, 12, user32)
|
||||
|
||||
LoadDLLfuncEx (load_wsock32, 0, wsock32, 1) // non-existent function forces wsock32 load
|
||||
LoadDLLfunc (WSAAsyncSelect, 16, wsock32)
|
||||
LoadDLLfunc (WSACleanup, 0, wsock32)
|
||||
LoadDLLfunc (WSAGetLastError, 0, wsock32)
|
||||
LoadDLLfunc (WSASetLastError, 4, wsock32)
|
||||
// LoadDLLfunc (WSAStartup, 8, wsock32)
|
||||
LoadDLLfunc (__WSAFDIsSet, 8, wsock32)
|
||||
LoadDLLfunc (accept, 12, wsock32)
|
||||
LoadDLLfunc (bind, 12, wsock32)
|
||||
LoadDLLfunc (closesocket, 4, wsock32)
|
||||
LoadDLLfunc (connect, 12, wsock32)
|
||||
LoadDLLfunc (gethostbyaddr, 12, wsock32)
|
||||
LoadDLLfunc (gethostbyname, 4, wsock32)
|
||||
LoadDLLfuncEx2 (gethostname, 8, wsock32, 1, 1)
|
||||
LoadDLLfunc (getpeername, 12, wsock32)
|
||||
LoadDLLfunc (getprotobyname, 4, wsock32)
|
||||
LoadDLLfunc (getprotobynumber, 4, wsock32)
|
||||
LoadDLLfunc (getservbyname, 8, wsock32)
|
||||
LoadDLLfunc (getservbyport, 8, wsock32)
|
||||
LoadDLLfunc (getsockname, 12, wsock32)
|
||||
LoadDLLfunc (getsockopt, 20, wsock32)
|
||||
LoadDLLfunc (inet_addr, 4, wsock32)
|
||||
LoadDLLfunc (inet_network, 4, wsock32)
|
||||
LoadDLLfunc (inet_ntoa, 4, wsock32)
|
||||
LoadDLLfunc (ioctlsocket, 12, wsock32)
|
||||
LoadDLLfunc (listen, 8, wsock32)
|
||||
LoadDLLfunc (rcmd, 24, wsock32)
|
||||
LoadDLLfunc (recv, 16, wsock32)
|
||||
LoadDLLfunc (recvfrom, 24, wsock32)
|
||||
LoadDLLfunc (rexec, 24, wsock32)
|
||||
LoadDLLfunc (rresvport, 4, wsock32)
|
||||
LoadDLLfunc (select, 20, wsock32)
|
||||
LoadDLLfunc (send, 16, wsock32)
|
||||
LoadDLLfunc (sendto, 24, wsock32)
|
||||
LoadDLLfunc (setsockopt, 20, wsock32)
|
||||
LoadDLLfunc (shutdown, 8, wsock32)
|
||||
LoadDLLfunc (socket, 12, wsock32)
|
||||
|
||||
LoadDLLfuncEx (WSACloseEvent, 4, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSACreateEvent, 0, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSADuplicateSocketA, 12, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSAGetOverlappedResult, 20, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSARecv, 28, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSARecvFrom, 36, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSASend, 28, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSASendTo, 36, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSASetEvent, 4, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSASocketA, 24, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSAWaitForMultipleEvents, 20, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSAEventSelect, 12, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSAEnumNetworkEvents, 12, ws2_32, 1)
|
||||
LoadDLLfunc (accept, 12, ws2_32)
|
||||
LoadDLLfunc (bind, 12, ws2_32)
|
||||
LoadDLLfunc (closesocket, 4, ws2_32)
|
||||
LoadDLLfunc (connect, 12, ws2_32)
|
||||
LoadDLLfunc (gethostbyaddr, 12, ws2_32)
|
||||
LoadDLLfunc (gethostbyname, 4, ws2_32)
|
||||
LoadDLLfuncEx2 (gethostname, 8, ws2_32, 1, 1)
|
||||
LoadDLLfunc (getpeername, 12, ws2_32)
|
||||
LoadDLLfunc (getprotobyname, 4, ws2_32)
|
||||
LoadDLLfunc (getprotobynumber, 4, ws2_32)
|
||||
LoadDLLfunc (getservbyname, 8, ws2_32)
|
||||
LoadDLLfunc (getservbyport, 8, ws2_32)
|
||||
LoadDLLfunc (getsockname, 12, ws2_32)
|
||||
LoadDLLfunc (getsockopt, 20, ws2_32)
|
||||
LoadDLLfunc (inet_addr, 4, ws2_32)
|
||||
LoadDLLfunc (inet_network, 4, ws2_32)
|
||||
LoadDLLfunc (inet_ntoa, 4, ws2_32)
|
||||
LoadDLLfunc (ioctlsocket, 12, ws2_32)
|
||||
LoadDLLfunc (listen, 8, ws2_32)
|
||||
LoadDLLfunc (rcmd, 24, ws2_32)
|
||||
LoadDLLfunc (recv, 16, ws2_32)
|
||||
LoadDLLfunc (recvfrom, 24, ws2_32)
|
||||
LoadDLLfunc (rexec, 24, ws2_32)
|
||||
LoadDLLfunc (rresvport, 4, ws2_32)
|
||||
LoadDLLfunc (select, 20, ws2_32)
|
||||
LoadDLLfunc (send, 16, ws2_32)
|
||||
LoadDLLfunc (sendto, 24, ws2_32)
|
||||
LoadDLLfunc (setsockopt, 20, ws2_32)
|
||||
LoadDLLfunc (shutdown, 8, ws2_32)
|
||||
LoadDLLfunc (socket, 12, ws2_32)
|
||||
LoadDLLfunc (WSAAsyncSelect, 16, ws2_32)
|
||||
LoadDLLfunc (WSACloseEvent, 4, ws2_32)
|
||||
LoadDLLfunc (WSACreateEvent, 0, ws2_32)
|
||||
LoadDLLfunc (WSADuplicateSocketA, 12, ws2_32)
|
||||
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
||||
LoadDLLfunc (WSAGetOverlappedResult, 20, ws2_32)
|
||||
LoadDLLfunc (WSARecv, 28, ws2_32)
|
||||
LoadDLLfunc (WSARecvFrom, 36, ws2_32)
|
||||
LoadDLLfunc (WSASend, 28, ws2_32)
|
||||
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
||||
LoadDLLfunc (WSASetEvent, 4, ws2_32)
|
||||
LoadDLLfunc (WSASetLastError, 4, ws2_32)
|
||||
LoadDLLfunc (WSASocketA, 24, ws2_32)
|
||||
// LoadDLLfunc (WSAStartup, 8, ws2_32)
|
||||
LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
|
||||
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
||||
LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
|
||||
LoadDLLfunc (__WSAFDIsSet, 8, ws2_32)
|
||||
|
||||
LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
|
||||
LoadDLLfuncEx (GetIfEntry, 4, iphlpapi, 1)
|
||||
|
|
|
@ -394,12 +394,7 @@ fhandler_socket::af_local_set_secret (char *buf)
|
|||
void
|
||||
fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
|
||||
{
|
||||
if (!winsock2_active)
|
||||
{
|
||||
fhandler_base::fixup_before_fork_exec (win_proc_id);
|
||||
debug_printf ("Without Winsock 2.0");
|
||||
}
|
||||
else if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
|
||||
if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
|
||||
debug_printf ("WSADuplicateSocket went fine, sock %p, win_proc_id %d, prot_info_ptr %p",
|
||||
get_socket (), win_proc_id, prot_info_ptr);
|
||||
else
|
||||
|
@ -410,7 +405,6 @@ fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void __stdcall load_wsock32 ();
|
||||
void
|
||||
fhandler_socket::fixup_after_fork (HANDLE parent)
|
||||
{
|
||||
|
@ -428,12 +422,6 @@ fhandler_socket::fixup_after_fork (HANDLE parent)
|
|||
set_io_handle ((HANDLE)INVALID_SOCKET);
|
||||
set_winsock_errno ();
|
||||
}
|
||||
else if (!new_sock && !winsock2_active)
|
||||
{
|
||||
load_wsock32 ();
|
||||
fhandler_base::fixup_after_fork (parent);
|
||||
debug_printf ("Without Winsock 2.0");
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_io_handle ());
|
||||
|
@ -447,10 +435,6 @@ fhandler_socket::fixup_after_exec ()
|
|||
debug_printf ("here");
|
||||
if (!close_on_exec ())
|
||||
fixup_after_fork (NULL);
|
||||
#if 0
|
||||
else if (!winsock2_active)
|
||||
closesocket (get_socket ());
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -477,37 +461,34 @@ fhandler_socket::dup (fhandler_base *child)
|
|||
}
|
||||
fhs->connect_state (connect_state ());
|
||||
|
||||
if (winsock2_active)
|
||||
/* Since WSADuplicateSocket() fails on NT systems when the process
|
||||
is currently impersonating a non-privileged account, we revert
|
||||
to the original account before calling WSADuplicateSocket() and
|
||||
switch back afterwards as it's also in fork().
|
||||
If WSADuplicateSocket() still fails for some reason, we fall back
|
||||
to DuplicateHandle(). */
|
||||
WSASetLastError (0);
|
||||
cygheap->user.deimpersonate ();
|
||||
fhs->set_io_handle (get_io_handle ());
|
||||
fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
||||
cygheap->user.reimpersonate ();
|
||||
if (!WSAGetLastError ())
|
||||
{
|
||||
/* Since WSADuplicateSocket() fails on NT systems when the process
|
||||
is currently impersonating a non-privileged account, we revert
|
||||
to the original account before calling WSADuplicateSocket() and
|
||||
switch back afterwards as it's also in fork().
|
||||
If WSADuplicateSocket() still fails for some reason, we fall back
|
||||
to DuplicateHandle(). */
|
||||
WSASetLastError (0);
|
||||
cygheap->user.deimpersonate ();
|
||||
fhs->set_io_handle (get_io_handle ());
|
||||
fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
||||
cygheap->user.reimpersonate ();
|
||||
if (!WSAGetLastError ())
|
||||
fhs->fixup_after_fork (hMainProc);
|
||||
if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
|
||||
{
|
||||
fhs->fixup_after_fork (hMainProc);
|
||||
if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
|
||||
{
|
||||
cygheap->fdtab.inc_need_fixup_before ();
|
||||
return 0;
|
||||
}
|
||||
cygheap->fdtab.inc_need_fixup_before ();
|
||||
return 0;
|
||||
}
|
||||
debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
|
||||
}
|
||||
debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
|
||||
|
||||
/* We don't call fhandler_base::dup here since that requires
|
||||
having winsock called from fhandler_base and it creates only
|
||||
inheritable sockets which is wrong for winsock2. */
|
||||
|
||||
if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
|
||||
!winsock2_active, DUPLICATE_SAME_ACCESS))
|
||||
FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
|
||||
__seterrno ();
|
||||
|
@ -992,8 +973,9 @@ fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
|
|||
msg_namelen: 0,
|
||||
msg_iov: (struct iovec *) iov, // const_cast
|
||||
msg_iovlen: iovcnt,
|
||||
msg_accrights: NULL,
|
||||
msg_accrightslen: 0
|
||||
msg_control: NULL,
|
||||
msg_controllen: 0,
|
||||
msg_flags: 0
|
||||
};
|
||||
|
||||
return recvmsg (&msg, 0, tot);
|
||||
|
@ -1007,34 +989,27 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
|||
DWORD ret = 0;
|
||||
|
||||
flags &= MSG_WINMASK;
|
||||
if (!winsock2_active)
|
||||
ret = res = ::recvfrom (get_socket (),
|
||||
(char *) ptr, len, flags,
|
||||
from, fromlen);
|
||||
WSABUF wsabuf = { len, (char *) ptr };
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret,
|
||||
(DWORD *) &flags, from, fromlen, NULL, NULL);
|
||||
else
|
||||
{
|
||||
WSABUF wsabuf = { len, (char *) ptr };
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret,
|
||||
(DWORD *) &flags, from, fromlen, NULL, NULL);
|
||||
else
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
|
||||
{
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
DWORD lflags = (DWORD) flags;
|
||||
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, &lflags,
|
||||
from, fromlen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !closed ()
|
||||
&& !(res = wait (evt, flags)));
|
||||
release (evt);
|
||||
DWORD lflags = (DWORD) flags;
|
||||
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, &lflags,
|
||||
from, fromlen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !closed ()
|
||||
&& !(res = wait (evt, flags)));
|
||||
release (evt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1056,6 +1031,13 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
|||
int
|
||||
fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
|
||||
{
|
||||
if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
|
||||
((struct OLD_msghdr *) msg)->msg_accrightslen = 0;
|
||||
else
|
||||
{
|
||||
msg->msg_controllen = 0;
|
||||
msg->msg_flags = 0;
|
||||
}
|
||||
if (get_addr_family () == AF_LOCAL)
|
||||
{
|
||||
/* On AF_LOCAL sockets the (fixed-size) name of the shared memory
|
||||
|
@ -1064,7 +1046,6 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
|
|||
go ahead recv'ing the normal data blocks. Otherwise start
|
||||
special handling for descriptor passing. */
|
||||
/*TODO*/
|
||||
msg->msg_accrightslen = 0;
|
||||
}
|
||||
|
||||
struct iovec *const iov = msg->msg_iov;
|
||||
|
@ -1075,104 +1056,56 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
|
|||
|
||||
int res = SOCKET_ERROR;
|
||||
|
||||
if (!winsock2_active)
|
||||
WSABUF wsabuf[iovcnt];
|
||||
unsigned long len = 0L;
|
||||
|
||||
const struct iovec *iovptr = iov + iovcnt;
|
||||
WSABUF *wsaptr = wsabuf + iovcnt;
|
||||
do
|
||||
{
|
||||
if (iovcnt == 1)
|
||||
res = recvfrom (iov->iov_base, iov->iov_len, flags, from, fromlen);
|
||||
else
|
||||
{
|
||||
if (tot == -1) // i.e. if not pre-calculated by the caller.
|
||||
{
|
||||
tot = 0;
|
||||
const struct iovec *iovptr = iov + iovcnt;
|
||||
do
|
||||
{
|
||||
iovptr -= 1;
|
||||
tot += iovptr->iov_len;
|
||||
}
|
||||
while (iovptr != iov);
|
||||
}
|
||||
|
||||
char *buf = (char *) alloca (tot);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
set_errno (ENOMEM);
|
||||
res = SOCKET_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = recvfrom (buf, tot, flags, from, fromlen);
|
||||
|
||||
const struct iovec *iovptr = iov;
|
||||
int nbytes = res;
|
||||
|
||||
while (nbytes > 0)
|
||||
{
|
||||
const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
|
||||
memcpy (iovptr->iov_base, buf, frag);
|
||||
buf += frag;
|
||||
iovptr += 1;
|
||||
nbytes -= frag;
|
||||
}
|
||||
}
|
||||
}
|
||||
iovptr -= 1;
|
||||
wsaptr -= 1;
|
||||
len += wsaptr->len = iovptr->iov_len;
|
||||
wsaptr->buf = (char *) iovptr->iov_base;
|
||||
}
|
||||
while (wsaptr != wsabuf);
|
||||
|
||||
DWORD ret = 0;
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
|
||||
(DWORD *) &flags, from, fromlen, NULL, NULL);
|
||||
else
|
||||
{
|
||||
WSABUF wsabuf[iovcnt];
|
||||
unsigned long len = 0L;
|
||||
|
||||
{
|
||||
const struct iovec *iovptr = iov + iovcnt;
|
||||
WSABUF *wsaptr = wsabuf + iovcnt;
|
||||
do
|
||||
{
|
||||
iovptr -= 1;
|
||||
wsaptr -= 1;
|
||||
len += wsaptr->len = iovptr->iov_len;
|
||||
wsaptr->buf = (char *) iovptr->iov_base;
|
||||
}
|
||||
while (wsaptr != wsabuf);
|
||||
}
|
||||
|
||||
DWORD ret = 0;
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
|
||||
(DWORD *) &flags, from, fromlen, NULL, NULL);
|
||||
else
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
|
||||
{
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
DWORD lflags = (DWORD) flags;
|
||||
res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
|
||||
&lflags, from, fromlen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !closed ()
|
||||
&& !(res = wait (evt, flags)));
|
||||
release (evt);
|
||||
DWORD lflags = (DWORD) flags;
|
||||
res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
|
||||
&lflags, from, fromlen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !closed ()
|
||||
&& !(res = wait (evt, flags)));
|
||||
release (evt);
|
||||
}
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
{
|
||||
/* According to SUSv3, errno isn't set in that case and no error
|
||||
condition is returned. */
|
||||
if (WSAGetLastError () == WSAEMSGSIZE)
|
||||
return len;
|
||||
|
||||
set_winsock_errno ();
|
||||
}
|
||||
else
|
||||
res = ret;
|
||||
}
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
{
|
||||
/* According to SUSv3, errno isn't set in that case and no error
|
||||
condition is returned. */
|
||||
if (WSAGetLastError () == WSAEMSGSIZE)
|
||||
return len;
|
||||
|
||||
set_winsock_errno ();
|
||||
}
|
||||
else
|
||||
res = ret;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1186,8 +1119,9 @@ fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
|
|||
msg_namelen: 0,
|
||||
msg_iov: (struct iovec *) iov, // const_cast
|
||||
msg_iovlen: iovcnt,
|
||||
msg_accrights: NULL,
|
||||
msg_accrightslen: 0
|
||||
msg_control: NULL,
|
||||
msg_controllen: 0,
|
||||
msg_flags: 0
|
||||
};
|
||||
|
||||
return sendmsg (&msg, 0, tot);
|
||||
|
@ -1205,37 +1139,30 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
|
|||
int res = SOCKET_ERROR;
|
||||
DWORD ret = 0;
|
||||
|
||||
if (!winsock2_active)
|
||||
ret = res = ::sendto (get_socket (), (const char *) ptr, len,
|
||||
flags & MSG_WINMASK,
|
||||
(to ? (const struct sockaddr *) &sin : NULL), tolen);
|
||||
WSABUF wsabuf = { len, (char *) ptr };
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
|
||||
flags & MSG_WINMASK,
|
||||
(to ? (const struct sockaddr *) &sin : NULL), tolen,
|
||||
NULL, NULL);
|
||||
else
|
||||
{
|
||||
WSABUF wsabuf = { len, (char *) ptr };
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
|
||||
flags & MSG_WINMASK,
|
||||
(to ? (const struct sockaddr *) &sin : NULL), tolen,
|
||||
NULL, NULL);
|
||||
else
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
|
||||
{
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
|
||||
flags & MSG_WINMASK,
|
||||
(to ? (const struct sockaddr *) &sin : NULL),
|
||||
tolen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !(res = wait (evt, 0))
|
||||
&& !closed ());
|
||||
release (evt);
|
||||
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
|
||||
flags & MSG_WINMASK,
|
||||
(to ? (const struct sockaddr *) &sin : NULL),
|
||||
tolen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !(res = wait (evt, 0))
|
||||
&& !closed ());
|
||||
release (evt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1277,103 +1204,50 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
|
|||
|
||||
int res = SOCKET_ERROR;
|
||||
|
||||
if (!winsock2_active)
|
||||
WSABUF wsabuf[iovcnt];
|
||||
|
||||
const struct iovec *iovptr = iov + iovcnt;
|
||||
WSABUF *wsaptr = wsabuf + iovcnt;
|
||||
do
|
||||
{
|
||||
if (iovcnt == 1)
|
||||
res = sendto (iov->iov_base, iov->iov_len, flags,
|
||||
(struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen);
|
||||
else
|
||||
{
|
||||
if (tot == -1) // i.e. if not pre-calculated by the caller.
|
||||
{
|
||||
tot = 0;
|
||||
const struct iovec *iovptr = iov + iovcnt;
|
||||
do
|
||||
{
|
||||
iovptr -= 1;
|
||||
tot += iovptr->iov_len;
|
||||
}
|
||||
while (iovptr != iov);
|
||||
}
|
||||
|
||||
char *const buf = (char *) alloca (tot);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
set_errno (ENOMEM);
|
||||
res = SOCKET_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *bufptr = buf;
|
||||
const struct iovec *iovptr = iov;
|
||||
int nbytes = tot;
|
||||
|
||||
while (nbytes != 0)
|
||||
{
|
||||
const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
|
||||
memcpy (bufptr, iovptr->iov_base, frag);
|
||||
bufptr += frag;
|
||||
iovptr += 1;
|
||||
nbytes -= frag;
|
||||
}
|
||||
|
||||
res = sendto (buf, tot, flags,
|
||||
(struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen);
|
||||
}
|
||||
}
|
||||
iovptr -= 1;
|
||||
wsaptr -= 1;
|
||||
wsaptr->len = iovptr->iov_len;
|
||||
wsaptr->buf = (char *) iovptr->iov_base;
|
||||
}
|
||||
while (wsaptr != wsabuf);
|
||||
|
||||
DWORD ret = 0;
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret,
|
||||
flags, (struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen, NULL, NULL);
|
||||
else
|
||||
{
|
||||
WSABUF wsabuf[iovcnt];
|
||||
|
||||
{
|
||||
const struct iovec *iovptr = iov + iovcnt;
|
||||
WSABUF *wsaptr = wsabuf + iovcnt;
|
||||
do
|
||||
{
|
||||
iovptr -= 1;
|
||||
wsaptr -= 1;
|
||||
wsaptr->len = iovptr->iov_len;
|
||||
wsaptr->buf = (char *) iovptr->iov_base;
|
||||
}
|
||||
while (wsaptr != wsabuf);
|
||||
}
|
||||
|
||||
DWORD ret = 0;
|
||||
|
||||
if (is_nonblocking () || closed () || async_io ())
|
||||
res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret,
|
||||
flags, (struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen, NULL, NULL);
|
||||
else
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
|
||||
{
|
||||
HANDLE evt;
|
||||
if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
res = WSASendTo (get_socket (), wsabuf, iovcnt,
|
||||
&ret, flags,
|
||||
(struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !(res = wait (evt, 0))
|
||||
&& !closed ());
|
||||
release (evt);
|
||||
res = WSASendTo (get_socket (), wsabuf, iovcnt,
|
||||
&ret, flags,
|
||||
(struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen, NULL, NULL);
|
||||
}
|
||||
while (res == SOCKET_ERROR
|
||||
&& WSAGetLastError () == WSAEWOULDBLOCK
|
||||
&& !(res = wait (evt, 0))
|
||||
&& !closed ());
|
||||
release (evt);
|
||||
}
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
set_winsock_errno ();
|
||||
else
|
||||
res = ret;
|
||||
}
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
set_winsock_errno ();
|
||||
else
|
||||
res = ret;
|
||||
|
||||
/* Special handling for EPIPE and SIGPIPE.
|
||||
|
||||
EPIPE is generated if the local end has been shut down on a connection
|
||||
|
@ -1628,8 +1502,6 @@ fhandler_socket::fcntl (int cmd, void *arg)
|
|||
void
|
||||
fhandler_socket::set_close_on_exec (bool val)
|
||||
{
|
||||
if (!winsock2_active) /* < Winsock 2.0 */
|
||||
set_no_inheritance (get_handle (), val);
|
||||
close_on_exec (val);
|
||||
debug_printf ("set close_on_exec for %s to %d", get_name (), val);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* cygwin/socket.h
|
||||
|
||||
Copyright 1999, 2000, 2001 Red Hat, Inc.
|
||||
Copyright 1999, 2000, 2001, 2005 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -26,30 +26,80 @@ struct sockaddr {
|
|||
#include <sys/types.h>
|
||||
|
||||
struct ucred {
|
||||
pid_t pid;
|
||||
__uid32_t uid;
|
||||
__gid32_t gid;
|
||||
pid_t pid;
|
||||
__uid32_t uid;
|
||||
__gid32_t gid;
|
||||
};
|
||||
|
||||
struct linger {
|
||||
unsigned short l_onoff; /* Linger active */
|
||||
unsigned short l_linger; /* How long to linger for */
|
||||
};
|
||||
|
||||
struct msghdr
|
||||
{
|
||||
void * msg_name; /* Socket name */
|
||||
int msg_namelen; /* Length of name */
|
||||
struct iovec * msg_iov; /* Data blocks */
|
||||
int msg_iovlen; /* Number of blocks */
|
||||
void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
|
||||
int msg_accrightslen; /* Length of rights list */
|
||||
unsigned short l_onoff; /* Linger active */
|
||||
unsigned short l_linger; /* How long to linger for */
|
||||
};
|
||||
|
||||
#ifndef socklen_t
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
struct msghdr
|
||||
{
|
||||
void * msg_name; /* Socket name */
|
||||
socklen_t msg_namelen; /* Length of name */
|
||||
struct iovec * msg_iov; /* Data blocks */
|
||||
int msg_iovlen; /* Number of blocks */
|
||||
void * msg_control; /* Ancillary data */
|
||||
socklen_t msg_controllen; /* Ancillary data buffer length */
|
||||
int msg_flags; /* Received flags on recvmsg */
|
||||
};
|
||||
|
||||
struct cmsghdr
|
||||
{
|
||||
socklen_t cmsg_len; /* Length of cmsghdr + data */
|
||||
int cmsg_level; /* Protocol */
|
||||
int cmsg_type; /* Protocol type */
|
||||
};
|
||||
|
||||
#define CMSG_ALIGN(len) \
|
||||
(((len) + sizeof (size_t) - 1) & ~(sizeof (size_t) - 1))
|
||||
#define CMSG_LEN(len) \
|
||||
(CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
|
||||
#define CMSG_SPACE(len) \
|
||||
(CMSG_ALIGN (sizeof (struct cmsghdr)) + CMSG_ALIGN(len))
|
||||
#define CMSG_FIRSTHDR(mhdr) \
|
||||
({ \
|
||||
struct msghdr *_m = (struct msghdr *) mhdr; \
|
||||
(_m)->msg_controllen >= sizeof (struct cmsghdr) \
|
||||
? (struct cmsghdr *) (_m)->msg_control \
|
||||
: (struct cmsghdr *) NULL; \
|
||||
})
|
||||
#define CMSG_NXTHDR(mhdr,cmsg) \
|
||||
({ \
|
||||
struct msghdr *_m = (struct msghdr *) mhdr; \
|
||||
struct cmsghdr *_c = (struct cmsghdr *) cmsg; \
|
||||
((char *) _c + CMSG_SPACE (_c->cmsg_len) \
|
||||
> (char *) _m->msg_control + _m->msg_controllen) \
|
||||
? (struct cmsghdr *) NULL \
|
||||
: (struct cmsghdr *) ((char *) _c + CMSG_ALIGN (_c->cmsg_len)); \
|
||||
})
|
||||
#define CMSG_DATA(cmsg) \
|
||||
((unsigned char *) ((struct cmsghdr *)(cmsg) + 1))
|
||||
|
||||
/* "Socket"-level control message types: */
|
||||
#define SCM_RIGHTS 0x01 /* access rights (array of int) */
|
||||
|
||||
#ifdef __INSIDE_CYGWIN__
|
||||
/* Definition of struct msghdr up to release 1.5.18 */
|
||||
struct OLD_msghdr
|
||||
{
|
||||
void * msg_name; /* Socket name */
|
||||
int msg_namelen; /* Length of name */
|
||||
struct iovec * msg_iov; /* Data blocks */
|
||||
int msg_iovlen; /* Number of blocks */
|
||||
void * msg_accrights; /* Per protocol magic */
|
||||
/* (eg BSD descriptor passing) */
|
||||
int msg_accrightslen; /* Length of rights list */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Socket types. */
|
||||
#define SOCK_STREAM 1 /* stream (connection) socket */
|
||||
#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
|
||||
|
@ -124,6 +174,8 @@ struct msghdr
|
|||
#define MSG_DONTROUTE 0x4 /* send without using routing tables */
|
||||
#define MSG_WINMASK 0x7 /* flags understood by WinSock calls */
|
||||
#define MSG_NOSIGNAL 0x20 /* Don't raise SIGPIPE */
|
||||
#define MSG_TRUNC 0x0100 /* Normal data truncated */
|
||||
#define MSG_CTRUNC 0x0200 /* Control data truncated */
|
||||
|
||||
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
|
||||
#define SOL_IP 0
|
||||
|
@ -146,17 +198,35 @@ struct msghdr
|
|||
#define IP_DEFAULT_MULTICAST_LOOP 1
|
||||
#define IP_MAX_MEMBERSHIPS 20
|
||||
|
||||
/* IP options for use with WinSock */
|
||||
/* IP options for use with getsockopt/setsockopt */
|
||||
#define IP_OPTIONS 1
|
||||
#define IP_HDRINCL 2
|
||||
#define IP_TOS 3
|
||||
#define IP_TTL 4
|
||||
#define IP_MULTICAST_IF 9
|
||||
#define IP_MULTICAST_TTL 10
|
||||
#define IP_MULTICAST_LOOP 11
|
||||
#define IP_ADD_MEMBERSHIP 12
|
||||
#define IP_DROP_MEMBERSHIP 13
|
||||
#define IP_DONTFRAGMENT 14
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 15
|
||||
#define IP_DROP_SOURCE_MEMBERSHIP 16
|
||||
#define IP_BLOCK_SOURCE 17
|
||||
#define IP_UNBLOCK_SOURCE 18
|
||||
#define IP_PKTINFO 19
|
||||
|
||||
#define IP_OPTIONS 1
|
||||
#define IP_MULTICAST_IF 2
|
||||
#define IP_MULTICAST_TTL 3
|
||||
#define IP_MULTICAST_LOOP 4
|
||||
#define IP_ADD_MEMBERSHIP 5
|
||||
#define IP_DROP_MEMBERSHIP 6
|
||||
#define IP_TTL 7
|
||||
#define IP_TOS 8
|
||||
#define IP_DONTFRAGMENT 9
|
||||
/* Old WinSock1 values, needed internally */
|
||||
#ifdef __INSIDE_CYGWIN__
|
||||
#define _WS1_IP_OPTIONS 1
|
||||
#define _WS1_IP_MULTICAST_IF 2
|
||||
#define _WS1_IP_MULTICAST_TTL 3
|
||||
#define _WS1_IP_MULTICAST_LOOP 4
|
||||
#define _WS1_IP_ADD_MEMBERSHIP 5
|
||||
#define _WS1_IP_DROP_MEMBERSHIP 6
|
||||
#define _WS1_IP_TTL 7
|
||||
#define _WS1_IP_TOS 8
|
||||
#define _WS1_IP_DONTFRAGMENT 9
|
||||
#endif
|
||||
|
||||
/* IPX options */
|
||||
#define IPX_TYPE 1
|
||||
|
|
|
@ -88,6 +88,15 @@ details. */
|
|||
#define CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES \
|
||||
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) >= \
|
||||
79)
|
||||
|
||||
#define CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR \
|
||||
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \
|
||||
138)
|
||||
|
||||
#define CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES \
|
||||
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \
|
||||
138)
|
||||
|
||||
/* We used to use the DLL major/minor to track
|
||||
non-backward-compatible interface changes to the API. Now we
|
||||
use an API major/minor number for this purpose. */
|
||||
|
@ -266,12 +275,14 @@ details. */
|
|||
137: fts_children, fts_close, fts_get_clientptr, fts_get_stream,
|
||||
fts_open, fts_read, fts_set, fts_set_clientptr, ftw, nftw.
|
||||
138: Export readdir_r.
|
||||
139: Start using POSIX definition of struct msghdr and WinSock2
|
||||
IPPROTO_IP values.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 138
|
||||
#define CYGWIN_VERSION_API_MINOR 139
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -29,6 +29,8 @@ details. */
|
|||
#include <assert.h>
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
#include "cygwin/version.h"
|
||||
#include "perprocess.h"
|
||||
#include "path.h"
|
||||
#include "fhandler.h"
|
||||
#include "dtable.h"
|
||||
|
@ -50,8 +52,6 @@ extern "C"
|
|||
int sscanf (const char *, const char *, ...);
|
||||
} /* End of "C" section */
|
||||
|
||||
WSADATA wsadata;
|
||||
|
||||
static fhandler_socket *
|
||||
get (const int fd)
|
||||
{
|
||||
|
@ -68,20 +68,6 @@ get (const int fd)
|
|||
return fh;
|
||||
}
|
||||
|
||||
static SOCKET __stdcall
|
||||
set_socket_inheritance (SOCKET sock)
|
||||
{
|
||||
SOCKET osock = sock;
|
||||
|
||||
if (!DuplicateHandle (hMainProc, (HANDLE) sock, hMainProc, (HANDLE *) &sock,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
||||
system_printf ("DuplicateHandle failed %E");
|
||||
else
|
||||
debug_printf ("DuplicateHandle succeeded osock %p, sock %p", osock, sock);
|
||||
VerifyHandle ((HANDLE) sock);
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* htonl: standards? */
|
||||
extern "C" unsigned long int
|
||||
htonl (unsigned long int x)
|
||||
|
@ -555,24 +541,20 @@ cygwin_getprotobynumber (int number)
|
|||
bool
|
||||
fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
|
||||
{
|
||||
if (!winsock2_active)
|
||||
soc = set_socket_inheritance (soc);
|
||||
else if (wincap.has_set_handle_information ())
|
||||
if (wincap.has_set_handle_information ())
|
||||
{
|
||||
/* NT systems apparently set sockets to inheritable by default */
|
||||
SetHandleInformation ((HANDLE) soc, HANDLE_FLAG_INHERIT, 0);
|
||||
debug_printf ("reset socket inheritance since winsock2_active %d",
|
||||
winsock2_active);
|
||||
debug_printf ("reset socket inheritance");
|
||||
}
|
||||
else
|
||||
debug_printf ("not setting socket inheritance since winsock2_active %d",
|
||||
winsock2_active);
|
||||
debug_printf ("not setting socket inheritance");
|
||||
fd = build_fh_dev (*dev);
|
||||
if (!fd.isopen ())
|
||||
return false;
|
||||
fd->set_io_handle ((HANDLE) soc);
|
||||
fd->set_flags (O_RDWR | O_BINARY);
|
||||
fd->uninterruptible_io (winsock2_active);
|
||||
fd->uninterruptible_io (true);
|
||||
cygheap->fdtab.inc_need_fixup_before ();
|
||||
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc);
|
||||
return true;
|
||||
|
@ -663,6 +645,27 @@ cygwin_recvfrom (int fd, void *buf, int len, int flags,
|
|||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
convert_ws1_ip_optname (int optname)
|
||||
{
|
||||
static int ws2_optname[] =
|
||||
{
|
||||
0,
|
||||
IP_OPTIONS,
|
||||
IP_MULTICAST_IF,
|
||||
IP_MULTICAST_TTL,
|
||||
IP_MULTICAST_LOOP,
|
||||
IP_ADD_MEMBERSHIP,
|
||||
IP_DROP_MEMBERSHIP,
|
||||
IP_TTL,
|
||||
IP_TOS,
|
||||
IP_DONTFRAGMENT
|
||||
};
|
||||
return (optname < 1 || optname > _WS1_IP_DONTFRAGMENT)
|
||||
? optname
|
||||
: ws2_optname[optname];
|
||||
}
|
||||
|
||||
/* exported as setsockopt: standards? */
|
||||
extern "C" int
|
||||
cygwin_setsockopt (int fd, int level, int optname, const void *optval,
|
||||
|
@ -670,48 +673,30 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
|
|||
{
|
||||
int res;
|
||||
fhandler_socket *fh = get (fd);
|
||||
const char *name = "error";
|
||||
|
||||
/* For the following debug_printf */
|
||||
switch (optname)
|
||||
{
|
||||
case SO_DEBUG:
|
||||
name = "SO_DEBUG";
|
||||
break;
|
||||
case SO_ACCEPTCONN:
|
||||
name = "SO_ACCEPTCONN";
|
||||
break;
|
||||
case SO_REUSEADDR:
|
||||
name = "SO_REUSEADDR";
|
||||
break;
|
||||
case SO_KEEPALIVE:
|
||||
name = "SO_KEEPALIVE";
|
||||
break;
|
||||
case SO_DONTROUTE:
|
||||
name = "SO_DONTROUTE";
|
||||
break;
|
||||
case SO_BROADCAST:
|
||||
name = "SO_BROADCAST";
|
||||
break;
|
||||
case SO_USELOOPBACK:
|
||||
name = "SO_USELOOPBACK";
|
||||
break;
|
||||
case SO_LINGER:
|
||||
name = "SO_LINGER";
|
||||
break;
|
||||
case SO_OOBINLINE:
|
||||
name = "SO_OOBINLINE";
|
||||
break;
|
||||
case SO_ERROR:
|
||||
name = "SO_ERROR";
|
||||
break;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT) || !fh)
|
||||
res = -1;
|
||||
else
|
||||
{
|
||||
/* Old applications still use the old Winsock1 IPPROTO_IP values. */
|
||||
if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES)
|
||||
optname = convert_ws1_ip_optname (optname);
|
||||
/* FOR THE RECORDS:
|
||||
|
||||
Setting IP_TOS is disabled by default since W2K, the official
|
||||
reason being that IP_TOS setting would interfere with Windows
|
||||
QOS settings. As result, setsockopt returns with WinSock error
|
||||
10022, WSAEINVAL, when running under W2K or later, instead of
|
||||
handling this gracefully.
|
||||
|
||||
The workaround is described in KB article 248611. Add a new
|
||||
registry DWORD value HKLM/System/CurrentControlSet/Services/...
|
||||
... Tcpip/Parameters/DisableUserTOSSetting, set to 0, and reboot.
|
||||
|
||||
FIXME: Maybe we should simply fake that IP_TOS could be set
|
||||
successfully, if DisableUserTOSSetting is not set to 0 on W2K
|
||||
and above? */
|
||||
res = setsockopt (fh->get_socket (), level, optname,
|
||||
(const char *) optval, optlen);
|
||||
|
||||
|
@ -722,8 +707,8 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
|
|||
set_winsock_errno ();
|
||||
}
|
||||
|
||||
syscall_printf ("%d = setsockopt (%d, %d, %x (%s), %p, %d)",
|
||||
res, fd, level, optname, name, optval, optlen);
|
||||
syscall_printf ("%d = setsockopt (%d, %d, %x, %p, %d)",
|
||||
res, fd, level, optname, optval, optlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -733,44 +718,6 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen)
|
|||
{
|
||||
int res;
|
||||
fhandler_socket *fh = get (fd);
|
||||
const char *name = "error";
|
||||
|
||||
/* For the following debug_printf */
|
||||
switch (optname)
|
||||
{
|
||||
case SO_DEBUG:
|
||||
name = "SO_DEBUG";
|
||||
break;
|
||||
case SO_ACCEPTCONN:
|
||||
name = "SO_ACCEPTCONN";
|
||||
break;
|
||||
case SO_REUSEADDR:
|
||||
name = "SO_REUSEADDR";
|
||||
break;
|
||||
case SO_KEEPALIVE:
|
||||
name = "SO_KEEPALIVE";
|
||||
break;
|
||||
case SO_DONTROUTE:
|
||||
name = "SO_DONTROUTE";
|
||||
break;
|
||||
case SO_BROADCAST:
|
||||
name = "SO_BROADCAST";
|
||||
break;
|
||||
case SO_USELOOPBACK:
|
||||
name = "SO_USELOOPBACK";
|
||||
break;
|
||||
case SO_LINGER:
|
||||
name = "SO_LINGER";
|
||||
break;
|
||||
case SO_OOBINLINE:
|
||||
name = "SO_OOBINLINE";
|
||||
break;
|
||||
case SO_ERROR:
|
||||
name = "SO_ERROR";
|
||||
break;
|
||||
case SO_PEERCRED:
|
||||
name = "SO_PEERCRED";
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT) || !fh)
|
||||
|
@ -782,6 +729,9 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Old applications still use the old Winsock1 IPPROTO_IP values. */
|
||||
if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES)
|
||||
optname = convert_ws1_ip_optname (optname);
|
||||
res = getsockopt (fh->get_socket (), level, optname, (char *) optval,
|
||||
(int *) optlen);
|
||||
|
||||
|
@ -797,8 +747,8 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen)
|
|||
set_winsock_errno ();
|
||||
}
|
||||
|
||||
syscall_printf ("%d = getsockopt (%d, %d, %x (%s), %p, %p)",
|
||||
res, fd, level, optname, name, optval, optlen);
|
||||
syscall_printf ("%d = getsockopt (%d, %d, 0x%x, %p, %p)",
|
||||
res, fd, level, optname, optval, optlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -1410,7 +1410,7 @@ start_thread_socket (select_record *me, select_stuff *stuff)
|
|||
select_printf ("getsockname error");
|
||||
goto err;
|
||||
}
|
||||
if (winsock2_active && wincap.has_set_handle_information ())
|
||||
if (wincap.has_set_handle_information ())
|
||||
SetHandleInformation ((HANDLE) si->exitsock, HANDLE_FLAG_INHERIT, 0);
|
||||
/* else
|
||||
too bad? */
|
||||
|
|
|
@ -225,13 +225,6 @@ void events_terminate ();
|
|||
|
||||
void __stdcall close_all_files (bool = false);
|
||||
|
||||
/* Globals that handle initialization of winsock in a child process. */
|
||||
extern HANDLE wsock32_handle;
|
||||
extern HANDLE ws2_32_handle;
|
||||
|
||||
/* Globals that handle initialization of netapi in a child process. */
|
||||
extern HANDLE netapi32_handle;
|
||||
|
||||
/* debug_on_trap support. see exceptions.cc:try_to_debug() */
|
||||
extern "C" void error_start_init (const char*);
|
||||
extern "C" int try_to_debug (bool waitloop = 1);
|
||||
|
@ -352,7 +345,4 @@ extern bool cygwin_testing;
|
|||
|
||||
extern char almost_null[];
|
||||
|
||||
#define winsock2_active (wsadata.wVersion >= 512)
|
||||
extern struct WSAData wsadata;
|
||||
|
||||
#endif /* defined __cplusplus */
|
||||
|
|
Loading…
Reference in New Issue