Windows fopen и флаг N

Я читаю код, который использует fopen для открытия файлов для записи. Код должен иметь возможность время от времени закрывать и переименовывать эти файлы (это регистратор вращающихся файлов). Автор говорит, что для этого дочерние процессы не должны наследовать эти FILE дескрипторы. (То есть в Windows; в Unix это нормально.) Поэтому автор пишет специальную подпрограмму, которая дублирует дескриптор как ненаследуемый и закрывает исходный дескриптор:

if (!(log->file = fopen(log->path, mode)))
    return ERROR;
#ifdef _WIN32
sf = _fileno(log->file);
sh = (HANDLE)_get_osfhandle(sf);
if (!DuplicateHandle(GetCurrentProcess(), sh, GetCurrentProcess(),
        &th, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
    fclose(log->file);
    return ERROR;
}
fclose(log->file);
flags = (*mode == 'a') ? _O_APPEND : 0;
tf = _open_osfhandle((intptr_t)th, _O_TEXT | flags);
if (!(log->file = _fdopen(tf, "at"))) {
    _close(tf);
    return ERROR;
}
#endif

Теперь я также читаю MSDN docs на fopen и видите, что их версия fopen имеет специальный флаг Microsoft, который, кажется, делает то же самое: флаг N:

N: указывает, что файл не наследуется дочерними процессами.

Вопрос: правильно ли я понимаю, что могу избавиться от того куска выше и заменить его (на винде) дополнительным N в параметре mode?


person Mikhail Edoshin    schedule 11.09.2012    source источник


Ответы (1)


Да, ты можешь.

fopen("myfile", "rbN") создает ненаследуемый дескриптор файла.

Флаг N нигде не упоминается в документации Linux для fopen, поэтому решение, скорее всего, будет не переносимым, но для MS VC оно работает нормально.

person nullptr    schedule 23.04.2013
comment
Спасибо за подтверждение; да, я использовал этот дополнительный флаг только в Windows. - person Mikhail Edoshin; 24.04.2013
comment
Может ли кто-нибудь прокомментировать, является ли Windows N примерно эквивалентной e glibc (что соответствует POSIX O_CLOEXEC)? Решают ли они в основном одну и ту же проблему? - person Quuxplusone; 10.08.2017