tests: add signature checks
[gnulib.git] / tests / test-pipe2.c
1 /* Test of pipe2.
2    Copyright (C) 2009 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 #include <config.h>
19
20 #include <unistd.h>
21
22 #include "signature.h"
23 SIGNATURE_CHECK (pipe2, int, (int[2], int));
24
25 #include <fcntl.h>
26 #include <stdbool.h>
27
28 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
29 /* Get declarations of the Win32 API functions.  */
30 # define WIN32_LEAN_AND_MEAN
31 # include <windows.h>
32 #endif
33
34 #include "binary-io.h"
35
36 #define ASSERT(expr) \
37   do                                                                         \
38     {                                                                        \
39       if (!(expr))                                                           \
40         {                                                                    \
41           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
42           fflush (stderr);                                                   \
43           abort ();                                                          \
44         }                                                                    \
45     }                                                                        \
46   while (0)
47
48 /* Return true if FD is open.  */
49 static bool
50 is_open (int fd)
51 {
52 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
53   /* On Win32, the initial state of unassigned standard file
54      descriptors is that they are open but point to an
55      INVALID_HANDLE_VALUE, and there is no fcntl.  */
56   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
57 #else
58 # ifndef F_GETFL
59 #  error Please port fcntl to your platform
60 # endif
61   return 0 <= fcntl (fd, F_GETFL);
62 #endif
63 }
64
65 /* Return true if FD is not inherited to child processes.  */
66 static bool
67 is_cloexec (int fd)
68 {
69 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
70   HANDLE h = (HANDLE) _get_osfhandle (fd);
71   DWORD flags;
72   ASSERT (GetHandleInformation (h, &flags));
73   return (flags & HANDLE_FLAG_INHERIT) == 0;
74 #else
75   int flags;
76   ASSERT ((flags = fcntl (fd, F_GETFD)) >= 0);
77   return (flags & FD_CLOEXEC) != 0;
78 #endif
79 }
80
81 /* Return true if FD is in non-blocking mode.  */
82 static bool
83 is_nonblocking (int fd)
84 {
85 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
86   /* We don't use the non-blocking mode for sockets here.  */
87   return 0;
88 #else
89   int flags;
90   ASSERT ((flags = fcntl (fd, F_GETFL)) >= 0);
91   return (flags & O_NONBLOCK) != 0;
92 #endif
93 }
94
95 int
96 main ()
97 {
98   int use_nonblocking;
99   int use_cloexec;
100
101 #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
102   for (use_nonblocking = 0; use_nonblocking <= 1; use_nonblocking++)
103 #else
104   use_nonblocking = 0;
105 #endif
106 #if defined O_CLOEXEC
107     for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++)
108 #else
109     use_cloexec = 0;
110 #endif
111       {
112         int o_flags;
113         int fd[2];
114
115         o_flags = 0;
116 #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
117         if (use_nonblocking)
118           o_flags |= O_NONBLOCK;
119 #endif
120 #if defined O_CLOEXEC
121         if (use_cloexec)
122           o_flags |= O_CLOEXEC;
123 #endif
124
125         fd[0] = -1;
126         fd[1] = -1;
127         ASSERT (pipe2 (fd, o_flags) >= 0);
128         ASSERT (fd[0] >= 0);
129         ASSERT (fd[1] >= 0);
130         ASSERT (fd[0] != fd[1]);
131         ASSERT (is_open (fd[0]) >= 0);
132         ASSERT (is_open (fd[1]) >= 0);
133         if (use_cloexec)
134           {
135             ASSERT (is_cloexec (fd[0]));
136             ASSERT (is_cloexec (fd[1]));
137           }
138         else
139           {
140             ASSERT (!is_cloexec (fd[0]));
141             ASSERT (!is_cloexec (fd[1]));
142           }
143         if (use_nonblocking)
144           {
145             ASSERT (is_nonblocking (fd[0]));
146             ASSERT (is_nonblocking (fd[1]));
147           }
148         else
149           {
150             ASSERT (!is_nonblocking (fd[0]));
151             ASSERT (!is_nonblocking (fd[1]));
152           }
153       }
154
155   return 0;
156 }