root/maint/gnulib/tests/test-fclose.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   1 /* Test of fclose module.
   2    Copyright (C) 2011-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, or (at your option)
   7    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.  */
  18 
  19 #include <config.h>
  20 
  21 #include <stdio.h>
  22 
  23 #include "signature.h"
  24 SIGNATURE_CHECK (fclose, int, (FILE *));
  25 
  26 #include <errno.h>
  27 #include <fcntl.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <unistd.h>
  31 
  32 #include "macros.h"
  33 
  34 #define BASE "test-fclose.t"
  35 
  36 int
  37 main (int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  38 {
  39   const char buf[] = "hello world";
  40   int fd;
  41   int fd2;
  42   FILE *f;
  43 
  44   /* Prepare a seekable file.  */
  45   fd = open (BASE, O_RDWR | O_CREAT | O_TRUNC, 0600);
  46   ASSERT (0 <= fd);
  47   ASSERT (write (fd, buf, sizeof buf) == sizeof buf);
  48   ASSERT (lseek (fd, 1, SEEK_SET) == 1);
  49 
  50   /* Create an output stream visiting the file; when it is closed, all
  51      other file descriptors visiting the file must see the new file
  52      position.  */
  53   fd2 = dup (fd);
  54   ASSERT (0 <= fd2);
  55   f = fdopen (fd2, "w");
  56   ASSERT (f);
  57   ASSERT (fputc (buf[1], f) == buf[1]);
  58   ASSERT (fclose (f) == 0);
  59   errno = 0;
  60   ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
  61   ASSERT (errno == EBADF);
  62   ASSERT (lseek (fd, 0, SEEK_CUR) == 2);
  63 
  64   /* Likewise for an input stream.  */
  65   fd2 = dup (fd);
  66   ASSERT (0 <= fd2);
  67   f = fdopen (fd2, "r");
  68   ASSERT (f);
  69   ASSERT (fgetc (f) == buf[2]);
  70   ASSERT (fclose (f) == 0);
  71   errno = 0;
  72   ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
  73   ASSERT (errno == EBADF);
  74   ASSERT (lseek (fd, 0, SEEK_CUR) == 3);
  75 
  76   /* Test that fclose() sets errno if someone else closes the stream
  77      fd behind the back of stdio.  */
  78   {
  79     FILE *fp = fdopen (fd, "w+");
  80     ASSERT (fp != NULL);
  81     ASSERT (close (fd) == 0);
  82     errno = 0;
  83     ASSERT (fclose (fp) == EOF);
  84     ASSERT (errno == EBADF);
  85   }
  86 
  87   /* Test that fclose() sets errno if the stream was constructed with
  88      an invalid file descriptor.  */
  89   {
  90     FILE *fp = fdopen (-1, "r");
  91     if (fp != NULL)
  92       {
  93         errno = 0;
  94         ASSERT (fclose (fp) == EOF);
  95         ASSERT (errno == EBADF);
  96       }
  97   }
  98   {
  99     FILE *fp;
 100     close (99);
 101     fp = fdopen (99, "r");
 102     if (fp != NULL)
 103       {
 104         errno = 0;
 105         ASSERT (fclose (fp) == EOF);
 106         ASSERT (errno == EBADF);
 107       }
 108   }
 109 
 110   /* Clean up.  */
 111   ASSERT (remove (BASE) == 0);
 112 
 113   return 0;
 114 }

/* [previous][next][first][last][top][bottom][index][help] */