Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog26
-rw-r--r--winsup/cygwin/fhandler.h4
-rw-r--r--winsup/cygwin/fhandler_socket.cc139
-rw-r--r--winsup/cygwin/net.cc15
-rw-r--r--winsup/cygwin/select.cc2
5 files changed, 58 insertions, 128 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c75a91d73..d3693c526 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 6468560b3..7b9ba7e3b 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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);
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);
}
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 80f34a886..87a413556 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -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).
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index a1abba610..abfe9e5a3 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -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;
}