1#include <errno.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5
6#include <support/xstdio.h>
7
8static char *fname;
9
10
11static void do_prepare (void);
12#define PREPARE(argc, argv) do_prepare ()
13static int do_test (void);
14#define TEST_FUNCTION do_test ()
15#include <test-skeleton.c>
16
17
18static void
19do_prepare (void)
20{
21 static const char pattern[] = "12345678901234567890";
22 int fd = create_temp_file (base: "bug-fseek.", filename: &fname);
23 if (fd == -1)
24 {
25 printf (format: "cannot create temporary file: %m\n");
26 exit (1);
27 }
28
29 if (write (fd, pattern, sizeof (pattern)) != sizeof (pattern))
30 {
31 perror ("short write");
32 abort ();
33 }
34 close (fd: fd);
35}
36
37
38
39static int
40do_test (void)
41{
42 FILE *f;
43 int result = 0;
44 char buf[10];
45
46
47 if ((f = fopen (fname, "r")) == (FILE *) NULL)
48 {
49 perror ("fopen(\"r\")");
50 }
51
52 xfread (ptr: buf, size: 3, nmemb: 1, stream: f);
53 errno = 0;
54 if (fseek (f, -10, SEEK_CUR) == 0)
55 {
56 printf (format: "fseek() for r to before start of file worked!\n");
57 result = 1;
58 }
59 else if (errno != EINVAL)
60 {
61 printf (format: "\
62fseek() for r to before start of file did not set errno to EINVAL. \
63Got %d instead\n",
64 errno);
65 result = 1;
66 }
67
68 fclose (f);
69
70
71 if ((f = fopen (fname, "r+")) == (FILE *) NULL)
72 {
73 perror ("fopen(\"r+\")");
74 }
75
76 xfread (ptr: buf, size: 3, nmemb: 1, stream: f);
77 errno = 0;
78 if (fseek (f, -10, SEEK_CUR) == 0)
79 {
80 printf (format: "fseek() for r+ to before start of file worked!\n");
81 result = 1;
82 }
83 else if (errno != EINVAL)
84 {
85 printf (format: "\
86fseek() for r+ to before start of file did not set errno to EINVAL. \
87Got %d instead\n",
88 errno);
89 result = 1;
90 }
91
92 fclose (f);
93
94
95 if ((f = fopen (fname, "r+")) == (FILE *) NULL)
96 {
97 perror ("fopen(\"r+\")");
98 }
99
100 xfread (ptr: buf, size: 3, nmemb: 1, stream: f);
101 if (ftell (stream: f) != 3)
102 {
103 puts (s: "ftell failed");
104 return 1;
105 }
106 errno = 0;
107 if (fseek (f, -10, SEEK_CUR) == 0)
108 {
109 printf (format: "fseek() for r+ to before start of file worked!\n");
110 result = 1;
111 }
112 else if (errno != EINVAL)
113 {
114 printf (format: "\
115fseek() for r+ to before start of file did not set errno to EINVAL. \
116Got %d instead\n",
117 errno);
118 result = 1;
119 }
120
121 fclose (f);
122
123 return result;
124}
125

source code of glibc/libio/bug-fseek.c