Back to index

glibc  2.9
tst-fseek.c
Go to the documentation of this file.
00001 /* Tests of fseek and fseeko.
00002    Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <error.h>
00022 #include <errno.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <unistd.h>
00027 #include <time.h>
00028 #include <sys/stat.h>
00029 
00030 
00031 int
00032 main (void)
00033 {
00034   const char *tmpdir;
00035   char *fname;
00036   int fd;
00037   FILE *fp;
00038   const char outstr[] = "hello world!\n";
00039   char strbuf[sizeof outstr];
00040   char buf[200];
00041   struct stat64 st1;
00042   struct stat64 st2;
00043   int result = 0;
00044 
00045   tmpdir = getenv ("TMPDIR");
00046   if (tmpdir == NULL || tmpdir[0] == '\0')
00047     tmpdir = "/tmp";
00048 
00049   asprintf (&fname, "%s/tst-fseek.XXXXXX", tmpdir);
00050   if (fname == NULL)
00051     error (EXIT_FAILURE, errno, "cannot generate name for temporary file");
00052 
00053   /* Create a temporary file.   */
00054   fd = mkstemp (fname);
00055   if (fd == -1)
00056     error (EXIT_FAILURE, errno, "cannot open temporary file");
00057 
00058   fp = fdopen (fd, "w+");
00059   if (fp == NULL)
00060     error (EXIT_FAILURE, errno, "cannot get FILE for temporary file");
00061 
00062   setbuffer (fp, strbuf, sizeof (outstr) -1);
00063 
00064   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
00065     {
00066       printf ("%d: write error\n", __LINE__);
00067       result = 1;
00068       goto out;
00069     }
00070 
00071   /* The EOF flag must be reset.  */
00072   if (fgetc (fp) != EOF)
00073     {
00074       printf ("%d: managed to read at end of file\n", __LINE__);
00075       result = 1;
00076     }
00077   else if (! feof (fp))
00078     {
00079       printf ("%d: EOF flag not set\n", __LINE__);
00080       result = 1;
00081     }
00082   if (fseek (fp, 0, SEEK_CUR) != 0)
00083     {
00084       printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
00085       result = 1;
00086     }
00087   else if (feof (fp))
00088     {
00089       printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
00090       result = 1;
00091     }
00092 
00093   /* Do the same for fseeko().  */
00094     if (fgetc (fp) != EOF)
00095     {
00096       printf ("%d: managed to read at end of file\n", __LINE__);
00097       result = 1;
00098     }
00099   else if (! feof (fp))
00100     {
00101       printf ("%d: EOF flag not set\n", __LINE__);
00102       result = 1;
00103     }
00104   if (fseeko (fp, 0, SEEK_CUR) != 0)
00105     {
00106       printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
00107       result = 1;
00108     }
00109   else if (feof (fp))
00110     {
00111       printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
00112       result = 1;
00113     }
00114 
00115   /* Go back to the beginning of the file: absolute.  */
00116   if (fseek (fp, 0, SEEK_SET) != 0)
00117     {
00118       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
00119       result = 1;
00120     }
00121   else if (fflush (fp) != 0)
00122     {
00123       printf ("%d: fflush() failed\n", __LINE__);
00124       result = 1;
00125     }
00126   else if (lseek (fd, 0, SEEK_CUR) != 0)
00127     {
00128       printf ("%d: lseek() returned different position\n", __LINE__);
00129       result = 1;
00130     }
00131   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
00132     {
00133       printf ("%d: fread() failed\n", __LINE__);
00134       result = 1;
00135     }
00136   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
00137     {
00138       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
00139       result = 1;
00140     }
00141 
00142   /* Now with fseeko.  */
00143   if (fseeko (fp, 0, SEEK_SET) != 0)
00144     {
00145       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
00146       result = 1;
00147     }
00148   else if (fflush (fp) != 0)
00149     {
00150       printf ("%d: fflush() failed\n", __LINE__);
00151       result = 1;
00152     }
00153   else if (lseek (fd, 0, SEEK_CUR) != 0)
00154     {
00155       printf ("%d: lseek() returned different position\n", __LINE__);
00156       result = 1;
00157     }
00158   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
00159     {
00160       printf ("%d: fread() failed\n", __LINE__);
00161       result = 1;
00162     }
00163   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
00164     {
00165       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
00166       result = 1;
00167     }
00168 
00169   /* Go back to the beginning of the file: relative.  */
00170   if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
00171     {
00172       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
00173       result = 1;
00174     }
00175   else if (fflush (fp) != 0)
00176     {
00177       printf ("%d: fflush() failed\n", __LINE__);
00178       result = 1;
00179     }
00180   else if (lseek (fd, 0, SEEK_CUR) != 0)
00181     {
00182       printf ("%d: lseek() returned different position\n", __LINE__);
00183       result = 1;
00184     }
00185   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
00186     {
00187       printf ("%d: fread() failed\n", __LINE__);
00188       result = 1;
00189     }
00190   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
00191     {
00192       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
00193       result = 1;
00194     }
00195 
00196   /* Now with fseeko.  */
00197   if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
00198     {
00199       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
00200       result = 1;
00201     }
00202   else if (fflush (fp) != 0)
00203     {
00204       printf ("%d: fflush() failed\n", __LINE__);
00205       result = 1;
00206     }
00207   else if (lseek (fd, 0, SEEK_CUR) != 0)
00208     {
00209       printf ("%d: lseek() returned different position\n", __LINE__);
00210       result = 1;
00211     }
00212   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
00213     {
00214       printf ("%d: fread() failed\n", __LINE__);
00215       result = 1;
00216     }
00217   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
00218     {
00219       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
00220       result = 1;
00221     }
00222 
00223   /* Go back to the beginning of the file: from the end.  */
00224   if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
00225     {
00226       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
00227       result = 1;
00228     }
00229   else if (fflush (fp) != 0)
00230     {
00231       printf ("%d: fflush() failed\n", __LINE__);
00232       result = 1;
00233     }
00234   else if (lseek (fd, 0, SEEK_CUR) != 0)
00235     {
00236       printf ("%d: lseek() returned different position\n", __LINE__);
00237       result = 1;
00238     }
00239   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
00240     {
00241       printf ("%d: fread() failed\n", __LINE__);
00242       result = 1;
00243     }
00244   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
00245     {
00246       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
00247       result = 1;
00248     }
00249 
00250   /* Now with fseeko.  */
00251   if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
00252     {
00253       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
00254       result = 1;
00255     }
00256   else if (fflush (fp) != 0)
00257     {
00258       printf ("%d: fflush() failed\n", __LINE__);
00259       result = 1;
00260     }
00261   else if (lseek (fd, 0, SEEK_CUR) != 0)
00262     {
00263       printf ("%d: lseek() returned different position\n", __LINE__);
00264       result = 1;
00265     }
00266   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
00267     {
00268       printf ("%d: fread() failed\n", __LINE__);
00269       result = 1;
00270     }
00271   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
00272     {
00273       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
00274       result = 1;
00275     }
00276 
00277   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
00278     {
00279       printf ("%d: write error 2\n", __LINE__);
00280       result = 1;
00281       goto out;
00282     }
00283 
00284   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
00285     {
00286       printf ("%d: write error 3\n", __LINE__);
00287       result = 1;
00288       goto out;
00289     }
00290 
00291   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
00292     {
00293       printf ("%d: write error 4\n", __LINE__);
00294       result = 1;
00295       goto out;
00296     }
00297 
00298   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
00299     {
00300       printf ("%d: write error 5\n", __LINE__);
00301       result = 1;
00302       goto out;
00303     }
00304 
00305   if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF)
00306     {
00307       printf ("%d: cannot add characters at the end\n", __LINE__);
00308       result = 1;
00309       goto out;
00310     }
00311 
00312   /* Check the access time.  */
00313   if (fstat64 (fd, &st1) < 0)
00314     {
00315       printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
00316       result = 1;
00317     }
00318   else
00319     {
00320       sleep (1);
00321 
00322       if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0)
00323        {
00324          printf ("%d: fseek() after write characters failed\n", __LINE__);
00325          result = 1;
00326          goto out;
00327        }
00328       else
00329        {
00330 
00331          time_t t;
00332          /* Make sure the timestamp actually can be different.  */
00333          sleep (1);
00334          t = time (NULL);
00335 
00336          if (fstat64 (fd, &st2) < 0)
00337            {
00338              printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__);
00339              result = 1;
00340            }
00341          if (st1.st_ctime >= t)
00342            {
00343              printf ("%d: st_ctime not updated\n", __LINE__);
00344              result = 1;
00345            }
00346          if (st1.st_mtime >= t)
00347            {
00348              printf ("%d: st_mtime not updated\n", __LINE__);
00349              result = 1;
00350            }
00351          if (st1.st_ctime >= st2.st_ctime)
00352            {
00353              printf ("%d: st_ctime not changed\n", __LINE__);
00354              result = 1;
00355            }
00356          if (st1.st_mtime >= st2.st_mtime)
00357            {
00358              printf ("%d: st_mtime not changed\n", __LINE__);
00359              result = 1;
00360            }
00361        }
00362     }
00363 
00364   if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
00365       != 2 + 2 * (sizeof (outstr) - 1))
00366     {
00367       printf ("%d: reading 2 records plus bits failed\n", __LINE__);
00368       result = 1;
00369     }
00370   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
00371           || memcmp (&buf[sizeof (outstr) - 1], outstr,
00372                     sizeof (outstr) - 1) != 0
00373           || buf[2 * (sizeof (outstr) - 1)] != '1'
00374           || buf[2 * (sizeof (outstr) - 1) + 1] != '2')
00375     {
00376       printf ("%d: reading records failed\n", __LINE__);
00377       result = 1;
00378     }
00379   else if (ungetc ('9', fp) == EOF)
00380     {
00381       printf ("%d: ungetc() failed\n", __LINE__);
00382       result = 1;
00383     }
00384   else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0)
00385     {
00386       printf ("%d: fseek after ungetc failed\n", __LINE__);
00387       result = 1;
00388     }
00389   else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
00390       != 2 + 2 * (sizeof (outstr) - 1))
00391     {
00392       printf ("%d: reading 2 records plus bits failed\n", __LINE__);
00393       result = 1;
00394     }
00395   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
00396           || memcmp (&buf[sizeof (outstr) - 1], outstr,
00397                     sizeof (outstr) - 1) != 0
00398           || buf[2 * (sizeof (outstr) - 1)] != '1')
00399     {
00400       printf ("%d: reading records for the second time failed\n", __LINE__);
00401       result = 1;
00402     }
00403   else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9')
00404     {
00405       printf ("%d: unget character not ignored\n", __LINE__);
00406       result = 1;
00407     }
00408   else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2')
00409     {
00410       printf ("%d: unget somehow changed character\n", __LINE__);
00411       result = 1;
00412     }
00413 
00414   fclose (fp);
00415 
00416   fp = fopen (fname, "r");
00417   if (fp == NULL)
00418     {
00419       printf ("%d: fopen() failed\n\n", __LINE__);
00420       result = 1;
00421     }
00422   else if (fstat64 (fileno (fp), &st1) < 0)
00423     {
00424       printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
00425       result = 1;
00426     }
00427   else if (fseeko (fp, 0, SEEK_END) != 0)
00428     {
00429       printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
00430       result = 1;
00431     }
00432   else if (ftello (fp) != st1.st_size)
00433     {
00434       printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
00435              (size_t) st1.st_size, (size_t) ftello (fp));
00436       result = 1;
00437     }
00438   else
00439     printf ("%d: SEEK_END works\n", __LINE__);
00440   if (fp != NULL)
00441     fclose (fp);
00442 
00443   fp = fopen (fname, "r");
00444   if (fp == NULL)
00445     {
00446       printf ("%d: fopen() failed\n\n", __LINE__);
00447       result = 1;
00448     }
00449   else if (fstat64 (fileno (fp), &st1) < 0)
00450     {
00451       printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__);
00452       result = 1;
00453     }
00454   else if (fgetc (fp) == EOF)
00455     {
00456       printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__);
00457       result = 1;
00458     }
00459   else if (fseeko (fp, 0, SEEK_END) != 0)
00460     {
00461       printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
00462       result = 1;
00463     }
00464   else if (ftello (fp) != st1.st_size)
00465     {
00466       printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
00467              (size_t) st1.st_size, (size_t) ftello (fp));
00468       result = 1;
00469     }
00470   else
00471     printf ("%d: SEEK_END works\n", __LINE__);
00472   if (fp != NULL)
00473     fclose (fp);
00474 
00475  out:
00476   unlink (fname);
00477 
00478   return result;
00479 }