LINUX.ORG.RU

История изменений

Исправление 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;