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:
parent
2bfe7a1198
commit
f4209f7ea9
1 changed files with 24 additions and 21 deletions
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue