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