fflush: also replace fclose when fixing fflush
[gnulib.git] / tests / test-fclose.c
1 /* Test of fclose module.
2    Copyright (C) 2011 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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Eric Blake.  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23
24 #include "signature.h"
25 SIGNATURE_CHECK (fclose, int, (FILE *));
26
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32
33 #include "macros.h"
34
35 #define BASE "test-fclose.t"
36
37 int
38 main (int argc, char **argv)
39 {
40   const char buf[] = "hello world";
41   int fd;
42   int fd2;
43   FILE *f;
44
45   /* Prepare a seekable file.  */
46   fd = open (BASE, O_RDWR | O_CREAT | O_TRUNC, 0600);
47   ASSERT (0 <= fd);
48   ASSERT (write (fd, buf, sizeof buf) == sizeof buf);
49   ASSERT (lseek (fd, 1, SEEK_SET) == 1);
50
51   /* Create an output stream visiting the file; when it is closed, all
52      other file descriptors visiting the file must see the new file
53      position.  */
54   fd2 = dup (fd);
55   ASSERT (0 <= fd2);
56   f = fdopen (fd2, "w");
57   ASSERT (f);
58   ASSERT (fputc (buf[1], f) == buf[1]);
59   ASSERT (fclose (f) == 0);
60   errno = 0;
61   ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
62   ASSERT (errno == EBADF);
63   ASSERT (lseek (fd, 0, SEEK_CUR) == 2);
64
65 #if GNULIB_FFLUSH
66   /* Likewise for an input stream, but only when we know fflush works
67      on input streams.  */
68   fd2 = dup (fd);
69   ASSERT (0 <= fd2);
70   f = fdopen (fd2, "r");
71   ASSERT (f);
72   ASSERT (fgetc (f) == buf[2]);
73   ASSERT (fclose (f) == 0);
74   errno = 0;
75   ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
76   ASSERT (errno == EBADF);
77   ASSERT (lseek (fd, 0, SEEK_CUR) == 3);
78 #endif
79
80   /* Test that fclose() sets errno if someone else closes the stream
81      fd behind the back of stdio.  */
82   f = fdopen (fd, "w+");
83   ASSERT (f);
84   ASSERT (close (fd) == 0);
85   errno = 0;
86   ASSERT (fclose (f) == EOF);
87   ASSERT (errno == EBADF);
88
89   /* Clean up.  */
90   ASSERT (remove (BASE) == 0);
91
92   return 0;
93 }