1/* Test case for bug with mmap stdio read past end of file. */
2
3#include <stdio.h>
4#include <error.h>
5#include <errno.h>
6
7static void do_prepare (void);
8#define PREPARE(argc, argv) do_prepare ()
9static int do_test (void);
10#define TEST_FUNCTION do_test ()
11#include <test-skeleton.c>
12
13static char *temp_file;
14
15static const char text1[] = "hello\n";
16
17static void
18do_prepare (void)
19{
20 int temp_fd = create_temp_file (base: "tst-mmap-offend.", filename: &temp_file);
21 if (temp_fd == -1)
22 error (status: 1, errno, format: "cannot create temporary file");
23 else
24 {
25 ssize_t cc = write (temp_fd, text1, sizeof text1 - 1);
26 if (cc != sizeof text1 - 1)
27 error (status: 1, errno, format: "cannot write to temporary file");
28 }
29 close (fd: temp_fd);
30}
31
32static int
33do_test (void)
34{
35 unsigned char buffer[8192];
36 int result = 0;
37 FILE *f = fopen (temp_file, "rm");
38 size_t cc;
39
40 if (f == NULL)
41 {
42 perror (temp_file);
43 return 1;
44 }
45
46 cc = fread (ptr: buffer, size: 1, n: sizeof (buffer), stream: f);
47 printf (format: "fread %zu: \"%.*s\"\n", cc, (int) cc, buffer);
48 if (cc != sizeof text1 - 1)
49 {
50 perror ("fread");
51 result = 1;
52 }
53
54 if (fseek (f, 2048, SEEK_SET) != 0)
55 {
56 perror ("fseek off end");
57 result = 1;
58 }
59
60 if (fread (ptr: buffer, size: 1, n: sizeof (buffer), stream: f) != 0
61 || ferror (stream: f) || !feof (stream: f))
62 {
63 printf (format: "after fread error %d eof %d\n",
64 ferror (stream: f), feof (stream: f));
65 result = 1;
66 }
67
68 printf (format: "ftell %ld\n", ftell (stream: f));
69
70 if (fseek (f, 0, SEEK_SET) != 0)
71 {
72 perror ("fseek rewind");
73 result = 1;
74 }
75
76 cc = fread (ptr: buffer, size: 1, n: sizeof (buffer), stream: f);
77 printf (format: "fread after rewind %zu: \"%.*s\"\n", cc, (int) cc, buffer);
78 if (cc != sizeof text1 - 1)
79 {
80 perror ("fread after rewind");
81 result = 1;
82 }
83
84 fclose (f);
85 return result;
86}
87

source code of glibc/libio/tst-mmap-offend.c