summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorscottc <scottc>2002-07-06 22:28:18 +0000
committerscottc <scottc>2002-07-06 22:28:18 +0000
commit4f1c2f17a9eba559ffbbeefc7742f14cf3bbd021 (patch)
tree1a84ed35064f40d2e6ff321607038381c395d728 /winsup
parent4f1067b288880016e1f82df4d9cd5950fa5257f1 (diff)
downloadgdb-4f1c2f17a9eba559ffbbeefc7742f14cf3bbd021.tar.gz
Merged changes from HEAD
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog50
-rw-r--r--winsup/cygwin/fhandler.h18
-rw-r--r--winsup/cygwin/fhandler_socket.cc6
-rw-r--r--winsup/cygwin/ntdll.h4
-rw-r--r--winsup/cygwin/path.cc70
-rw-r--r--winsup/cygwin/select.cc63
6 files changed, 150 insertions, 61 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c073b409d9f..8f8c2016169 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,53 @@
+2002-07-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (fhandler_socket::is_unconnected): Constify.
+ (fhandler_socket::is_connect_pending): Ditto.
+ (fhandler_socket::is_connected): Ditto.
+ (fhandler_socket::set_connect_state): New method.
+ (struct select_record): Add member `except_on_write'.
+ (select_record::select_record): Initialize all bool values to `false'.
+ * fhandler_socket.cc: Use set_connect_state() method throughout.
+ (fhandler_socket::connect): Set state always to connected if connection
+ isn't pending.
+ * net.cc (cygwin_getsockopt): Revert erroneous previous patch.
+ * select.cc (set_bits): Check for `except_on_write'. Set fd in
+ write_fds if set. Set connect state to connected if fd has been
+ returned by WINSOCK_SELECT.
+ (peek_socket): Check for `except_on_write'.
+ (start_thread_socket): Ditto.
+ (fhandler_socket::select_write): Don't set `write_ready' if connect
+ is pending. Set `except_on_write' if connect is pending.
+
+2002-07-05 Christopher Faylor <cgf@redhat.com>
+
+ * ntdll.h (_SYSTEM_PROCESSOR_TIMES): Force eight byte alignment.
+ (_SYSTEM_TIME_OF_DAY_INFORMATION): Ditto.
+
+ * path.cc (suffix_scan::has): Reorganize to eliminate double scanning
+ for for .exe (in the typical case).
+
+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 5727d24ab10..164a892d1fe 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,11 @@ class fhandler_socket: public fhandler_base
void set_shutdown_read () {FHSETF (SHUTRD);}
void set_shutdown_write () {FHSETF (SHUTWR);}
+ bool is_unconnected () const {return had_connect_or_listen == UNCONNECTED;}
+ bool is_connect_pending () const {return had_connect_or_listen == CONNECT_PENDING;}
+ bool is_connected () const {return had_connect_or_listen == CONNECTED;}
+ void set_connect_state (int newstate) { had_connect_or_listen = newstate; }
+
int bind (const struct sockaddr *name, int namelen);
int connect (const struct sockaddr *name, int namelen);
int listen (int backlog);
@@ -1176,6 +1186,7 @@ struct select_record
bool windows_handle;
bool read_ready, write_ready, except_ready;
bool read_selected, write_selected, except_selected;
+ bool except_on_write;
int (*startup) (select_record *me, class select_stuff *stuff);
int (*peek) (select_record *, bool);
int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
@@ -1184,9 +1195,10 @@ struct select_record
struct select_record *next;
select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
- fh (in_fh), saw_error (0), windows_handle (0),
- read_ready (0), write_ready (0), except_ready (0),
- read_selected (0), write_selected (0), except_selected (0),
+ fh (in_fh), saw_error (false), windows_handle (false),
+ read_ready (false), write_ready (false), except_ready (false),
+ read_selected (false), write_selected (false),
+ except_selected (false), except_on_write (false),
startup (NULL), peek (NULL), verify (NULL), cleanup (NULL),
next (NULL) {}
};
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 7970e4b63b0..aed61d78036 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 (WSAGetLastError () == WSAEINPROGRESS)
+ set_connect_state (CONNECT_PENDING);
+ else
+ set_connect_state (CONNECTED);
return res;
}
@@ -464,6 +468,8 @@ fhandler_socket::listen (int backlog)
int res = ::listen (get_socket (), backlog);
if (res)
set_winsock_errno ();
+ else
+ set_connect_state (CONNECTED);
return res;
}
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index f10d27dcf46..00a0ac71716 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -50,7 +50,7 @@ typedef struct _SYSTEM_BASIC_INFORMATION
UCHAR NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
-typedef struct _SYSTEM_PROCESSOR_TIMES
+typedef struct __attribute__ ((aligned (8))) _SYSTEM_PROCESSOR_TIMES
{
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
@@ -244,7 +244,7 @@ typedef struct _SYSTEM_PERFORMANCE_INFORMATION
ULONG SystemCalls;
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
-typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
+typedef struct __attribute__ ((aligned(8))) _SYSTEM_TIME_OF_DAY_INFORMATION
{
LARGE_INTEGER BootTime;
LARGE_INTEGER CurrentTime;
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index ed76f941e45..c09b4591f37 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2822,8 +2822,43 @@ suffix_scan::has (const char *in_path, const suffix_info *in_suffixes)
int
suffix_scan::next ()
{
- if (suffixes)
+ for (;;)
{
+ if (!suffixes)
+ switch (nextstate)
+ {
+ case SCAN_BEG:
+ suffixes = suffixes_start;
+ if (!suffixes)
+ {
+ nextstate = SCAN_LNK;
+ return 1;
+ }
+ if (!*suffixes->name)
+ suffixes++;
+ nextstate = SCAN_EXTRALNK;
+ /* fall through to suffix checking below */
+ break;
+ case SCAN_HASLNK:
+ nextstate = SCAN_EXTRALNK; /* Skip SCAN_BEG */
+ return 1;
+ case SCAN_LNK:
+ case SCAN_EXTRALNK:
+ strcpy (eopath, ".lnk");
+ nextstate = SCAN_DONE;
+ return 1;
+ case SCAN_JUSTCHECK:
+ nextstate = SCAN_APPENDLNK;
+ return 1;
+ case SCAN_APPENDLNK:
+ strcat (eopath, ".lnk");
+ nextstate = SCAN_DONE;
+ return 1;
+ default:
+ *eopath = '\0';
+ return 0;
+ }
+
while (suffixes && suffixes->name)
if (!suffixes->addon)
suffixes++;
@@ -2837,39 +2872,6 @@ suffix_scan::next ()
}
suffixes = NULL;
}
-
- switch (nextstate)
- {
- case SCAN_BEG:
- suffixes = suffixes_start;
- if (!suffixes)
- nextstate = SCAN_LNK;
- else
- {
- if (!*suffixes->name)
- suffixes++;
- nextstate = SCAN_EXTRALNK;
- }
- return 1;
- case SCAN_HASLNK:
- nextstate = SCAN_EXTRALNK; /* Skip SCAN_BEG */
- return 1;
- case SCAN_LNK:
- case SCAN_EXTRALNK:
- strcpy (eopath, ".lnk");
- nextstate = SCAN_DONE;
- return 1;
- case SCAN_JUSTCHECK:
- nextstate = SCAN_APPENDLNK;
- return 1;
- case SCAN_APPENDLNK:
- strcat (eopath, ".lnk");
- nextstate = SCAN_DONE;
- return 1;
- default:
- *eopath = '\0';
- return 0;
- }
}
/* Check if PATH is a symlink. PATH must be a valid Win32 path name.
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index b50ffb1f2cc..30e082a2e21 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -336,11 +336,20 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
if (me->write_selected && me->write_ready)
{
UNIX_FD_SET (me->fd, writefds);
+ if (me->except_on_write && me->fh->get_device () == FH_SOCKET)
+ ((fhandler_socket *) me->fh)->set_connect_state (CONNECTED);
ready++;
}
- if (me->except_selected && me->except_ready)
+ if ((me->except_selected || me->except_on_write) && me->except_ready)
{
- UNIX_FD_SET (me->fd, exceptfds);
+ if (me->except_on_write) /* Only on sockets */
+ {
+ UNIX_FD_SET (me->fd, writefds);
+ if (me->fh->get_device () == FH_SOCKET)
+ ((fhandler_socket *) me->fh)->set_connect_state (CONNECTED);
+ }
+ if (me->except_selected)
+ UNIX_FD_SET (me->fd, exceptfds);
ready++;
}
select_printf ("ready %d", ready);
@@ -1180,39 +1189,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_on_write) && !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_on_write) && !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_on_write) && 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 +1294,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_on_write) && !s->except_ready)
{
WINSOCK_FD_SET (h, &si->exceptfds);
select_printf ("Added to exceptfds");
@@ -1410,8 +1424,13 @@ 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_unconnected ();
s->write_selected = true;
+ if (is_connect_pending ())
+ {
+ s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
+ s->except_on_write = true;
+ }
return s;
}