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:
authorCorinna Vinschen <corinna@vinschen.de>2002-07-05 22:26:23 +0400
committerCorinna Vinschen <corinna@vinschen.de>2002-07-05 22:26:23 +0400
commitd5591d9df67a1425a8c05f22cbde430c4a93627f (patch)
tree96201f8ba2ad69fb41b3dd47a170d65c62f59fd5 /winsup/cygwin
parent89ffbd66e7747dd3719b1252e4037805385c8237 (diff)
* fhandler.h (UNCONNECTED): New define.
(CONNECT_PENDING): Ditto. (CONNECTED): Ditto. (class fhandler_socket): Add member `had_connect_or_listen'. Add member functions `is_unconnected', `is_connect_pending' and `is_connected'. * fhandler_socket.cc (fhandler_socket::connect): Set member `had_connect_or_listen' according to return code of WinSock call. (fhandler_socket::listen): Ditto. * net.cc (cygwin_getsockopt): Modify SO_ERROR return value in case of socket with pending connect(). * select.cc (peek_socket): Only add socket to matching fd_set if it's not "ready". Call WINSOCK_SELECT only if at least one socket is in one of the fd_sets. (start_thread_socket): Only add socket to matching fd_set if it's not "ready". (fhandler_socket::select_write): Set write_ready to true also if socket isn't connected or listening.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog22
-rw-r--r--winsup/cygwin/fhandler.h9
-rw-r--r--winsup/cygwin/fhandler_socket.cc6
-rw-r--r--winsup/cygwin/net.cc2
-rw-r--r--winsup/cygwin/select.cc45
5 files changed, 64 insertions, 20 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 15f24ae98..849e5a623 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,25 @@
+2002-07-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (UNCONNECTED): New define.
+ (CONNECT_PENDING): Ditto.
+ (CONNECTED): Ditto.
+ (class fhandler_socket): Add member `had_connect_or_listen'.
+ Add member functions `is_unconnected', `is_connect_pending' and
+ `is_connected'.
+ * fhandler_socket.cc (fhandler_socket::connect): Set member
+ `had_connect_or_listen' according to return code of WinSock
+ call.
+ (fhandler_socket::listen): Ditto.
+ * net.cc (cygwin_getsockopt): Modify SO_ERROR return value in
+ case of socket with pending connect().
+ * select.cc (peek_socket): Only add socket to matching fd_set
+ if it's not "ready". Call WINSOCK_SELECT only if at least one
+ socket is in one of the fd_sets.
+ (start_thread_socket): Only add socket to matching fd_set
+ if it's not "ready".
+ (fhandler_socket::select_write): Set write_ready to true also
+ if socket isn't connected or listening.
+
2002-07-04 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::set_sun_path): Don't free
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 5727d24ab..980957a67 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -101,6 +101,10 @@ enum
both flags are set. */
#define O_NONBLOCK_MASK (O_NONBLOCK | OLD_O_NDELAY)
+#define UNCONNECTED 0
+#define CONNECT_PENDING 1
+#define CONNECTED 2
+
extern const char *windows_device_names[];
extern struct __cygwin_perfile *perfile_table;
#define __fmode (*(user_data->fmode_ptr))
@@ -367,6 +371,7 @@ class fhandler_socket: public fhandler_base
HANDLE secret_event;
struct _WSAPROTOCOL_INFOA *prot_info_ptr;
char *sun_path;
+ int had_connect_or_listen;
public:
fhandler_socket ();
@@ -380,6 +385,10 @@ class fhandler_socket: public fhandler_base
void set_shutdown_read () {FHSETF (SHUTRD);}
void set_shutdown_write () {FHSETF (SHUTWR);}
+ bool is_unconnected () {return had_connect_or_listen == UNCONNECTED;}
+ bool is_connect_pending () {return had_connect_or_listen == CONNECT_PENDING;}
+ bool is_connected () {return had_connect_or_listen == CONNECTED;}
+
int bind (const struct sockaddr *name, int namelen);
int connect (const struct sockaddr *name, int namelen);
int listen (int backlog);
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 7970e4b63..e95655510 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -455,6 +455,10 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
}
}
+ if (!res)
+ had_connect_or_listen = CONNECTED;
+ else if (WSAGetLastError () == WSAEINPROGRESS)
+ had_connect_or_listen = CONNECT_PENDING;
return res;
}
@@ -464,6 +468,8 @@ fhandler_socket::listen (int backlog)
int res = ::listen (get_socket (), backlog);
if (res)
set_winsock_errno ();
+ else
+ had_connect_or_listen = CONNECTED;
return res;
}
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 870bf7865..1445ae683 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -712,6 +712,8 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen)
if (optname == SO_ERROR)
{
int *e = (int *) optval;
+ if (!*e && fh->is_connect_pending ())
+ *e = WSAEINPROGRESS;
*e = find_winsock_errno (*e);
}
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index b50ffb1f2..46f0c6963 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -1180,39 +1180,44 @@ peek_socket (select_record *me, bool)
set_handle_or_return_if_not_open (h, me);
select_printf ("considering handle %p", h);
- if (me->read_selected)
+ if (me->read_selected && !me->read_ready)
{
select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (),
me->fd);
WINSOCK_FD_SET (h, &ws_readfds);
}
- if (me->write_selected)
+ if (me->write_selected && !me->write_ready)
{
select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (),
me->fd);
WINSOCK_FD_SET (h, &ws_writefds);
}
- if (me->except_selected)
+ if (me->except_selected && !me->except_ready)
{
select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (),
me->fd);
WINSOCK_FD_SET (h, &ws_exceptfds);
}
- int r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
- select_printf ("WINSOCK_SELECT returned %d", r);
- if (r == -1)
+ int r;
+ if ((me->read_selected && !me->read_ready)
+ || (me->write_selected && !me->write_ready)
+ || (me->except_selected && !me->except_ready))
{
- select_printf ("error %d", WSAGetLastError ());
- set_winsock_errno ();
- return 0;
+ r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
+ select_printf ("WINSOCK_SELECT returned %d", r);
+ if (r == -1)
+ {
+ select_printf ("error %d", WSAGetLastError ());
+ set_winsock_errno ();
+ return 0;
+ }
+ if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
+ me->read_ready = true;
+ if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
+ me->write_ready = true;
+ if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready))
+ me->except_ready = true;
}
-
- if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
- me->read_ready = true;
- if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
- me->write_ready = true;
- if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready))
- me->except_ready = true;
return me->read_ready || me->write_ready || me->except_ready;
}
@@ -1280,17 +1285,17 @@ start_thread_socket (select_record *me, select_stuff *stuff)
{
HANDLE h = s->fh->get_handle ();
select_printf ("Handle %p", h);
- if (s->read_selected)
+ if (s->read_selected && !s->read_ready)
{
WINSOCK_FD_SET (h, &si->readfds);
select_printf ("Added to readfds");
}
- if (s->write_selected)
+ if (s->write_selected && !s->write_ready)
{
WINSOCK_FD_SET (h, &si->writefds);
select_printf ("Added to writefds");
}
- if (s->except_selected)
+ if (s->except_selected && !s->except_ready)
{
WINSOCK_FD_SET (h, &si->exceptfds);
select_printf ("Added to exceptfds");
@@ -1410,7 +1415,7 @@ fhandler_socket::select_write (select_record *s)
s->cleanup = socket_cleanup;
}
s->peek = peek_socket;
- s->write_ready = saw_shutdown_write ();
+ s->write_ready = saw_shutdown_write () || !is_connected ();
s->write_selected = true;
return s;
}