* 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:
Corinna Vinschen
2005-10-17 21:22:18 +00:00
parent 9276ec15a7
commit 8b00a766ff
8 changed files with 406 additions and 471 deletions

View File

@@ -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);
}