spawn: Use special invocation for <spawn.h> on OS/2 kLIBC.
[gnulib.git] / tests / test-pipe2.c
blob97d6d9cb3c357d0fc43081f697dd5871bc6d8e56
1 /* Test of pipe2.
2 Copyright (C) 2009-2021 Free Software Foundation, Inc.
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.
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.
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/>. */
17 #include <config.h>
19 #include <unistd.h>
21 #include "signature.h"
22 SIGNATURE_CHECK (pipe2, int, (int[2], int));
24 #include <fcntl.h>
25 #include <stdbool.h>
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
39 #include "binary-io.h"
40 #include "macros.h"
41 #if GNULIB_NONBLOCKING
42 # include "nonblocking.h"
43 #endif
45 /* Return true if FD is open. */
46 static bool
47 is_open (int fd)
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
62 /* Return true if FD is not inherited to child processes. */
63 static bool
64 is_cloexec (int fd)
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
78 #if ! GNULIB_NONBLOCKING
79 static int
80 get_nonblocking_flag (int fd)
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
93 #endif
95 int
96 main ()
98 int use_nonblocking;
99 int use_cloexec;
101 for (use_nonblocking = 0; use_nonblocking <= !!O_NONBLOCK; use_nonblocking++)
102 for (use_cloexec = 0; use_cloexec <= !!O_CLOEXEC; use_cloexec++)
104 int o_flags;
105 int fd[2];
107 o_flags = 0;
108 if (use_nonblocking)
109 o_flags |= O_NONBLOCK;
110 if (use_cloexec)
111 o_flags |= O_CLOEXEC;
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)
123 ASSERT (is_cloexec (fd[0]));
124 ASSERT (is_cloexec (fd[1]));
126 else
128 ASSERT (!is_cloexec (fd[0]));
129 ASSERT (!is_cloexec (fd[1]));
131 if (use_nonblocking)
133 ASSERT (get_nonblocking_flag (fd[0]) == 1);
134 ASSERT (get_nonblocking_flag (fd[1]) == 1);
136 else
138 ASSERT (get_nonblocking_flag (fd[0]) == 0);
139 ASSERT (get_nonblocking_flag (fd[1]) == 0);
142 ASSERT (close (fd[0]) == 0);
143 ASSERT (close (fd[1]) == 0);
146 return 0;