diff --git a/libio/bug-fseek.c b/libio/bug-fseek.c index 1b60580b53..19d5e2429e 100644 --- a/libio/bug-fseek.c +++ b/libio/bug-fseek.c @@ -3,6 +3,7 @@ #include #include +#include static char *fname; @@ -48,7 +49,7 @@ do_test (void) perror ("fopen(\"r\")"); } - fread (buf, 3, 1, f); + xfread (buf, 3, 1, f); errno = 0; if (fseek (f, -10, SEEK_CUR) == 0) { @@ -72,7 +73,7 @@ Got %d instead\n", perror ("fopen(\"r+\")"); } - fread (buf, 3, 1, f); + xfread (buf, 3, 1, f); errno = 0; if (fseek (f, -10, SEEK_CUR) == 0) { @@ -96,7 +97,7 @@ Got %d instead\n", perror ("fopen(\"r+\")"); } - fread (buf, 3, 1, f); + xfread (buf, 3, 1, f); if (ftell (f) != 3) { puts ("ftell failed"); diff --git a/stdio-common/bug12.c b/stdio-common/bug12.c index 48610c0e78..1ba296deb4 100644 --- a/stdio-common/bug12.c +++ b/stdio-common/bug12.c @@ -1,6 +1,8 @@ #include #include +#include + char x[4096], z[4096], b[21], m[4096 * 4]; int @@ -20,24 +22,24 @@ main (void) } rewind (f); - fread (m, 4096 * 4 - 10, 1, f); - fread (b, 20, 1, f); + xfread (m, 4096 * 4 - 10, 1, f); + xfread (b, 20, 1, f); printf ("got %s (should be %s)\n", b, "zzzzzzzzzzxxxxxxxxxx"); if (strcmp (b, "zzzzzzzzzzxxxxxxxxxx")) failed = 1; fseek (f, -40, SEEK_CUR); - fread (b, 20, 1, f); + xfread (b, 20, 1, f); printf ("got %s (should be %s)\n", b, "zzzzzzzzzzzzzzzzzzzz"); if (strcmp (b, "zzzzzzzzzzzzzzzzzzzz")) failed = 1; - fread (b, 20, 1, f); + xfread (b, 20, 1, f); printf ("got %s (should be %s)\n", b, "zzzzzzzzzzxxxxxxxxxx"); if (strcmp (b, "zzzzzzzzzzxxxxxxxxxx")) failed = 1; - fread (b, 20, 1, f); + xfread (b, 20, 1, f); printf ("got %s (should be %s)\n", b, "xxxxxxxxxxxxxxxxxxxx"); if (strcmp (b, "xxxxxxxxxxxxxxxxxxxx")) failed = 1; diff --git a/stdio-common/bug3.c b/stdio-common/bug3.c index 62a6cab330..deabd00572 100644 --- a/stdio-common/bug3.c +++ b/stdio-common/bug3.c @@ -1,6 +1,8 @@ #include #include +#include + int main (void) { @@ -32,7 +34,7 @@ main (void) char buf[25]; buf[0] = j; - fread (buf + 1, 1, 23, f); + xfread (buf + 1, 1, 23, f); buf[24] = '\0'; if (strcmp (buf, "Where does this text go?") != 0) { diff --git a/stdio-common/bug4.c b/stdio-common/bug4.c index cf7fe116eb..4059ff75b3 100644 --- a/stdio-common/bug4.c +++ b/stdio-common/bug4.c @@ -2,6 +2,8 @@ #include #include +#include + int stdio_block_read = 1, stdio_block_write = 1; int @@ -30,7 +32,7 @@ main (int argc, char *argv[]) fseek (f, 8180L, 0); fwrite ("Where does this text come from?", 1, 31, f); fseek (f, 8180L, 0); - fread (buffer, 1, 31, f); + xfread (buffer, 1, 31, f); fwrite (buffer, 1, 31, stdout); fclose (f); remove (filename); diff --git a/stdio-common/tst-cookie.c b/stdio-common/tst-cookie.c index 030e684562..90ebc8e58c 100644 --- a/stdio-common/tst-cookie.c +++ b/stdio-common/tst-cookie.c @@ -5,6 +5,8 @@ #include +#include + #define THE_COOKIE ((void *) 0xdeadbeeful) @@ -77,7 +79,8 @@ do_test (void) f = fopencookie (THE_COOKIE, "r+", fcts); - fread (buf, 1, 1, f); + xfread (buf, 1, 1, f); + fwrite (buf, 1, 1, f); fseek (f, 0, SEEK_CUR); fclose (f); diff --git a/stdio-common/tst-fmemopen3.c b/stdio-common/tst-fmemopen3.c index bef87b712a..1627f17f59 100644 --- a/stdio-common/tst-fmemopen3.c +++ b/stdio-common/tst-fmemopen3.c @@ -21,6 +21,8 @@ #include #include +#include + static void print_buffer (const char *s, size_t n) { @@ -153,7 +155,7 @@ do_test_read_seek_neg (const char *mode, const char *expected) FILE *fp = fmemopen (buf, sizeof (buf), mode); fseek (fp, offset, SEEK_END); - fread (tmp, tmps, 1, fp); + xfread (tmp, tmps, 1, fp); if (memcmp (tmp, expected, tmps) != 0) { diff --git a/support/Makefile b/support/Makefile index 130de4a985..1f0f526e06 100644 --- a/support/Makefile +++ b/support/Makefile @@ -125,6 +125,7 @@ libsupport-routines = \ xfclose \ xfopen \ xfork \ + xfread \ xfreopen \ xftruncate \ xgetline \ diff --git a/support/xfread.c b/support/xfread.c new file mode 100644 index 0000000000..948f0c8111 --- /dev/null +++ b/support/xfread.c @@ -0,0 +1,39 @@ +/* fread with error checking. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include +#include + +void +xfread (void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t count = 0; + char *p = ptr; + + while (count < nmemb) + { + size_t ret = fread (p, size, nmemb - count, stream); + if (ret <= 0 && ferror(stream)) + FAIL_EXIT1 ("read of %zu bytes failed after %td: %m", + size * nmemb, p - (char *) ptr); + count += ret; + p += size * ret; + } +} diff --git a/support/xstdio.h b/support/xstdio.h index 5410d42579..633c342c82 100644 --- a/support/xstdio.h +++ b/support/xstdio.h @@ -27,6 +27,7 @@ __BEGIN_DECLS FILE *xfopen (const char *path, const char *mode); void xfclose (FILE *); FILE *xfreopen (const char *path, const char *mode, FILE *stream); +void xfread (void *ptr, size_t size, size_t nmemb, FILE *stream); /* Read a line from FP, using getline. *BUFFER must be NULL, or a heap-allocated pointer of *LENGTH bytes. Return the number of