История изменений
Исправление reprimand, (текущая версия) :
По умолчанию сигналы вызывают перезапуск системных вызовов (или это только в glibc так?)
Не вызывают. И даже в glibc не вызывают.
Пруфцы:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <iso646.h>
#include <errno.h>
static void signal_handler(int signo) {
}
int main() {
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
while(1) {
char buf;
ssize_t got = read(STDIN_FILENO, &buf, 1);
if (got < 0 and errno == EINTR) {
puts("I GOT EINTR!\n");
break;
}
}
return EXIT_SUCCESS;
}
Кстати, ты удивишься, сколько всего может сломаться, если вдруг начнет получать EINTR. Больше узнать об этом можно по ключевом слову SA_RESTART в man 2 sigaction
Я не удивляюсь этому ничего, мало того, я еще N лет назад писал коммерческий код который предполагает EINTR и перезапускает системные вызовы. Собственно, так же и делают многие библиотеки, так же и делает библиотека с которой я сейчас работаю. И это _норма_.
ЕМНИП SA_RESTART просто позволяет не перезапускать системные вызовы руками - это происходит автоматически.
Вешаться на SIGINT, а потом рассылать его же кажется не самой хорошей идеей, хотя бы потому что pthread_kill(SIGINT) в теории должен позвать обработчик этого сигнала в «убиваемом» треде и, кажется, тогда наступит неловкая рекурсивная ситуация
Нет, потому что у меня в коде я эту ситуацию избегаю:
if (mypid != main_thread) return;
Исходная версия reprimand, :
По умолчанию сигналы вызывают перезапуск системных вызовов (или это только в glibc так?)
Не вызывают. И даже в glibc не вызывают.
Пруфцы:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <iso646.h>
#include <errno.h>
static void signal_handler(int signo) {
}
int main() {
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
while(1) {
char buf;
ssize_t got = read(STDIN_FILENO, &buf, 1);
if (got < 0 and errno == EINTR) {
puts("I GOT EINTR!\n");
break;
}
}
return EXIT_SUCCESS;
}
Кстати, ты удивишься, сколько всего может сломаться, если вдруг начнет получать EINTR. Больше узнать об этом можно по ключевом слову SA_RESTART в man 2 sigaction
Я не удивляюсь этому ничего, мало того, я еще N лет назад писал коммерческий код который предполагает EINTR и перезапускает системные вызовы. Собственно, так же и делают многие библиотеки, так же и делает библиотека с которой я сейчас работаю. И это _норма_.
ЕМНИП SA_RESTART просто позволяет не перезапускать системные вызова руками - это происходит автоматически.
Вешаться на SIGINT, а потом рассылать его же кажется не самой хорошей идеей, хотя бы потому что pthread_kill(SIGINT) в теории должен позвать обработчик этого сигнала в «убиваемом» треде и, кажется, тогда наступит неловкая рекурсивная ситуация
Нет, потому что у меня в коде я эту ситуацию избегаю:
if (mypid != main_thread) return;