Simplify Windows client to react to Ctrl-C always

When select() gets interrupted by SIGINT while a handler is active
without SA_RESTART, it returns immediately with EINTR.  w32_select()
did that only while it waited for standard input to become ready for
reading.  This isn't the case when:

* The client has already received EOF on standard input.  But then the
  action is SIG_DFL, so there was no problem.

* Reading standard input is suspended until the server drains the
  input buffer.  Then reaction to Ctrl-C got delayed until the socket
  got ready, and w32_select() returned normally.  Harmless, because
  the reaction merely appends to the input buffer.

Change w32_select() to match select()'s behavior anyway.
This commit is contained in:
Markus Armbruster 2009-04-12 11:46:22 +02:00
parent 2bfe7a1198
commit f4209f7ea9

View file

@ -184,24 +184,31 @@ w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval*
{ {
HANDLE handles[3]; HANDLE handles[3];
SOCKET sock; SOCKET sock;
int result, s_result, num_handles = 0; int inp, result, s_result, num_handles;
struct timeval tv_time = {0, 0}; struct timeval tv_time = {0, 0};
fd_set rdfd2; fd_set rdfd2;
if (rdfd->fd_count > 1) { switch (rdfd->fd_count) {
sock = rdfd->fd_array[1]; case 1:
if (rdfd->fd_array[0]) inp = -1;
handles[num_handles++] = (HANDLE)rdfd->fd_array[0];
else {
handles[num_handles++] = ctrl_c_event;
handles[num_handles++] = bounce_full;
}
} else {
assert(rdfd->fd_count == 1);
sock = rdfd->fd_array[0]; sock = rdfd->fd_array[0];
break;
case 2:
inp = rdfd->fd_array[0];
sock = rdfd->fd_array[1];
break;
default:
assert(0);
} }
assert(wrfd->fd_count == 0 ||
(wrfd->fd_count == 1 && wrfd->fd_array[0] == sock)); assert(wrfd->fd_count == 0
|| (wrfd->fd_count == 1 && wrfd->fd_array[0] == sock));
assert(inp < 0 || inp == input_fd);
num_handles = 0;
handles[num_handles++] = ctrl_c_event;
if (inp >= 0)
handles[num_handles++] = inp ? (HANDLE)inp : bounce_full;
/* always wait on the socket */ /* always wait on the socket */
handles[num_handles++] = WSACreateEvent(); handles[num_handles++] = WSACreateEvent();
@ -220,7 +227,7 @@ w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval*
} }
WSACloseEvent(handles[num_handles - 1]); WSACloseEvent(handles[num_handles - 1]);
if (num_handles == 3 && result == WAIT_OBJECT_0) { if (result == WAIT_OBJECT_0) {
errno = EINTR; errno = EINTR;
return -1; return -1;
} }
@ -235,12 +242,8 @@ w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval*
} }
*rdfd = rdfd2; *rdfd = rdfd2;
if (num_handles == 3 && result == WAIT_OBJECT_0 + 1) { if (inp >= 0 && result == WAIT_OBJECT_0 + 1) {
FD_SET((SOCKET)0, rdfd); FD_SET((SOCKET)inp, rdfd);
s_result++;
}
if (num_handles == 2 && result == WAIT_OBJECT_0) {
FD_SET((SOCKET)handles[0], rdfd);
s_result++; s_result++;
} }
return s_result; return s_result;