Li em Programação Avançada em Ambiente Unix isto:
O buffer de linha vem com duas ressalvas. Primeiro, o tamanho do buffer que a biblioteca de E/S padrão usa para coletar cada linha é fixo, então a E/S pode ocorrer se preenchermos esse buffer antes de escrever uma nova linha. Segundo, sempre que a entrada for solicitada por meio da biblioteca de E/S padrão de (a) um fluxo sem buffer ou (b) um fluxo com buffer de linha (que requer que os dados sejam solicitados do kernel), todos os fluxos de saída com buffer de linha são liberados. O motivo do qualificador em (b) é que os dados solicitados podem já estar no buffer, o que não requer que os dados sejam lidos do kernel. Obviamente, qualquer entrada de um fluxo sem buffer, item (a), requer que os dados sejam obtidos do kernel.
https://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html afirma:
Liberar a saída em um fluxo em buffer significa transmitir todos os caracteres acumulados para o arquivo. Há muitas circunstâncias em que a saída em buffer em um fluxo é liberada automaticamente:
Quando você tenta fazer uma saída e o buffer de saída está cheio.
Quando o fluxo é fechado. Veja Fechando Fluxos.
Quando o programa termina chamando exit. Veja Término Normal. Quando uma nova linha é escrita, se o fluxo for bufferizado por linha.
Sempre que uma operação de entrada em qualquer fluxo realmente lê dados de seu arquivo.
Então eu escrevi um programa para testar isso:
#include <stdio.h>
#include <unistd.h>
int
main()
{
printf("Hello");
FILE *fp = fopen("hugefile", "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file\n");
return -1;
}
setvbuf(fp, NULL, _IONBF, 0);
sleep(2);
char buf[10];
while (fread(buf, sizeof(char), 10, fp) == 10) {
}
if (ferror(fp)) {
fprintf(stderr, "Read error\n");
return -1;
}; // I expect "Hello" to appear on a screen but it doesn't
fclose(fp);
sleep(50);
}
Mas fread() não dispara o flashing da saída. Estou esquecendo de algo?
Não sei o que pode ser relevante aqui, mas eu uso:
gcc versão 14.2.1 20240910
glibc 2.40+r16+gaa533d58ff-2