pty: Activate the signature wrapper of forkpty.
[gnulib.git] / tests / test-fclose.c
1 /* Test of fclose module.
2    Copyright (C) 2011-2013 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 <http://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)
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 }