maint: update copyright
[gnulib.git] / tests / test-fflush.c
1 /* Test of POSIX compatible fflush() function.
2    Copyright (C) 2007, 2009-2014 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 <http://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 }