(root)/
glibc-2.38/
libio/
bug-ungetc4.c
       1  /* Test program for ungetc/fseekpos interaction.
       2     Copyright (C) 2004-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 <stdio.h>
      20  
      21  #include <support/xunistd.h>
      22  
      23  static void do_prepare (void);
      24  #define PREPARE(argc, argv) do_prepare ()
      25  static int do_test (void);
      26  #define TEST_FUNCTION do_test ()
      27  #include "../test-skeleton.c"
      28  
      29  static const char pattern[] = "abcdefghijklmnopqrstuvwxyz";
      30  static char *temp_file;
      31  
      32  static void
      33  do_prepare (void)
      34  {
      35    int fd = create_temp_file ("bug-ungetc.", &temp_file);
      36    if (fd == -1)
      37      {
      38        printf ("cannot create temporary file: %m\n");
      39        exit (1);
      40      }
      41    xwrite (fd, pattern, sizeof (pattern) - 1);
      42    close (fd);
      43  }
      44  
      45  #define TEST_POS 5
      46  
      47  static int
      48  do_one_test (int mode)
      49  {
      50    FILE *f = fopen (temp_file, "r");
      51    if (f == NULL)
      52      {
      53        printf ("%d: could not open temporary file: %m\n", mode);
      54        return 1;
      55      }
      56  
      57    int i;
      58    for (i = 0; i < TEST_POS; ++i)
      59      getc (f);
      60  
      61    fpos_t p;
      62    if (fgetpos (f, &p) != 0)
      63      {
      64        printf ("%d: fgetpos failed: %m\n", mode);
      65        return 1;
      66      }
      67  
      68    if (mode)
      69      {
      70        if (fseek (f, 0, SEEK_SET) != 0)
      71          {
      72            printf ("%d: fseek failed: %m\n", mode);
      73            return 1;
      74          }
      75  
      76        for (i = 0; i < TEST_POS - (mode >= 2); ++i)
      77          getc (f);
      78      }
      79  
      80    if (mode != 2 && ungetc ('X', f) != 'X')
      81      {
      82        printf ("%d: ungetc failed\n", mode);
      83        return 1;
      84      }
      85  
      86    if (mode == 3 && getc (f) != 'X')
      87      {
      88        printf ("%d: getc after ungetc did not return X\n", mode);
      89        return 1;
      90      }
      91  
      92    if (fsetpos (f, &p) != 0)
      93      {
      94        printf ("%d: fsetpos failed: %m\n", mode);
      95        return 1;
      96      }
      97  
      98    if (getc (f) != pattern[TEST_POS])
      99      {
     100        printf ("%d: getc did not return %c\n", mode, pattern[TEST_POS]);
     101        return 1;
     102      }
     103  
     104    fclose (f);
     105  
     106    return 0;
     107  }
     108  
     109  static int
     110  do_test (void)
     111  {
     112    int mode, ret = 0;
     113    for (mode = 0; mode <= 4; mode++)
     114      ret |= do_one_test (mode);
     115    return ret;
     116  }