(root)/
sed-4.9/
gnulib-tests/
test-fwriting.c
       1  /* Test of fwriting() function.
       2     Copyright (C) 2007-2022 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 "fwriting.h"
      25  
      26  #include <stdio.h>
      27  
      28  #include "macros.h"
      29  
      30  #define TESTFILE "t-fwriting.tmp"
      31  
      32  int
      33  main ()
      34  {
      35    FILE *fp;
      36  
      37    /* Create a file with some contents.  Write-only file is always writing.  */
      38    fp = fopen (TESTFILE, "w");
      39    if (fp == NULL)
      40      goto skip;
      41    ASSERT (fwriting (fp));
      42    if (fwrite ("foobarsh", 1, 8, fp) < 8)
      43      goto skip;
      44    ASSERT (fwriting (fp));
      45    if (fclose (fp))
      46      goto skip;
      47  
      48    /* Open it in read-only mode.  Read-only file is never writing.  */
      49    fp = fopen (TESTFILE, "r");
      50    if (fp == NULL)
      51      goto skip;
      52    ASSERT (!fwriting (fp));
      53    if (fgetc (fp) != 'f')
      54      goto skip;
      55    ASSERT (!fwriting (fp));
      56    if (fseek (fp, 2, SEEK_CUR))
      57      goto skip;
      58    ASSERT (!fwriting (fp));
      59    if (fgetc (fp) != 'b')
      60      goto skip;
      61    ASSERT (!fwriting (fp));
      62    fflush (fp);
      63    ASSERT (!fwriting (fp));
      64    if (fgetc (fp) != 'a')
      65      goto skip;
      66    ASSERT (!fwriting (fp));
      67    if (fseek (fp, 0, SEEK_END))
      68      goto skip;
      69    ASSERT (!fwriting (fp));
      70    if (fclose (fp))
      71      goto skip;
      72  
      73    /* Open it in read-write mode.  POSIX requires a reposition (fseek,
      74       fsetpos, rewind) or fflush when transitioning from write to read,
      75       fwriting is only deterministic after input or output, but this
      76       test case should be portable even on open, after reposition, and
      77       after fflush.  */
      78    /* First a scenario with only fgetc, fseek, fputc.  */
      79    fp = fopen (TESTFILE, "r+");
      80    if (fp == NULL)
      81      goto skip;
      82    ASSERT (!fwriting (fp));
      83    if (fgetc (fp) != 'f')
      84      goto skip;
      85    ASSERT (!fwriting (fp));
      86    if (fseek (fp, 2, SEEK_CUR))
      87      goto skip;
      88    ASSERT (!fwriting (fp));
      89    if (fgetc (fp) != 'b')
      90      goto skip;
      91    ASSERT (!fwriting (fp));
      92    /* This fseek call is necessary when switching from reading to writing.
      93       See the description of fopen(), ISO C 99 7.19.5.3.(6).  */
      94    if (fseek (fp, 0, SEEK_CUR) != 0)
      95      goto skip;
      96    ASSERT (!fwriting (fp));
      97    if (fputc ('x', fp) != 'x')
      98      goto skip;
      99    ASSERT (fwriting (fp));
     100    if (fseek (fp, 0, SEEK_END))
     101      goto skip;
     102    /* freading (fp) is undefined here, because on some implementations (e.g.
     103       glibc) fseek causes a buffer to be read.
     104       fwriting (fp) is undefined as well.  */
     105    if (fclose (fp))
     106      goto skip;
     107  
     108    /* Open it in read-write mode.  POSIX requires a reposition (fseek,
     109       fsetpos, rewind) or fflush when transitioning from write to read,
     110       fwriting is only deterministic after input or output, but this
     111       test case should be portable even on open, after reposition, and
     112       after fflush.  */
     113    /* Here a scenario that includes fflush.  */
     114    fp = fopen (TESTFILE, "r+");
     115    if (fp == NULL)
     116      goto skip;
     117    ASSERT (!fwriting (fp));
     118    if (fgetc (fp) != 'f')
     119      goto skip;
     120    ASSERT (!fwriting (fp));
     121    if (fseek (fp, 2, SEEK_CUR))
     122      goto skip;
     123    ASSERT (!fwriting (fp));
     124    if (fgetc (fp) != 'b')
     125      goto skip;
     126    ASSERT (!fwriting (fp));
     127    fflush (fp);
     128    ASSERT (!fwriting (fp));
     129    if (fgetc (fp) != 'x')
     130      goto skip;
     131    ASSERT (!fwriting (fp));
     132    /* This fseek call is necessary when switching from reading to writing.
     133       See the description of fopen(), ISO C 99 7.19.5.3.(6).  */
     134    if (fseek (fp, 0, SEEK_CUR) != 0)
     135      goto skip;
     136    ASSERT (!fwriting (fp));
     137    if (fputc ('z', fp) != 'z')
     138      goto skip;
     139    ASSERT (fwriting (fp));
     140    if (fseek (fp, 0, SEEK_END))
     141      goto skip;
     142    /* freading (fp) is undefined here, because on some implementations (e.g.
     143       glibc) fseek causes a buffer to be read.
     144       fwriting (fp) is undefined as well.  */
     145    if (fclose (fp))
     146      goto skip;
     147  
     148    /* Open it in append mode.  */
     149    fp = fopen (TESTFILE, "a");
     150    if (fp == NULL)
     151      goto skip;
     152    ASSERT (fwriting (fp));
     153    if (fwrite ("bla", 1, 3, fp) < 3)
     154      goto skip;
     155    ASSERT (fwriting (fp));
     156    if (fclose (fp))
     157      goto skip;
     158  
     159    return 0;
     160  
     161   skip:
     162    fprintf (stderr, "Skipping test: file operations failed.\n");
     163    return 77;
     164  }