Всем доброго времени суток.
Имеется программа на Си которая обрабатывает входящие подключения при помощи kqueue и каждое подключение отправляет на обработку в отдельный тред:
int main(int argc, char **argv) {
...
#ifdef __FreeBSD__
// Create kqueue
int kq;
kq = kqueue();
if (kq < 0) {
perror("kqueue");
exit(EXIT_FAILURE);
}
// Register server socket with kqueue
for read events
struct kevent ev;
EV_SET(&ev, listen_sock, EVFILT_READ, EV_ADD, 0, 0, NULL);
if (kevent(kq, &ev, 1, NULL, 0, NULL) < 0) {
perror(«kevent»);
exit(EXIT_FAILURE);
}
// Loop for handling events
while (1) {
struct kevent event;
int n = kevent(kq, NULL, 0, &event, 1, NULL);
if (n < 0) {
perror(«kevent»);
exit(EXIT_SUCCESS);
}
//int *arg;
if ((int)event.ident == listen_sock) {
int client_socket = accept(listen_sock, NULL, NULL);
if (client_socket < 0) {
perror(«accept»);
exit(EXIT_FAILURE);
}
int *arg = malloc(sizeof(*arg));
*arg = client_socket;
pthread_t tid;
if (pthread_create(&tid, NULL, handle_client, arg) != 0) {
perror(«pthread_create»);
free(arg);
continue;
}
pthread_detach(tid);
}
}
#endif
}
Программа пишет в лог в отдельный файл. Возникла необходимость сделать ротацию логов. Ротация логов осуществляется стандартно: переименовывается текущий лог и отправляется программе SIGUSR1 чтоб она переоткрыла лог файл. Следовтельно, нужно чтоб программа перехватывала SIGUSR1 и переоткрывала лог файл.
Для этого в main()
вешаю обработчик SIGUSR1:
signal(SIGUSR1, sigusr1_handler);
void sigusr1_handler(int signal_num) {
printf("Got SIGUSR1!\n");
}
В итоге получаю ошибку: kevent: Interrupted system call
Вот трейс:
Thread 1 received signal SIGUSR1, User defined signal 1.
Sent by kill() from pid 39787 and user 1001.
0x000000080105341a in _kevent () from /lib/libc.so.7
(gdb) bt
#0 0x000000080105341a in _kevent () from /lib/libc.so.7
#1 0x0000000800f1cb81 in ?? () from /lib/libthr.so.3
#2 0x00000000002088e9 in main (argc=3, argv=0x7fffffffe460) at main.c:387
(gdb) list main.c:387
382 }
383
384 // Loop for handling events
385 while (1) {
386 struct kevent event;
387 int n = kevent(kq, NULL, 0, &event, 1, NULL);
388
389 if (n < 0) {
390 perror("kevent");
391 exit(EXIT_FAILURE);
kqueue
& kevent
(если убрать все внутри цикла while(1)
) все работает отлично: сигнал перехватывается, обрабатывается и программа продолжает работу.Собственно вопрос: как корректно обработать сигнал в случае использования kqueue, выполнить нужные действия и продолжить работу программы?