Бих искал да напиша SIGSEGV манипулатор, който записва съобщения във файл (FILE *). Чувал съм, че fprintf не е reentrant и не трябва да се извиква в манипулатор на сигнали. Има ли негова версия за повторно влизане или друга функция, която предоставя I/O на форматиран файл, който може да бъде извикан в манипулатор на сигнали?
Форматиран I/O в манипулатора на сигнали
Отговори (1)
Съгласно 7.14.1.1 5 от версия N1570 на стандарта C11:
Ако [the] сигналът възникне [], поведението е недефинирано, ако [] манипулаторът на сигнала извика която и да е функция в стандартната библиотека, различна от функцията
abort
, функцията_Exit
, функциятаquick_exit
или функциятаsignal
[].
Накратко, единствените стандартни библиотечни функции, които можете да извикате, са:
abort
_Exit
quick_exit
signal
(прилагат се допълнителни ограничения)
Очевидно нито една от тях не е форматирана I/O функция, така че ако искате да се придържате към стандартния C, няма какво да направите.
POSIX
Това беше гледната точка на стандарт C. Ако обаче не сте съгласни да сте зависими от POSIX, можете да използвате всяка от неговите async-safe функции. Една от асинхронно безопасните функции е write
, която, както може да очаквате, записва във файл. Необходим е обикновен буфер, така че ако искате да форматирате нещо, ще трябва да го форматирате сами и може също да не можете да разпределите динамично памет. Също така трябва да внимавате с достъпа до глобални и статични променливи: стандартът C казва, че можете да получите достъп до тях само ако типът е volatile sig_atomic_t
.
Прескачането през тези обръчи ще ви позволи да напишете съобщение в манипулатора на сигнали, стига да сте на POSIX платформа. Не е толкова лесно като fprintf
, но ако трябва да го направите, така се прави.