История изменений
Исправление 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;