1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 
6 
7 static char fname[] = "/tmp/rndseek.XXXXXX";
8 static char tempdata[65 * 1024];
9 
10 
11 static int do_test (void);
12 #define TEST_FUNCTION do_test ()
13 
14 #include "../test-skeleton.c"
15 
16 
17 static int
fp_test(const char * name,FILE * fp)18 fp_test (const char *name, FILE *fp)
19 {
20   int result = 0;
21   int rounds = 10000;
22 
23   do
24     {
25       int idx = random () % (sizeof (tempdata) - 2);
26       char ch1;
27       char ch2;
28 
29       if (fseek (fp, idx, SEEK_SET) != 0)
30 	{
31 	  printf ("%s: %d: fseek failed: %m\n", name, rounds);
32 	  result = 1;
33 	  break;
34 	}
35 
36       ch1 = fgetc_unlocked (fp);
37       ch2 = tempdata[idx];
38       if (ch1 != ch2)
39 	{
40 	  printf ("%s: %d: character at index %d not what is expected ('%c' vs '%c')\n",
41 		  name, rounds, idx, ch1, ch2);
42 	  result = 1;
43 	  break;
44 	}
45 
46       ch1 = fgetc (fp);
47       ch2 = tempdata[idx + 1];
48       if (ch1 != ch2)
49 	{
50 	  printf ("%s: %d: character at index %d not what is expected ('%c' vs '%c')\n",
51 		  name, rounds, idx + 1, ch1, ch2);
52 	  result = 1;
53 	  break;
54 	}
55     }
56   while (--rounds > 0);
57 
58   fclose (fp);
59 
60   return result;
61 }
62 
63 
64 static int
do_test(void)65 do_test (void)
66 {
67   int fd;
68   FILE *fp;
69   size_t i;
70   int result;
71 
72   fd = mkstemp (fname);
73   if (fd == -1)
74     {
75       printf ("cannot open temporary file: %m\n");
76       return 1;
77     }
78   /* Make sure the file gets removed.  */
79   add_temp_file (fname);
80 
81   /* Repeatability demands this.  */
82   srandom (42);
83 
84   /* First create some temporary data.  */
85   for (i = 0; i < sizeof (tempdata); ++i)
86     tempdata[i] = 'a' + random () % 26;
87 
88   /* Write this data to a file.  */
89   if (TEMP_FAILURE_RETRY (write (fd, tempdata, sizeof (tempdata)))
90       != sizeof (tempdata))
91     {
92       printf ("cannot wrote data to temporary file: %m\n");
93       return 1;
94     }
95 
96   /* Now try reading the data.  */
97   fp = fdopen (dup (fd), "r");
98   if (fp == NULL)
99     {
100       printf ("cannot duplicate temporary file descriptor: %m\n");
101       return 1;
102     }
103 
104   rewind (fp);
105   for (i = 0; i < sizeof (tempdata); ++i)
106     {
107       int ch0 = fgetc (fp);
108       char ch1 = ch0;
109       char ch2 = tempdata[i];
110 
111       if (ch0 == EOF)
112 	{
113 	  puts ("premature end of file while reading data");
114 	  return 1;
115 	}
116 
117       if (ch1 != ch2)
118 	{
119 	  printf ("%zd: '%c' vs '%c'\n", i, ch1, ch2);
120 	  return 1;
121 	}
122     }
123 
124   result = fp_test ("fdopen(\"r\")", fp);
125 
126   fp = fopen (fname, "r");
127   result |= fp_test ("fopen(\"r\")", fp);
128 
129   fp = fopen64 (fname, "r");
130   result |= fp_test ("fopen64(\"r\")", fp);
131 
132   /* The "rw" mode will prevent the mmap-using code from being used.  */
133   fp = fdopen (fd, "rw");
134   result = fp_test ("fdopen(\"rw\")", fp);
135 
136   fp = fopen (fname, "rw");
137   result |= fp_test ("fopen(\"rw\")", fp);
138 
139   fp = fopen64 (fname, "rw");
140   result |= fp_test ("fopen64(\"rw\")", fp);
141 
142   return result;
143 }
144