Форматиран I/O в манипулатора на сигнали

Бих искал да напиша SIGSEGV манипулатор, който записва съобщения във файл (FILE *). Чувал съм, че fprintf не е reentrant и не трябва да се извиква в манипулатор на сигнали. Има ли негова версия за повторно влизане или друга функция, която предоставя I/O на форматиран файл, който може да бъде извикан в манипулатор на сигнали?


person user2491608    schedule 16.06.2013    source източник
comment
Възможен дубликат на Print int от манипулатора на сигнали чрез запис или асинхронно безопасни функции   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 20.09.2017


Отговори (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, но ако трябва да го направите, така се прави.

person icktoofay    schedule 16.06.2013