diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2006-07-27 09:11:38 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2006-07-27 09:11:38 +0000 |
commit | 9869e006f3ac34d7bd67fb6327f3605725995abc (patch) | |
tree | a4649e2504fc1caae8493a2583962aacd1cd737e /winsup/cygwin/fhandler_socket.cc | |
parent | 40f67ea198cf8b2bd27e87614065717613b2ff8b (diff) | |
download | cygnal-9869e006f3ac34d7bd67fb6327f3605725995abc.tar.gz cygnal-9869e006f3ac34d7bd67fb6327f3605725995abc.tar.bz2 cygnal-9869e006f3ac34d7bd67fb6327f3605725995abc.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 139 |
1 files changed, 23 insertions, 116 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 63858206d..a6f760a9b 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -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)); @@ -599,83 +595,28 @@ fhandler_socket::release_events () } 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 ()) - { - /* 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)) + int ret = fhandler_base::dup (child); + if (ret) { - 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); } |