Открытые потоки автоматически очищаются и закрываются на SIGINT в C? - PullRequest
4 голосов
/ 11 января 2010

Я прочитал на странице руководства, что при вызове exit() все потоки автоматически очищаются и закрываются. Сначала я скептически относился к тому, как это было сделано и действительно ли это надежно, но, видя, что я больше не могу это выяснить, я смирюсь с тем, что это просто работает - посмотрим, что-нибудь взорвется. В любом случае, если это поведение закрытия потока присутствует в exit(), такое поведение также присутствует в обработчике по умолчанию для SIGINT (сигнал прерывания обычно запускается с помощью Ctrl + C)? Или нужно будет сделать что-то вроде этого:

#include <signal.h>
#include <stdlib.h>

void onInterrupt(int dummy) { exit(0); }

int main() {
   signal(SIGINT, onInterrupt);
   FILE *file = fopen("file", "a");
   for (;;) { fprintf(file, "bleh"); } }

чтобы file правильно закрылся? Или можно безопасно пропустить строки signal(SIG... и void onInterrupt(...?

Пожалуйста, ограничьте любые ответы C, C99 и POSIX, так как я не использую GNU libc. Спасибо.

Ответы [ 2 ]

7 голосов
/ 11 января 2010

C99 spec 7.19.3 имеет более слабую гарантию:

5 Если основной функция возвращается к исходному вызывающему, или, если вызывается функция выхода, все открытые файлы закрываются (следовательно, все выходные потоки сбрасываются) до завершения программы. Другие пути к завершение программы, например, вызов функции прерывания, не обязательно закрывать все файлы должным образом.

4 Файл может быть отсоединен от управляющего потока путем закрытия файла. Выходные потоки сбрасываются (любое неписанное содержимое буфера передается в среду хоста) перед поток отсоединяется от файла.

Так что в C99, если он закрыт, он сбрасывается.

Функция выхода POSIX содержит больше подробностей, в частности то, что _exit закрывает потоки, определяется реализацией.

6 голосов
/ 11 января 2010

Вам придется обрабатывать сигнал, если вы хотите, чтобы ваши буферы были очищены. В противном случае процесс будет прерван, а файловые дескрипторы закрыты без очистки буферов stdio.

...