Como fechar um arquivo?
Eu me senti em paz com a Posix depois de muitos anos de experiência.
Então eu liesta mensagem de Linus Torvalds, por volta de 2002:
int ret;
do {
ret = close(fd);
} while(ret == -1 && errno != EBADF);
NÃO.
O acima é
a) não é portátil
(b) prática não atual
A parte "não portátil" vem do fato de que (como alguém apontou), um ambiente encadeado no qual o kernelfaz fechar o FD em caso de erros, o FD pode ter sido reutilizado validamente (pelo kernel) para algum outro encadeamento, e fechar o FD pela segunda vez é um BUG.
Não é apenas loop atéEBADF
não é portável, mas qualquer loop é devido a uma condição de corrida que eu provavelmente teria notado se não tivesse "feito as pazes" tomando essas coisas como garantidas.
No entanto, na implementação da biblioteca padrão do GCC C ++,basic_file_stdio.cc
, temos
do
__err = fclose(_M_cfile);
while (__err && errno == EINTR);
O alvo principal desta biblioteca é o Linux, mas parece não estar atendendo a Linus.
Até onde eu entendi,EINTR
acontece somente após uma chamada do sistemablocos, o que implica que o kernel recebeu a solicitação para liberar o descritor antes de iniciar qualquer trabalho interrompido. Portanto, não há necessidade de loop. De fato, oSA_RESTART
o comportamento do sinal não se aplica aclose
e gere esse loop por padrão, precisamente porque é inseguro.
Este é um bug padrão da biblioteca, certo? Em todos os arquivos já fechados por um aplicativo C ++.
EDITAR: Para evitar causar muito alarme antes que algum guru venha com uma resposta, devo observar queclose
apenas parece ser permitido bloquear em circunstâncias específicas, talvez nenhuma delas se aplique a arquivos regulares. Não tenho certeza de todos os detalhes, mas você não deve verEINTR
declose
sem optar por algo porfcntl
ousetsockopt
. No entanto, a possibilidade torna o código genérico da biblioteca mais perigoso.