(root)/
glibc-2.38/
libio/
tst-mmap2-eofsync.c
       1  /* Test program for synchronization of stdio state with file after EOF.  */
       2  
       3  #include <stdio.h>
       4  #include <error.h>
       5  #include <errno.h>
       6  #include <string.h>
       7  #include <unistd.h>
       8  
       9  static void do_prepare (void);
      10  #define PREPARE(argc, argv) do_prepare ()
      11  static int do_test (void);
      12  #define TEST_FUNCTION do_test ()
      13  #include <test-skeleton.c>
      14  
      15  static char *temp_file;
      16  static int temp_fd;
      17  
      18  static char *pages;
      19  
      20  static void
      21  do_prepare (void)
      22  {
      23    pages = xmalloc (getpagesize () * 2);
      24    memset (pages, 'a', getpagesize ());
      25    memset (pages + getpagesize (), 'b', getpagesize ());
      26  
      27    temp_fd = create_temp_file ("tst-mmap2-eofsync.", &temp_file);
      28    if (temp_fd == -1)
      29      error (1, errno, "cannot create temporary file");
      30    else
      31      {
      32        ssize_t cc = write (temp_fd, pages, getpagesize ());
      33        if (cc != getpagesize ())
      34  	error (1, errno, "cannot write to temporary file");
      35      }
      36  }
      37  
      38  static int
      39  do_test (void)
      40  {
      41    const size_t pagesize = getpagesize ();
      42    FILE *f;
      43    char buf[pagesize];
      44    int result = 0;
      45    int c;
      46  
      47    f = fopen (temp_file, "rm");
      48    if (f == NULL)
      49      {
      50        perror (temp_file);
      51        return 1;
      52      }
      53  
      54    if (fread (buf, pagesize, 1, f) != 1)
      55      {
      56        perror ("fread");
      57        return 1;
      58      }
      59  
      60    if (memcmp (buf, pages, pagesize))
      61      {
      62        puts ("data mismatch in page 1");
      63        result = 1;
      64      }
      65  
      66    printf ("feof = %d, ferror = %d immediately after fread\n",
      67  	  feof (f), ferror (f));
      68  
      69    c = fgetc (f);
      70    if (c == EOF)
      71      printf ("fgetc -> EOF (feof = %d, ferror = %d)\n",
      72  	    feof (f), ferror (f));
      73    else
      74      {
      75        printf ("fgetc returned %o (feof = %d, ferror = %d)\n",
      76  	      c, feof (f), ferror (f));
      77        result = 1;
      78      }
      79  
      80    c = write (temp_fd, pages + pagesize, pagesize);
      81    if (c == (ssize_t) pagesize)
      82      printf ("wrote more to file\n");
      83    else
      84      {
      85        printf ("wrote %d != %zd (%m)\n", c, pagesize);
      86        result = 1;
      87      }
      88  
      89    if (fread (buf, pagesize, 1, f) != 1)
      90      {
      91        printf ("second fread fails: feof = %d, ferror = %d (%m)\n",
      92  	      feof (f), ferror (f));
      93        clearerr (f);
      94        if (fread (buf, pagesize, 1, f) != 1)
      95  	{
      96  	  printf ("retry fread fails: feof = %d, ferror = %d (%m)\n",
      97  		  feof (f), ferror (f));
      98  	  result = 1;
      99  	}
     100      }
     101    if (result == 0 && memcmp (buf, pages + pagesize, pagesize))
     102      {
     103        puts ("data mismatch in page 2");
     104        result = 1;
     105      }
     106  
     107    fseek (f, pagesize - 1, SEEK_SET);
     108    c = fgetc (f);
     109    if (c != 'a')
     110      {
     111        printf ("fgetc at end of page 1 read '%c' (%m)\n", c);
     112        result = 1;
     113      }
     114  
     115    if (ftruncate (temp_fd, pagesize) < 0)
     116      {
     117        printf ("ftruncate failed: %m\n");
     118        result = 1;
     119      }
     120  
     121    fflush (f);
     122  
     123    c = fgetc (f);
     124    if (c == EOF)
     125      printf ("after truncate fgetc -> EOF (feof = %d, ferror = %d)\n",
     126  	    feof (f), ferror (f));
     127    else
     128      {
     129        printf ("after truncate fgetc returned '%c' (feof = %d, ferror = %d)\n",
     130  	      c, feof (f), ferror (f));
     131        result = 1;
     132      }
     133  
     134    fclose (f);
     135  
     136    return result;
     137  }