Я пытаюсь обработать подключение к сокету из другого процесса, асинхронно обрабатывая SIGALRM из функции alarm
. Чтобы смоделировать и проверить это, я использую команды Linux nc 127.0.0.1 [port]
и kill -14 $(myprocess)
. Однако при выполнении команды kill
, за которой следует команда nc
, select
мгновенно возвращается в бесконечном цикле, как в моде. Код C, содержащий оператор select
, приведен ниже.
int main() {
int port = 4555;
int master_sockfd;
bind_and_listen(&master_sockfd, port);
signal(SIGALRM, handle_alarm);
for (;;) {
fd_set readfds;
int max_fd = master_sockfd;
FD_ZERO(&readfds);
FD_SET(master_sockfd, &readfds);
printf("waiting for master_sockfd to be set\n");
int activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR)) {
perror("select() ");
exit(EXIT_FAILURE);
} else if (errno == EINTR) {
perror("select() ");
if (FD_ISSET(master_sockfd, &readfds)) {
printf("Why is sockfd ready for I/O if select was interrupted with a signal?\n");
}
continue;
} else if (FD_ISSET(master_sockfd, &readfds)) {
printf("Reading from socket\n");
// handle client
}
}
return 0;
}
void handle_alarm() {
printf("handling alarm\n");
}
Затем при выполнении kill -14 $(myprocess); nc 127.0.0.1 4555
Вывод будет следующим:
select() : Interrupted system call
Why is sockfd ready for I/O if select was interrupted with a signal?
waiting for master_sockfd to be set
select() : Interrupted system call
Why is sockfd ready for I/O if select was interrupted with a signal?
waiting for master_sockfd to be set
select() : Interrupted system call
Why is sockfd ready for I/O if select was interrupted with a signal?
waiting for master_sockfd to be set
.
.
.
, который печатается бесконечно.
Почему это происходит?