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.

questionAnswers(1)

yourAnswerToTheQuestion