* 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:
Corinna Vinschen 2006-07-27 09:11:38 +00:00
parent 40f67ea198
commit 9869e006f3
5 changed files with 58 additions and 128 deletions

View File

@ -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> 2006-07-26 Brian ford <Brian.Ford@FlightSafety.com>
* fhandler.cc (fhandler_base::read): Call get_readahead_into_buffer * fhandler.cc (fhandler_base::read): Call get_readahead_into_buffer

View File

@ -418,7 +418,6 @@ class fhandler_socket: public fhandler_base
void af_local_set_sockpair_cred (); void af_local_set_sockpair_cred ();
private: private:
struct _WSAPROTOCOL_INFOA *prot_info_ptr;
char *sun_path; char *sun_path;
struct status_flags struct status_flags
{ {
@ -481,10 +480,7 @@ class fhandler_socket: public fhandler_base
int dup (fhandler_base *child); int dup (fhandler_base *child);
void set_close_on_exec (bool val); void set_close_on_exec (bool val);
virtual void fixup_before_fork_exec (DWORD);
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
void fixup_after_exec ();
bool need_fixup_before () const {return true;}
char *get_proc_fd_name (char *buf); char *get_proc_fd_name (char *buf);
select_record *select_read (select_record *s); select_record *select_read (select_record *s);

View File

@ -136,22 +136,10 @@ fhandler_socket::fhandler_socket () :
status () status ()
{ {
need_fork_fixup (true); 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 () fhandler_socket::~fhandler_socket ()
{ {
if (prot_info_ptr)
cfree (prot_info_ptr);
if (sun_path) if (sun_path)
cfree (sun_path); cfree (sun_path);
} }
@ -398,7 +386,7 @@ struct wsa_event
{ {
LONG serial_number; LONG serial_number;
long events; long events;
int connect_errorcode; int errorcode;
pid_t owner; pid_t owner;
}; };
@ -520,7 +508,9 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
LOCK_EVENTS; LOCK_EVENTS;
wsock_events->events |= evts.lNetworkEvents; wsock_events->events |= evts.lNetworkEvents;
if (evts.lNetworkEvents & FD_CONNECT) 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; UNLOCK_EVENTS;
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner) if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
kill (wsock_events->owner, SIGURG); kill (wsock_events->owner, SIGURG);
@ -530,17 +520,23 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
LOCK_EVENTS; LOCK_EVENTS;
if ((events = (wsock_events->events & event_mask)) != 0) if ((events = (wsock_events->events & event_mask)) != 0)
{ {
if (events & FD_CONNECT) if (events & (FD_CONNECT | FD_CLOSE))
{ {
int wsa_err = 0; int wsa_err = 0;
if ((wsa_err = wsock_events->connect_errorcode) != 0) if ((wsa_err = wsock_events->errorcode) != 0)
{ {
WSASetLastError (wsa_err); WSASetLastError (wsa_err);
ret = SOCKET_ERROR; ret = SOCKET_ERROR;
} }
wsock_events->connect_errorcode = 0; if (events & FD_CONNECT)
{
if (!wsock_events->errorcode)
wsock_events->events |= FD_WRITE;
wsock_events->events &= ~FD_CONNECT; wsock_events->events &= ~FD_CONNECT;
} }
if (!(events & FD_CLOSE))
wsock_events->errorcode = 0;
}
if (erase) if (erase)
wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE)); wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
} }
@ -598,84 +594,29 @@ fhandler_socket::release_events ()
CloseHandle (wsock_mtx); 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 void
fhandler_socket::fixup_after_fork (HANDLE parent) 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_mtx, "wsock_mtx");
fork_fixup (parent, wsock_evt, "wsock_evt"); fork_fixup (parent, wsock_evt, "wsock_evt");
} fhandler_base::fixup_after_fork (parent);
}
void
fhandler_socket::fixup_after_exec ()
{
if (!close_on_exec ())
fixup_after_fork (NULL);
} }
int int
fhandler_socket::dup (fhandler_base *child) fhandler_socket::dup (fhandler_base *child)
{ {
HANDLE nh;
debug_printf ("here"); debug_printf ("here");
fhandler_socket *fhs = (fhandler_socket *) child; fhandler_socket *fhs = (fhandler_socket *) child;
if (!DuplicateHandle (hMainProc, wsock_mtx, hMainProc, &fhs->wsock_mtx, 0, if (!DuplicateHandle (hMainProc, wsock_mtx, hMainProc, &fhs->wsock_mtx, 0,
TRUE, DUPLICATE_SAME_ACCESS)) TRUE, DUPLICATE_SAME_ACCESS))
{ {
system_printf ("DuplicateHandle(%x) failed, %E", wsock_mtx);
__seterrno (); __seterrno ();
return -1; return -1;
} }
if (!DuplicateHandle (hMainProc, wsock_evt, hMainProc, &fhs->wsock_evt, 0, if (!DuplicateHandle (hMainProc, wsock_evt, hMainProc, &fhs->wsock_evt, 0,
TRUE, DUPLICATE_SAME_ACCESS)) TRUE, DUPLICATE_SAME_ACCESS))
{ {
system_printf ("DuplicateHandle(%x) failed, %E", wsock_evt);
__seterrno (); __seterrno ();
CloseHandle (fhs->wsock_mtx); CloseHandle (fhs->wsock_mtx);
return -1; return -1;
@ -698,48 +639,13 @@ fhandler_socket::dup (fhandler_base *child)
} }
} }
fhs->connect_state (connect_state ()); fhs->connect_state (connect_state ());
int ret = fhandler_base::dup (child);
/* Since WSADuplicateSocket() fails on NT systems when the process if (ret)
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 ())
{ {
/* 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_evt);
CloseHandle (fhs->wsock_mtx); CloseHandle (fhs->wsock_mtx);
return -1;
} }
VerifyHandle (nh); return ret;
fhs->set_io_handle (nh);
cygheap->fdtab.inc_need_fixup_before ();
return 0;
} }
int __stdcall int __stdcall
@ -1379,7 +1285,8 @@ fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
wsock_events->events &= ~FD_WRITE; wsock_events->events &= ~FD_WRITE;
UNLOCK_EVENTS; 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) if (res == SOCKET_ERROR)
set_winsock_errno (); 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_mtx, val);
set_no_inheritance (wsock_evt, 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); debug_printf ("set close_on_exec for %s to %d", get_name (), val);
} }

View File

@ -500,15 +500,17 @@ cygwin_getprotobynumber (int number)
bool bool
fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc) fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
{
if (wincap.has_set_handle_information ())
{ {
/* NT systems apparently set sockets to inheritable by default */ /* NT systems apparently set sockets to inheritable by default */
SetHandleInformation ((HANDLE) soc, HANDLE_FLAG_INHERIT, 0); if (!wincap.has_set_handle_information ()
debug_printf ("reset socket inheritance"); && !DuplicateHandle (hMainProc, (HANDLE) soc,
hMainProc, (HANDLE *) &soc,
0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
{
debug_printf ("set socket inheritance failed, %E");
return false;
} }
else
debug_printf ("not setting socket inheritance");
fd = build_fh_dev (*dev); fd = build_fh_dev (*dev);
if (!fd.isopen ()) if (!fd.isopen ())
return false; return false;
@ -517,7 +519,6 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
return false; return false;
fd->set_flags (O_RDWR | O_BINARY); fd->set_flags (O_RDWR | O_BINARY);
fd->uninterruptible_io (true); fd->uninterruptible_io (true);
cygheap->fdtab.inc_need_fixup_before ();
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc); debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc);
#if 0 #if 0
/* Same default buffer sizes as on Linux (instead of WinSock default 8K). /* Same default buffer sizes as on Linux (instead of WinSock default 8K).

View File

@ -1279,7 +1279,7 @@ peek_socket (select_record *me, bool)
me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE)); me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE));
} }
if (me->except_selected) 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; return me->read_ready || me->write_ready || me->except_ready;
} }