VirtualBox

source: kBuild/vendor/grep/current/gnulib-tests/test-dup-safer.c@ 3630

Last change on this file since 3630 was 3529, checked in by bird, 3 years ago

Imported grep 3.7 from grep-3.7.tar.gz (sha256: c22b0cf2d4f6bbe599c902387e8058990e1eee99aef333a203829e5fd3dbb342), applying minimal auto-props.

  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1/* Test that dup_safer leaves standard fds alone.
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 of the License, or
7 (at your option) 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/* Written by Eric Blake <[email protected]>, 2009. */
18
19#include <config.h>
20
21#include "unistd--.h"
22
23#include <fcntl.h>
24#include <errno.h>
25#include <stdbool.h>
26#include <stdio.h>
27#include <unistd.h>
28
29#include "binary-io.h"
30#include "cloexec.h"
31
32#if defined _WIN32 && ! defined __CYGWIN__
33/* Get declarations of the native Windows API functions. */
34# define WIN32_LEAN_AND_MEAN
35# include <windows.h>
36/* Get _get_osfhandle. */
37# if GNULIB_MSVC_NOTHROW
38# include "msvc-nothrow.h"
39# else
40# include <io.h>
41# endif
42#endif
43
44#if !O_BINARY
45# define set_binary_mode(f,m) zero ()
46static int zero (void) { return 0; }
47#endif
48
49/* This test intentionally closes stderr. So, we arrange to have fd 10
50 (outside the range of interesting fd's during the test) set up to
51 duplicate the original stderr. */
52
53#define BACKUP_STDERR_FILENO 10
54#define ASSERT_STREAM myerr
55#include "macros.h"
56
57static FILE *myerr;
58
59/* Return true if FD is open. */
60static bool
61is_open (int fd)
62{
63#if defined _WIN32 && ! defined __CYGWIN__
64 /* On native Windows, the initial state of unassigned standard file
65 descriptors is that they are open but point to an
66 INVALID_HANDLE_VALUE, and there is no fcntl. */
67 return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
68#else
69# ifndef F_GETFL
70# error Please port fcntl to your platform
71# endif
72 return 0 <= fcntl (fd, F_GETFL);
73#endif
74}
75
76/* Return true if FD is open and inheritable across exec/spawn. */
77static bool
78is_inheritable (int fd)
79{
80#if defined _WIN32 && ! defined __CYGWIN__
81 /* On native Windows, the initial state of unassigned standard file
82 descriptors is that they are open but point to an
83 INVALID_HANDLE_VALUE, and there is no fcntl. */
84 HANDLE h = (HANDLE) _get_osfhandle (fd);
85 DWORD flags;
86 if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
87 return 0;
88 return (flags & HANDLE_FLAG_INHERIT) != 0;
89#else
90# ifndef F_GETFD
91# error Please port fcntl to your platform
92# endif
93 int i = fcntl (fd, F_GETFD);
94 return 0 <= i && (i & FD_CLOEXEC) == 0;
95#endif
96}
97
98/* Return true if FD is open in the given MODE, which is either
99 O_TEXT or O_BINARY. */
100static bool
101is_mode (int fd, int mode)
102{
103 int value = set_binary_mode (fd, O_BINARY);
104 set_binary_mode (fd, value);
105 return mode == value;
106}
107
108#define witness "test-dup-safer.txt"
109
110int
111main (void)
112{
113 int i;
114 int fd;
115 int bad_fd = getdtablesize ();
116
117 /* We close fd 2 later, so save it in fd 10. */
118 if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
119 || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
120 return 2;
121
122 /* Create file for later checks. */
123 fd = creat (witness, 0600);
124 ASSERT (STDERR_FILENO < fd);
125
126 /* Four iterations, with progressively more standard descriptors
127 closed. */
128 for (i = -1; i <= STDERR_FILENO; i++)
129 {
130 if (0 <= i)
131 ASSERT (close (i) == 0);
132
133 /* Detect errors. */
134 errno = 0;
135 ASSERT (dup (-1) == -1);
136 ASSERT (errno == EBADF);
137 errno = 0;
138 ASSERT (dup (bad_fd) == -1);
139 ASSERT (errno == EBADF);
140 close (fd + 1);
141 errno = 0;
142 ASSERT (dup (fd + 1) == -1);
143 ASSERT (errno == EBADF);
144
145 /* Preserve text vs. binary. */
146 set_binary_mode (fd, O_BINARY);
147 ASSERT (dup (fd) == fd + 1);
148 ASSERT (is_open (fd + 1));
149 ASSERT (is_inheritable (fd + 1));
150 ASSERT (is_mode (fd + 1, O_BINARY));
151
152 ASSERT (close (fd + 1) == 0);
153 set_binary_mode (fd, O_TEXT);
154 ASSERT (dup (fd) == fd + 1);
155 ASSERT (is_open (fd + 1));
156 ASSERT (is_inheritable (fd + 1));
157 ASSERT (is_mode (fd + 1, O_TEXT));
158
159 /* Create cloexec copy. */
160 ASSERT (close (fd + 1) == 0);
161 ASSERT (fd_safer_flag (dup_cloexec (fd), O_CLOEXEC) == fd + 1);
162 ASSERT (set_cloexec_flag (fd + 1, true) == 0);
163 ASSERT (is_open (fd + 1));
164 ASSERT (!is_inheritable (fd + 1));
165 ASSERT (close (fd) == 0);
166
167 /* dup always creates inheritable copies. Also, check that
168 earliest slot past std fds is used. */
169 ASSERT (dup (fd + 1) == fd);
170 ASSERT (is_open (fd));
171 ASSERT (is_inheritable (fd));
172 ASSERT (close (fd + 1) == 0);
173 }
174
175 /* Cleanup. */
176 ASSERT (close (fd) == 0);
177 ASSERT (unlink (witness) == 0);
178
179 return 0;
180}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette