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