(root)/
m4-1.4.19/
tests/
test-fflush.c
       1  /* Test of POSIX compatible fflush() function.
       2     Copyright (C) 2007, 2009-2021 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 Eric Blake, 2007.  */
      18  
      19  #include <config.h>
      20  
      21  /* None of the files accessed by this test are large, so disable the
      22     ftell link warning if we are not using the gnulib ftell module.  */
      23  #define _GL_NO_LARGE_FILES
      24  #include <stdio.h>
      25  
      26  #include "signature.h"
      27  SIGNATURE_CHECK (fflush, int, (FILE *));
      28  
      29  #include <errno.h>
      30  #include <unistd.h>
      31  
      32  #include "macros.h"
      33  
      34  int
      35  main (void)
      36  {
      37    FILE *f;
      38    char buffer[10];
      39    int fd;
      40  
      41    /* Create test file.  */
      42    f = fopen ("test-fflush.txt", "w");
      43    if (!f || fwrite ("1234567890ABCDEFG", 1, 17, f) != 17 || fclose (f) != 0)
      44      {
      45        fputs ("Failed to create sample file.\n", stderr);
      46        unlink ("test-fflush.txt");
      47        return 1;
      48      }
      49  
      50    /* Test fflush.  */
      51    f = fopen ("test-fflush.txt", "r");
      52    ASSERT (f != NULL);
      53    fd = fileno (f);
      54    if (!f || 0 > fd || fread (buffer, 1, 5, f) != 5)
      55      {
      56        fputs ("Failed initial read of sample file.\n", stderr);
      57        if (f)
      58          fclose (f);
      59        unlink ("test-fflush.txt");
      60        return 1;
      61      }
      62    /* For deterministic results, ensure f read a bigger buffer.
      63       This is not the case on BeOS, nor on uClibc.  */
      64  #if !(defined __BEOS__ || defined __UCLIBC__)
      65    if (lseek (fd, 0, SEEK_CUR) == 5)
      66      {
      67        fputs ("Sample file was not buffered after fread.\n", stderr);
      68        fclose (f);
      69        unlink ("test-fflush.txt");
      70        return 1;
      71      }
      72  #endif
      73    /* POSIX requires fflush-fseek to set file offset of fd.  */
      74    if (fflush (f) != 0 || fseeko (f, 0, SEEK_CUR) != 0)
      75      {
      76        fputs ("Failed to flush-fseek sample file.\n", stderr);
      77        fclose (f);
      78        unlink ("test-fflush.txt");
      79        return 1;
      80      }
      81    /* Check that offset is correct.  */
      82    if (lseek (fd, 0, SEEK_CUR) != 5)
      83      {
      84        fprintf (stderr, "File offset is wrong after fseek: %ld.\n",
      85                 (long) lseek (fd, 0, SEEK_CUR));
      86        fclose (f);
      87        unlink ("test-fflush.txt");
      88        return 1;
      89      }
      90    if (ftell (f) != 5)
      91      {
      92        fprintf (stderr, "ftell result is wrong after fseek: %ld.\n",
      93                 (long) ftell (f));
      94        fclose (f);
      95        unlink ("test-fflush.txt");
      96        return 1;
      97      }
      98    /* Check that file reading resumes at correct location.  */
      99    if (fgetc (f) != '6')
     100      {
     101        fputs ("Failed to read next byte after fseek.\n", stderr);
     102        fclose (f);
     103        unlink ("test-fflush.txt");
     104        return 1;
     105      }
     106    /* For deterministic results, ensure f read a bigger buffer.  */
     107    if (lseek (fd, 0, SEEK_CUR) == 6)
     108      {
     109        fputs ("Sample file was not buffered after fgetc.\n", stderr);
     110        fclose (f);
     111        unlink ("test-fflush.txt");
     112        return 1;
     113      }
     114    /* POSIX requires fflush-fseeko to set file offset of fd.  */
     115    if (fflush (f) != 0 || fseeko (f, 0, SEEK_CUR) != 0)
     116      {
     117        fputs ("Failed to flush-fseeko sample file.\n", stderr);
     118        fclose (f);
     119        unlink ("test-fflush.txt");
     120        return 1;
     121      }
     122    /* Check that offset is correct.  */
     123    if (lseek (fd, 0, SEEK_CUR) != 6)
     124      {
     125        fprintf (stderr, "File offset is wrong after fseeko: %ld.\n",
     126                 (long) lseek (fd, 0, SEEK_CUR));
     127        fclose (f);
     128        unlink ("test-fflush.txt");
     129        return 1;
     130      }
     131    if (ftell (f) != 6)
     132      {
     133        fprintf (stderr, "ftell result is wrong after fseeko: %ld.\n",
     134                 (long) ftell (f));
     135        fclose (f);
     136        unlink ("test-fflush.txt");
     137        return 1;
     138      }
     139    /* Check that file reading resumes at correct location.  */
     140    if (fgetc (f) != '7')
     141      {
     142        fputs ("Failed to read next byte after fseeko.\n", stderr);
     143        fclose (f);
     144        unlink ("test-fflush.txt");
     145        return 1;
     146      }
     147    fclose (f);
     148  
     149    /* Test that fflush() sets errno if someone else closes the stream
     150       fd behind the back of stdio.  */
     151    {
     152      FILE *fp = fopen ("test-fflush.txt", "w");
     153      ASSERT (fp != NULL);
     154      fputc ('x', fp);
     155      ASSERT (close (fileno (fp)) == 0);
     156      errno = 0;
     157      ASSERT (fflush (fp) == EOF);
     158      ASSERT (errno == EBADF);
     159      fclose (fp);
     160    }
     161  
     162    /* Test that fflush() sets errno if the stream was constructed with
     163       an invalid file descriptor.  */
     164    {
     165      FILE *fp = fdopen (-1, "w");
     166      if (fp != NULL)
     167        {
     168          fputc ('x', fp);
     169          errno = 0;
     170          ASSERT (fflush (fp) == EOF);
     171          ASSERT (errno == EBADF);
     172        }
     173    }
     174    {
     175      FILE *fp;
     176      close (99);
     177      fp = fdopen (99, "w");
     178      if (fp != NULL)
     179        {
     180          fputc ('x', fp);
     181          errno = 0;
     182          ASSERT (fflush (fp) == EOF);
     183          ASSERT (errno == EBADF);
     184        }
     185    }
     186  
     187    /* Clean up.  */
     188    unlink ("test-fflush.txt");
     189  
     190    return 0;
     191  }