(root)/
coreutils-9.4/
gnulib-tests/
test-freading.c
       1  /* Test of freading() function.
       2     Copyright (C) 2007-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
      18  
      19  #include <config.h>
      20  
      21  /* None of the files accessed by this test are large, so disable the
      22     fseek link warning if we are not using the gnulib fseek module.  */
      23  #define _GL_NO_LARGE_FILES
      24  #include "freading.h"
      25  
      26  #include <stdio.h>
      27  
      28  #include "macros.h"
      29  
      30  #define TESTFILE "t-freading.tmp"
      31  
      32  int
      33  main (void)
      34  {
      35    FILE *fp;
      36  
      37    /* Create a file with some contents.  Write-only file is never reading.  */
      38    fp = fopen (TESTFILE, "w");
      39    ASSERT (fp);
      40    ASSERT (!freading (fp));
      41    ASSERT (fwrite ("foobarsh", 1, 8, fp) == 8);
      42    ASSERT (!freading (fp));
      43    ASSERT (fclose (fp) == 0);
      44  
      45    /* Open it in read-only mode.  Read-only file is always reading.  */
      46    fp = fopen (TESTFILE, "r");
      47    ASSERT (fp);
      48    ASSERT (freading (fp));
      49    ASSERT (fgetc (fp) == 'f');
      50    ASSERT (freading (fp));
      51    ASSERT (fseek (fp, 2, SEEK_CUR) == 0);
      52    ASSERT (freading (fp));
      53    ASSERT (fgetc (fp) == 'b');
      54    ASSERT (freading (fp));
      55    fflush (fp);
      56    ASSERT (freading (fp));
      57    ASSERT (fgetc (fp) == 'a');
      58    ASSERT (freading (fp));
      59    ASSERT (fseek (fp, 0, SEEK_END) == 0);
      60    ASSERT (freading (fp));
      61    ASSERT (fclose (fp) == 0);
      62  
      63    /* Open it in read-write mode.  POSIX requires a reposition (fseek,
      64       fsetpos, rewind) or EOF when transitioning from read to write;
      65       freading is only deterministic after input or output, but this
      66       test case should be portable even on open, after reposition, and
      67       at EOF.  */
      68    /* First a scenario with only fgetc, fseek, fputc.  */
      69    fp = fopen (TESTFILE, "r+");
      70    ASSERT (fp);
      71    ASSERT (!freading (fp));
      72    ASSERT (fgetc (fp) == 'f');
      73    ASSERT (freading (fp));
      74    ASSERT (fseek (fp, 2, SEEK_CUR) ==  0);
      75    /* freading (fp) is undefined here, but fwriting (fp) is false.  */
      76    ASSERT (fgetc (fp) == 'b');
      77    ASSERT (freading (fp));
      78    /* This fseek call is necessary when switching from reading to writing.
      79       See the description of fopen(), ISO C 99 7.19.5.3.(6).  */
      80    ASSERT (fseek (fp, 0, SEEK_CUR) == 0);
      81    /* freading (fp) is undefined here, but fwriting (fp) is false.  */
      82    ASSERT (fputc ('x', fp) == 'x');
      83    ASSERT (!freading (fp));
      84    ASSERT (fseek (fp, 0, SEEK_END) == 0);
      85    /* freading (fp) is undefined here, because on some implementations (e.g.
      86       glibc) fseek causes a buffer to be read.
      87       fwriting (fp) is undefined as well.  */
      88    ASSERT (fclose (fp) == 0);
      89  
      90    /* Open it in read-write mode.  POSIX requires a reposition (fseek,
      91       fsetpos, rewind) or EOF when transitioning from read to write;
      92       freading is only deterministic after input or output, but this
      93       test case should be portable even on open, after reposition, and
      94       at EOF.  */
      95    /* Here a scenario that includes fflush.  */
      96    fp = fopen (TESTFILE, "r+");
      97    ASSERT (fp);
      98    ASSERT (!freading (fp));
      99    ASSERT (fgetc (fp) == 'f');
     100    ASSERT (freading (fp));
     101    ASSERT (fseek (fp, 2, SEEK_CUR) == 0);
     102    /* freading (fp) is undefined here, but fwriting (fp) is false.  */
     103    ASSERT (fgetc (fp) == 'b');
     104    ASSERT (freading (fp));
     105    fflush (fp);
     106    /* freading (fp) is undefined here, but fwriting (fp) is false.  */
     107    ASSERT (fgetc (fp) == 'x');
     108    ASSERT (freading (fp));
     109    /* This fseek call is necessary when switching from reading to writing.
     110       See the description of fopen(), ISO C 99 7.19.5.3.(6).  */
     111    ASSERT (fseek (fp, 0, SEEK_CUR) == 0);
     112    /* freading (fp) is undefined here, but fwriting (fp) is false.  */
     113    ASSERT (fputc ('z', fp) == 'z');
     114    ASSERT (!freading (fp));
     115    ASSERT (fseek (fp, 0, SEEK_END) == 0);
     116    /* freading (fp) is undefined here, because on some implementations (e.g.
     117       glibc) fseek causes a buffer to be read.
     118       fwriting (fp) is undefined as well.  */
     119    ASSERT (fclose (fp) == 0);
     120  
     121    /* Open it in append mode.  Write-only file is never reading.  */
     122    fp = fopen (TESTFILE, "a");
     123    ASSERT (fp);
     124    ASSERT (!freading (fp));
     125    ASSERT (fwrite ("bla", 1, 3, fp) == 3);
     126    ASSERT (!freading (fp));
     127    ASSERT (fclose (fp) == 0);
     128    ASSERT (remove (TESTFILE) == 0);
     129    return 0;
     130  }