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