tests: fix warn unused result on asprintf calls
[platform/upstream/glibc.git] / stdio-common / tst-fseek.c
1 /* Tests of fseek and fseeko.
2    Copyright (C) 2000-2023 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18
19 #include <error.h>
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include <sys/stat.h>
27
28 #include <support/support.h>
29
30 static int
31 do_test (void)
32 {
33   const char *tmpdir;
34   char *fname;
35   int fd;
36   FILE *fp;
37   const char outstr[] = "hello world!\n";
38   char strbuf[sizeof outstr];
39   char buf[200];
40   struct stat64 st1;
41   struct stat64 st2;
42   int result = 0;
43
44   tmpdir = getenv ("TMPDIR");
45   if (tmpdir == NULL || tmpdir[0] == '\0')
46     tmpdir = "/tmp";
47
48   fname = xasprintf ("%s/tst-fseek.XXXXXX", tmpdir);
49
50   /* Create a temporary file.   */
51   fd = mkstemp (fname);
52   if (fd == -1)
53     error (EXIT_FAILURE, errno, "cannot open temporary file");
54
55   fp = fdopen (fd, "w+");
56   if (fp == NULL)
57     error (EXIT_FAILURE, errno, "cannot get FILE for temporary file");
58
59   setbuffer (fp, strbuf, sizeof (outstr) -1);
60
61   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
62     {
63       printf ("%d: write error\n", __LINE__);
64       result = 1;
65       goto out;
66     }
67
68   /* The EOF flag must be reset.  */
69   if (fgetc (fp) != EOF)
70     {
71       printf ("%d: managed to read at end of file\n", __LINE__);
72       result = 1;
73     }
74   else if (! feof (fp))
75     {
76       printf ("%d: EOF flag not set\n", __LINE__);
77       result = 1;
78     }
79   if (fseek (fp, 0, SEEK_CUR) != 0)
80     {
81       printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
82       result = 1;
83     }
84   else if (feof (fp))
85     {
86       printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
87       result = 1;
88     }
89
90   /* Do the same for fseeko().  */
91     if (fgetc (fp) != EOF)
92     {
93       printf ("%d: managed to read at end of file\n", __LINE__);
94       result = 1;
95     }
96   else if (! feof (fp))
97     {
98       printf ("%d: EOF flag not set\n", __LINE__);
99       result = 1;
100     }
101   if (fseeko (fp, 0, SEEK_CUR) != 0)
102     {
103       printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
104       result = 1;
105     }
106   else if (feof (fp))
107     {
108       printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
109       result = 1;
110     }
111
112   /* Go back to the beginning of the file: absolute.  */
113   if (fseek (fp, 0, SEEK_SET) != 0)
114     {
115       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
116       result = 1;
117     }
118   else if (fflush (fp) != 0)
119     {
120       printf ("%d: fflush() failed\n", __LINE__);
121       result = 1;
122     }
123   else if (lseek (fd, 0, SEEK_CUR) != 0)
124     {
125       printf ("%d: lseek() returned different position\n", __LINE__);
126       result = 1;
127     }
128   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
129     {
130       printf ("%d: fread() failed\n", __LINE__);
131       result = 1;
132     }
133   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
134     {
135       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
136       result = 1;
137     }
138
139   /* Now with fseeko.  */
140   if (fseeko (fp, 0, SEEK_SET) != 0)
141     {
142       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
143       result = 1;
144     }
145   else if (fflush (fp) != 0)
146     {
147       printf ("%d: fflush() failed\n", __LINE__);
148       result = 1;
149     }
150   else if (lseek (fd, 0, SEEK_CUR) != 0)
151     {
152       printf ("%d: lseek() returned different position\n", __LINE__);
153       result = 1;
154     }
155   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
156     {
157       printf ("%d: fread() failed\n", __LINE__);
158       result = 1;
159     }
160   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
161     {
162       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
163       result = 1;
164     }
165
166   /* Go back to the beginning of the file: relative.  */
167   if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
168     {
169       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
170       result = 1;
171     }
172   else if (fflush (fp) != 0)
173     {
174       printf ("%d: fflush() failed\n", __LINE__);
175       result = 1;
176     }
177   else if (lseek (fd, 0, SEEK_CUR) != 0)
178     {
179       printf ("%d: lseek() returned different position\n", __LINE__);
180       result = 1;
181     }
182   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
183     {
184       printf ("%d: fread() failed\n", __LINE__);
185       result = 1;
186     }
187   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
188     {
189       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
190       result = 1;
191     }
192
193   /* Now with fseeko.  */
194   if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
195     {
196       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
197       result = 1;
198     }
199   else if (fflush (fp) != 0)
200     {
201       printf ("%d: fflush() failed\n", __LINE__);
202       result = 1;
203     }
204   else if (lseek (fd, 0, SEEK_CUR) != 0)
205     {
206       printf ("%d: lseek() returned different position\n", __LINE__);
207       result = 1;
208     }
209   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
210     {
211       printf ("%d: fread() failed\n", __LINE__);
212       result = 1;
213     }
214   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
215     {
216       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
217       result = 1;
218     }
219
220   /* Go back to the beginning of the file: from the end.  */
221   if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
222     {
223       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
224       result = 1;
225     }
226   else if (fflush (fp) != 0)
227     {
228       printf ("%d: fflush() failed\n", __LINE__);
229       result = 1;
230     }
231   else if (lseek (fd, 0, SEEK_CUR) != 0)
232     {
233       printf ("%d: lseek() returned different position\n", __LINE__);
234       result = 1;
235     }
236   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
237     {
238       printf ("%d: fread() failed\n", __LINE__);
239       result = 1;
240     }
241   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
242     {
243       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
244       result = 1;
245     }
246
247   /* Now with fseeko.  */
248   if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
249     {
250       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
251       result = 1;
252     }
253   else if (fflush (fp) != 0)
254     {
255       printf ("%d: fflush() failed\n", __LINE__);
256       result = 1;
257     }
258   else if (lseek (fd, 0, SEEK_CUR) != 0)
259     {
260       printf ("%d: lseek() returned different position\n", __LINE__);
261       result = 1;
262     }
263   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
264     {
265       printf ("%d: fread() failed\n", __LINE__);
266       result = 1;
267     }
268   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
269     {
270       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
271       result = 1;
272     }
273
274   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
275     {
276       printf ("%d: write error 2\n", __LINE__);
277       result = 1;
278       goto out;
279     }
280
281   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
282     {
283       printf ("%d: write error 3\n", __LINE__);
284       result = 1;
285       goto out;
286     }
287
288   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
289     {
290       printf ("%d: write error 4\n", __LINE__);
291       result = 1;
292       goto out;
293     }
294
295   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
296     {
297       printf ("%d: write error 5\n", __LINE__);
298       result = 1;
299       goto out;
300     }
301
302   if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF)
303     {
304       printf ("%d: cannot add characters at the end\n", __LINE__);
305       result = 1;
306       goto out;
307     }
308
309   /* Check the access time.  */
310   if (fstat64 (fd, &st1) < 0)
311     {
312       printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
313       result = 1;
314     }
315   else
316     {
317       sleep (1);
318
319       if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0)
320         {
321           printf ("%d: fseek() after write characters failed\n", __LINE__);
322           result = 1;
323           goto out;
324         }
325       else
326         {
327
328           time_t t;
329           /* Make sure the timestamp actually can be different.  */
330           sleep (1);
331           t = time (NULL);
332
333           if (fstat64 (fd, &st2) < 0)
334             {
335               printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__);
336               result = 1;
337             }
338           if (st1.st_ctime >= t)
339             {
340               printf ("%d: st_ctime not updated\n", __LINE__);
341               result = 1;
342             }
343           if (st1.st_mtime >= t)
344             {
345               printf ("%d: st_mtime not updated\n", __LINE__);
346               result = 1;
347             }
348           if (st1.st_ctime >= st2.st_ctime)
349             {
350               printf ("%d: st_ctime not changed\n", __LINE__);
351               result = 1;
352             }
353           if (st1.st_mtime >= st2.st_mtime)
354             {
355               printf ("%d: st_mtime not changed\n", __LINE__);
356               result = 1;
357             }
358         }
359     }
360
361   if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
362       != 2 + 2 * (sizeof (outstr) - 1))
363     {
364       printf ("%d: reading 2 records plus bits failed\n", __LINE__);
365       result = 1;
366     }
367   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
368            || memcmp (&buf[sizeof (outstr) - 1], outstr,
369                       sizeof (outstr) - 1) != 0
370            || buf[2 * (sizeof (outstr) - 1)] != '1'
371            || buf[2 * (sizeof (outstr) - 1) + 1] != '2')
372     {
373       printf ("%d: reading records failed\n", __LINE__);
374       result = 1;
375     }
376   else if (ungetc ('9', fp) == EOF)
377     {
378       printf ("%d: ungetc() failed\n", __LINE__);
379       result = 1;
380     }
381   else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0)
382     {
383       printf ("%d: fseek after ungetc failed\n", __LINE__);
384       result = 1;
385     }
386   else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
387       != 2 + 2 * (sizeof (outstr) - 1))
388     {
389       printf ("%d: reading 2 records plus bits failed\n", __LINE__);
390       result = 1;
391     }
392   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
393            || memcmp (&buf[sizeof (outstr) - 1], outstr,
394                       sizeof (outstr) - 1) != 0
395            || buf[2 * (sizeof (outstr) - 1)] != '1')
396     {
397       printf ("%d: reading records for the second time failed\n", __LINE__);
398       result = 1;
399     }
400   else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9')
401     {
402       printf ("%d: unget character not ignored\n", __LINE__);
403       result = 1;
404     }
405   else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2')
406     {
407       printf ("%d: unget somehow changed character\n", __LINE__);
408       result = 1;
409     }
410
411   fclose (fp);
412
413   fp = fopen (fname, "r");
414   if (fp == NULL)
415     {
416       printf ("%d: fopen() failed\n\n", __LINE__);
417       result = 1;
418     }
419   else if (fstat64 (fileno (fp), &st1) < 0)
420     {
421       printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
422       result = 1;
423     }
424   else if (fseeko (fp, 0, SEEK_END) != 0)
425     {
426       printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
427       result = 1;
428     }
429   else if (ftello (fp) != st1.st_size)
430     {
431       printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
432               (size_t) st1.st_size, (size_t) ftello (fp));
433       result = 1;
434     }
435   else
436     printf ("%d: SEEK_END works\n", __LINE__);
437   if (fp != NULL)
438     fclose (fp);
439
440   fp = fopen (fname, "r");
441   if (fp == NULL)
442     {
443       printf ("%d: fopen() failed\n\n", __LINE__);
444       result = 1;
445     }
446   else if (fstat64 (fileno (fp), &st1) < 0)
447     {
448       printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__);
449       result = 1;
450     }
451   else if (fgetc (fp) == EOF)
452     {
453       printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__);
454       result = 1;
455     }
456   else if (fseeko (fp, 0, SEEK_END) != 0)
457     {
458       printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
459       result = 1;
460     }
461   else if (ftello (fp) != st1.st_size)
462     {
463       printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
464               (size_t) st1.st_size, (size_t) ftello (fp));
465       result = 1;
466     }
467   else
468     printf ("%d: SEEK_END works\n", __LINE__);
469   if (fp != NULL)
470     fclose (fp);
471
472  out:
473   unlink (fname);
474
475   return result;
476 }
477
478 #define TEST_FUNCTION do_test ()
479 #include "../test-skeleton.c"