digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
[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 <fcntl.h>
23 #include <stdbool.h>
24
25 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
26 /* Get declarations of the Win32 API functions.  */
27 # define WIN32_LEAN_AND_MEAN
28 # include <windows.h>
29 #endif
30
31 #include "binary-io.h"
32
33 #define ASSERT(expr) \
34   do                                                                         \
35     {                                                                        \
36       if (!(expr))                                                           \
37         {                                                                    \
38           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
39           fflush (stderr);                                                   \
40           abort ();                                                          \
41         }                                                                    \
42     }                                                                        \
43   while (0)
44
45 /* Return true if FD is open.  */
46 static bool
47 is_open (int fd)
48 {
49 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
50   /* On Win32, 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
64 is_cloexec (int fd)
65 {
66 #if (defined _WIN32 || 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 /* Return true if FD is in non-blocking mode.  */
79 static bool
80 is_nonblocking (int fd)
81 {
82 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
83   /* We don't use the non-blocking mode for sockets here.  */
84   return 0;
85 #else
86   int flags;
87   ASSERT ((flags = fcntl (fd, F_GETFL)) >= 0);
88   return (flags & O_NONBLOCK) != 0;
89 #endif
90 }
91
92 int
93 main ()
94 {
95   int use_nonblocking;
96   int use_cloexec;
97
98 #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
99   for (use_nonblocking = 0; use_nonblocking <= 1; use_nonblocking++)
100 #else
101   use_nonblocking = 0;
102 #endif
103 #if defined O_CLOEXEC
104     for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++)
105 #else
106     use_cloexec = 0;
107 #endif
108       {
109         int o_flags;
110         int fd[2];
111
112         o_flags = 0;
113 #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
114         if (use_nonblocking)
115           o_flags |= O_NONBLOCK;
116 #endif
117 #if defined O_CLOEXEC
118         if (use_cloexec)
119           o_flags |= O_CLOEXEC;
120 #endif
121
122         fd[0] = -1;
123         fd[1] = -1;
124         ASSERT (pipe2 (fd, o_flags) >= 0);
125         ASSERT (fd[0] >= 0);
126         ASSERT (fd[1] >= 0);
127         ASSERT (fd[0] != fd[1]);
128         ASSERT (is_open (fd[0]) >= 0);
129         ASSERT (is_open (fd[1]) >= 0);
130         if (use_cloexec)
131           {
132             ASSERT (is_cloexec (fd[0]));
133             ASSERT (is_cloexec (fd[1]));
134           }
135         else
136           {
137             ASSERT (!is_cloexec (fd[0]));
138             ASSERT (!is_cloexec (fd[1]));
139           }
140         if (use_nonblocking)
141           {
142             ASSERT (is_nonblocking (fd[0]));
143             ASSERT (is_nonblocking (fd[1]));
144           }
145         else
146           {
147             ASSERT (!is_nonblocking (fd[0]));
148             ASSERT (!is_nonblocking (fd[1]));
149           }
150       }
151
152   return 0;
153 }