* fhandler.h (class fhandler_socket): Remove prot_info_ptr.
(fhandler_socket::fixup_before_fork_exec): Remove. (fhandler_socket::fixup_after_exec): Remove. (fhandler_socket::need_fixup_before): Remove. * fhandler_socket.cc (fhandler_socket::fhandler_socket): Drop initializing prot_info_ptr. Remove unused code. (fhandler_socket::~fhandler_socket): Drop free'ing prot_info_ptr. (struct wsa_event): Rename connect_errorcode to errorcode. (fhandler_socket::evaluate_events): Handle FD_CLOSE error condition as FD_CONNECT error condition, except, never reset an FD_CLOSE error condition. Always set FD_WRITE after successfully recorded FD_CONNECT. (fhandler_socket::fixup_before_fork_exec): Remove. (fhandler_socket::fixup_after_fork): Revert to using handle duplication. (fhandler_socket::fixup_after_exec): Remove. (fhandler_socket::dup): Revert to using handle duplication. (fhandler_socket::send_internal): Only call wait_for_events in case of WSAEWOULDBLOCK condition. (fhandler_socket::set_close_on_exec): Call fhandler_base::set_close_on_exec. * net.cc (fdsock): Just set socket to inheritable on non-NT. Don't call inc_need_fixup_before. * select.cc (peek_socket): Don't set except_ready on every FD_CLOSE, just on error.
This commit is contained in:
parent
40f67ea198
commit
9869e006f3
|
@ -1,3 +1,29 @@
|
|||
2006-07-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler.h (class fhandler_socket): Remove prot_info_ptr.
|
||||
(fhandler_socket::fixup_before_fork_exec): Remove.
|
||||
(fhandler_socket::fixup_after_exec): Remove.
|
||||
(fhandler_socket::need_fixup_before): Remove.
|
||||
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Drop
|
||||
initializing prot_info_ptr. Remove unused code.
|
||||
(fhandler_socket::~fhandler_socket): Drop free'ing prot_info_ptr.
|
||||
(struct wsa_event): Rename connect_errorcode to errorcode.
|
||||
(fhandler_socket::evaluate_events): Handle FD_CLOSE error condition
|
||||
as FD_CONNECT error condition, except, never reset an FD_CLOSE error
|
||||
condition. Always set FD_WRITE after successfully recorded FD_CONNECT.
|
||||
(fhandler_socket::fixup_before_fork_exec): Remove.
|
||||
(fhandler_socket::fixup_after_fork): Revert to using handle duplication.
|
||||
(fhandler_socket::fixup_after_exec): Remove.
|
||||
(fhandler_socket::dup): Revert to using handle duplication.
|
||||
(fhandler_socket::send_internal): Only call wait_for_events in case
|
||||
of WSAEWOULDBLOCK condition.
|
||||
(fhandler_socket::set_close_on_exec): Call
|
||||
fhandler_base::set_close_on_exec.
|
||||
* net.cc (fdsock): Just set socket to inheritable on non-NT. Don't
|
||||
call inc_need_fixup_before.
|
||||
* select.cc (peek_socket): Don't set except_ready on every FD_CLOSE,
|
||||
just on error.
|
||||
|
||||
2006-07-26 Brian ford <Brian.Ford@FlightSafety.com>
|
||||
|
||||
* fhandler.cc (fhandler_base::read): Call get_readahead_into_buffer
|
||||
|
|
|
@ -418,7 +418,6 @@ class fhandler_socket: public fhandler_base
|
|||
void af_local_set_sockpair_cred ();
|
||||
|
||||
private:
|
||||
struct _WSAPROTOCOL_INFOA *prot_info_ptr;
|
||||
char *sun_path;
|
||||
struct status_flags
|
||||
{
|
||||
|
@ -481,10 +480,7 @@ class fhandler_socket: public fhandler_base
|
|||
int dup (fhandler_base *child);
|
||||
|
||||
void set_close_on_exec (bool val);
|
||||
virtual void fixup_before_fork_exec (DWORD);
|
||||
void fixup_after_fork (HANDLE);
|
||||
void fixup_after_exec ();
|
||||
bool need_fixup_before () const {return true;}
|
||||
char *get_proc_fd_name (char *buf);
|
||||
|
||||
select_record *select_read (select_record *s);
|
||||
|
|
|
@ -136,22 +136,10 @@ fhandler_socket::fhandler_socket () :
|
|||
status ()
|
||||
{
|
||||
need_fork_fixup (true);
|
||||
prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
|
||||
sizeof (WSAPROTOCOL_INFOA));
|
||||
#if 0
|
||||
if (pc.is_fs_special ())
|
||||
{
|
||||
fhandler_socket * fhs = (fhandler_socket *) fh;
|
||||
fhs->set_addr_family (AF_LOCAL);
|
||||
fhs->set_sun_path (posix_path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fhandler_socket::~fhandler_socket ()
|
||||
{
|
||||
if (prot_info_ptr)
|
||||
cfree (prot_info_ptr);
|
||||
if (sun_path)
|
||||
cfree (sun_path);
|
||||
}
|
||||
|
@ -398,7 +386,7 @@ struct wsa_event
|
|||
{
|
||||
LONG serial_number;
|
||||
long events;
|
||||
int connect_errorcode;
|
||||
int errorcode;
|
||||
pid_t owner;
|
||||
};
|
||||
|
||||
|
@ -520,7 +508,9 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
|
|||
LOCK_EVENTS;
|
||||
wsock_events->events |= evts.lNetworkEvents;
|
||||
if (evts.lNetworkEvents & FD_CONNECT)
|
||||
wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
|
||||
wsock_events->errorcode = evts.iErrorCode[FD_CONNECT_BIT];
|
||||
else if (evts.lNetworkEvents & FD_CLOSE)
|
||||
wsock_events->errorcode = evts.iErrorCode[FD_CLOSE_BIT];
|
||||
UNLOCK_EVENTS;
|
||||
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
|
||||
kill (wsock_events->owner, SIGURG);
|
||||
|
@ -530,16 +520,22 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
|
|||
LOCK_EVENTS;
|
||||
if ((events = (wsock_events->events & event_mask)) != 0)
|
||||
{
|
||||
if (events & FD_CONNECT)
|
||||
if (events & (FD_CONNECT | FD_CLOSE))
|
||||
{
|
||||
int wsa_err = 0;
|
||||
if ((wsa_err = wsock_events->connect_errorcode) != 0)
|
||||
if ((wsa_err = wsock_events->errorcode) != 0)
|
||||
{
|
||||
WSASetLastError (wsa_err);
|
||||
ret = SOCKET_ERROR;
|
||||
}
|
||||
wsock_events->connect_errorcode = 0;
|
||||
wsock_events->events &= ~FD_CONNECT;
|
||||
if (events & FD_CONNECT)
|
||||
{
|
||||
if (!wsock_events->errorcode)
|
||||
wsock_events->events |= FD_WRITE;
|
||||
wsock_events->events &= ~FD_CONNECT;
|
||||
}
|
||||
if (!(events & FD_CLOSE))
|
||||
wsock_events->errorcode = 0;
|
||||
}
|
||||
if (erase)
|
||||
wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
|
||||
|
@ -598,84 +594,29 @@ fhandler_socket::release_events ()
|
|||
CloseHandle (wsock_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
|
||||
{
|
||||
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
|
||||
{
|
||||
debug_printf ("WSADuplicateSocket error, sock %p, win_proc_id %d, prot_info_ptr %p",
|
||||
get_socket (), win_proc_id, prot_info_ptr);
|
||||
set_winsock_errno ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::fixup_after_fork (HANDLE parent)
|
||||
{
|
||||
SOCKET new_sock;
|
||||
|
||||
debug_printf ("WSASocket begin, dwServiceFlags1=%d",
|
||||
prot_info_ptr->dwServiceFlags1);
|
||||
|
||||
if ((new_sock = WSASocketA (FROM_PROTOCOL_INFO,
|
||||
FROM_PROTOCOL_INFO,
|
||||
FROM_PROTOCOL_INFO,
|
||||
prot_info_ptr, 0, 0)) == INVALID_SOCKET)
|
||||
{
|
||||
debug_printf ("WSASocket error");
|
||||
set_io_handle ((HANDLE)INVALID_SOCKET);
|
||||
set_winsock_errno ();
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_socket ());
|
||||
|
||||
/* Go figure! Even though the original socket was not inheritable,
|
||||
the duplicated socket is inheritable again. This can lead to all
|
||||
sorts of trouble, apparently. Note that there's no way to prevent
|
||||
this on 9x, not even by trying to reset socket inheritance using
|
||||
DuplicateHandle and closing the original socket. */
|
||||
if (wincap.has_set_handle_information ())
|
||||
SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
|
||||
|
||||
set_io_handle ((HANDLE) new_sock);
|
||||
}
|
||||
if (parent) /* fork, not exec or dup */
|
||||
{
|
||||
fork_fixup (parent, wsock_mtx, "wsock_mtx");
|
||||
fork_fixup (parent, wsock_evt, "wsock_evt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::fixup_after_exec ()
|
||||
{
|
||||
if (!close_on_exec ())
|
||||
fixup_after_fork (NULL);
|
||||
fork_fixup (parent, wsock_mtx, "wsock_mtx");
|
||||
fork_fixup (parent, wsock_evt, "wsock_evt");
|
||||
fhandler_base::fixup_after_fork (parent);
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_socket::dup (fhandler_base *child)
|
||||
{
|
||||
HANDLE nh;
|
||||
|
||||
debug_printf ("here");
|
||||
fhandler_socket *fhs = (fhandler_socket *) child;
|
||||
|
||||
if (!DuplicateHandle (hMainProc, wsock_mtx, hMainProc, &fhs->wsock_mtx, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
system_printf ("DuplicateHandle(%x) failed, %E", wsock_mtx);
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
if (!DuplicateHandle (hMainProc, wsock_evt, hMainProc, &fhs->wsock_evt, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
system_printf ("DuplicateHandle(%x) failed, %E", wsock_evt);
|
||||
__seterrno ();
|
||||
CloseHandle (fhs->wsock_mtx);
|
||||
return -1;
|
||||
|
@ -698,48 +639,13 @@ fhandler_socket::dup (fhandler_base *child)
|
|||
}
|
||||
}
|
||||
fhs->connect_state (connect_state ());
|
||||
|
||||
/* 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 ())
|
||||
int ret = fhandler_base::dup (child);
|
||||
if (ret)
|
||||
{
|
||||
/* Call with NULL parent, otherwise wsock_mtx and wsock_evt are
|
||||
duplicated again with wrong close_on_exec settings. */
|
||||
fhs->fixup_after_fork (NULL);
|
||||
if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
|
||||
{
|
||||
cygheap->fdtab.inc_need_fixup_before ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
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,
|
||||
FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
system_printf ("DuplicateHandle(%x) failed, %E", get_io_handle ());
|
||||
__seterrno ();
|
||||
CloseHandle (fhs->wsock_evt);
|
||||
CloseHandle (fhs->wsock_mtx);
|
||||
return -1;
|
||||
}
|
||||
VerifyHandle (nh);
|
||||
fhs->set_io_handle (nh);
|
||||
cygheap->fdtab.inc_need_fixup_before ();
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
|
@ -1379,7 +1285,8 @@ fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
|
|||
wsock_events->events &= ~FD_WRITE;
|
||||
UNLOCK_EVENTS;
|
||||
}
|
||||
while (res && err && !(res = wait_for_events (FD_WRITE | FD_CLOSE)));
|
||||
while (res && err == WSAEWOULDBLOCK
|
||||
&& !(res = wait_for_events (FD_WRITE | FD_CLOSE)));
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
set_winsock_errno ();
|
||||
|
@ -1682,7 +1589,7 @@ fhandler_socket::set_close_on_exec (bool val)
|
|||
{
|
||||
set_no_inheritance (wsock_mtx, val);
|
||||
set_no_inheritance (wsock_evt, val);
|
||||
close_on_exec (val);
|
||||
fhandler_base::set_close_on_exec (val);
|
||||
debug_printf ("set close_on_exec for %s to %d", get_name (), val);
|
||||
}
|
||||
|
||||
|
|
|
@ -501,14 +501,16 @@ cygwin_getprotobynumber (int number)
|
|||
bool
|
||||
fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
|
||||
{
|
||||
if (wincap.has_set_handle_information ())
|
||||
/* NT systems apparently set sockets to inheritable by default */
|
||||
if (!wincap.has_set_handle_information ()
|
||||
&& !DuplicateHandle (hMainProc, (HANDLE) soc,
|
||||
hMainProc, (HANDLE *) &soc,
|
||||
0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
||||
{
|
||||
/* NT systems apparently set sockets to inheritable by default */
|
||||
SetHandleInformation ((HANDLE) soc, HANDLE_FLAG_INHERIT, 0);
|
||||
debug_printf ("reset socket inheritance");
|
||||
debug_printf ("set socket inheritance failed, %E");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
debug_printf ("not setting socket inheritance");
|
||||
fd = build_fh_dev (*dev);
|
||||
if (!fd.isopen ())
|
||||
return false;
|
||||
|
@ -517,7 +519,6 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
|
|||
return false;
|
||||
fd->set_flags (O_RDWR | O_BINARY);
|
||||
fd->uninterruptible_io (true);
|
||||
cygheap->fdtab.inc_need_fixup_before ();
|
||||
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc);
|
||||
#if 0
|
||||
/* Same default buffer sizes as on Linux (instead of WinSock default 8K).
|
||||
|
|
|
@ -1279,7 +1279,7 @@ peek_socket (select_record *me, bool)
|
|||
me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE));
|
||||
}
|
||||
if (me->except_selected)
|
||||
me->except_ready |= ret || !!(events & (FD_OOB | FD_CLOSE));
|
||||
me->except_ready |= ret || !!(events & FD_OOB);
|
||||
|
||||
return me->read_ready || me->write_ready || me->except_ready;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue