Dank @JdeBP für den Hinweis konnte ich einen kleinen Testfall erstellen, der dasselbe tut wie hexdump
:
#include <stdio.h>
int main(void){
char buf[64]; size_t r;
for(;;){
printf("eof=%d, error=%d\n", feof(stdin), ferror(stdin));
r = fread(buf, 1, sizeof buf, stdin);
printf("read %zd bytes, eof=%d, error=%d\n",
r, feof(stdin), ferror(stdin));
if(!r) return 0;
}
}
Bei Ausführung auf einem glibc-basierten System (typischer Linux-Desktop).
prompt$ ./fread-test
eof=0, error=0
<control-D>
read 0 bytes, eof=1, error=0
prompt$ ./fread-test
eof=0, error=0
hello
<control-D>
read 6 bytes, eof=1, error=0
eof=1, error=0
<control-D>
read 0 bytes, eof=1, error=0
Bei Ausführung auf BSD, Solaris, Busybox (uclibc), Android usw.:
prompt$ ./fread-test
eof=0, error=0
hello
<control-D>
read 6 bytes, eof=1, error=0
eof=1, error=0
read 0 bytes, eof=1, error=0
Basierend auf meiner unfachmännischen Interpretation des Standards sieht dies wie ein Fehler aus in glibc (der GNU-C-Bibliothek).
Über fread
:
Für jedes Objekt sollen Größenaufrufe an die Funktion fgetc() erfolgen und die Ergebnisse in der gelesenen Reihenfolge in einem Array aus unsigned char gespeichert werden, das genau das Objekt überlagert.
Über fgetc
:
Wenn der Dateiende-Indikator für den auf bystream zeigenden Eingabestream nicht gesetzt ist und ein nächstes Byte vorhanden ist, erhalten die fgetc()-Funktionen das nächste Byte
Es scheint, dass glibc versucht, "das nächste Byte zu erhalten", selbst wenn der eof-Indikator gesetzt ist.
Tatsächlich ist es tatsächlich ein Fehler in der GNU-C-Bibliothek, der in den BSD- oder Musl-C-Bibliotheken nicht vorhanden ist. Es war 2005 bekannt. Ulrich Drepper schloss den Fehlerbericht, ohne den Fehler 2007 zu beheben. Es wurde 2012 diskutiert, wo festgestellt wurde, dass andere C-Bibliotheken dieses Verhalten nicht hatten und haben, dass der 1999er C-Standard ziemlich ist spezifisch darüber, und dass Solaris sogar einen speziellen Mechanismus dafür hat, der aufgerufen wird, wenn c99
wird anstelle von cc
als Compiler verwendet .
Es wurde schließlich 2018 behoben. Das Update befindet sich in Version 2.28 der GNU C-Bibliothek. Die aktuelle „stabile“ Version von Debian, Version 9, ist Version 2.24 der GNU C-Bibliothek, und dieser Fehler manifestiert sich daher weiterhin, 14 Jahre nachdem er gemeldet wurde.
Wie in den Diskussionen zur GNU-C-Bibliothek erwähnt, gibt es die Möglichkeit von Software, die geschrieben wurde, um die Macken der GNU C-Bibliothek zu benötigen, ohne Rücksicht auf andere C-Bibliotheken wie Musl oder das Verhalten auf anderen Plattformen. In den vorgenannten Diskussionen über die Jahre wurde jedoch kein solches Programm identifiziert. Während mehrere Programme, die von der alten GNU-C-Bibliothek beschädigt wurden, Benutzer dazu auffordern, EOF zweimal hintereinander zu signalisieren, haben identifiziert worden; einschließlich unter anderem hexdump
hier und patch
auf StackOverflow im Jahr 2018.