2015-10-16 3 views
1

Является ли этот код безопасным для Linux в том смысле, что 1) он не может сбой и не может читать свободную() редакционную память, а 2) файл freopen() ed имеет тот же номер блокировки, что и файл fclose() ed?Безопасно ли flockfile() FILE *, который был закрыт() ed на linux?

Тема 1:

flockfile(file); 
freopen("name", a", file); 
funlockfile(file); 

Резьба2:

flockfile(file); 
fputs("stuff", file); 
funlockfile(file); 
+0

Я не могу поставить в ответ, но я бы вопрос в любом обзоре кода, который пришел мой путь. Если это безопасно, я бы хотел, чтобы комментарий там направлял меня к источнику, который говорит, что он безопасен. – John3136

+0

@ John3136 спасибо в любом случае –

+0

Зачем вам нужен звонок fclose? – Random832

ответ

6

Там нет безопасных операций на закрытой FILE*. От fclose(3):

... любой дальнейший доступ (включая другой вызов функции fclose()) к потоку приводит к неопределенному поведению.

Это потому, что fclose (может) освободить объект, на который указывает указатель на файл.

Тем не менее, это абсолютно безопасно для блокировки потока, в то время как freopen, поскольку блокировка привязана к потоку, а не к основному файлу. На самом деле, согласно flockfile(3):

Функции stdio являются потокобезопасными.

Дополнительно freopen также отмечен как «МТ-сейф» в freopen(3). Поэтому freopen должен запереть внутреннюю блокировку , чтобы избежать закрытия базового дескриптора файла, в то время как другой поток - это, например, freopen. Следовательно, он должен быть безопасным, чтобы принимать его извне (блокировка повторяется).

Наконец, вам действительно не нужны эти вызовы для flockfile, так как все файловые операции уже являются потокобезопасными.


Я проверял (прочитав источник), что и Glibc и Libc OpenBSD (также используется на андроид) заблокировать поток внутри, когда freopen называется.

Glibc freopen код начинается с:

FILE* 
freopen (filename, mode, fp) 
    const char* filename; 
    const char* mode; 
    FILE* fp; 
{ 
    FILE *result; 
    CHECK_FILE (fp, NULL); 
    if (!(fp->_flags & _IO_IS_FILEBUF)) 
    return NULL; 
    _IO_acquire_lock (fp); // <-- This a macro that calls the private equivalent of flockfile and does some gcc cleanup magic. 

И закрывается:

_IO_release_lock (fp); 
    return result; 
} 
+0

Спасибо. Я обновил вопрос, чтобы уточнить его, удалив fclose() и просто оставив freopen(). Что вы думаете об этом случае. –

+0

Спасибо. У вас есть что-то, что вы можете ссылаться, чтобы поддержать безопасность этого? –

+0

@JohnCashew, к сожалению, я не могу найти никаких документов, явно заявляющих, что безопасно называть 'freopen', удерживая блокировку, но было бы невозможно безопасно реализовать' freopen' любым другим способом. – Steven