1
/* -*- buffer-read-only: t -*- vi: set ro: */
2
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
4
Copyright (C) 2009, 2010 Free Software Foundation, Inc.
6
This program is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 3 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
26
#include "signature.h"
27
SIGNATURE_CHECK (fcntl, int, (int, int, ...));
35
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
36
/* Get declarations of the Win32 API functions. */
37
# define WIN32_LEAN_AND_MEAN
41
#include "binary-io.h"
44
/* Use O_CLOEXEC if available, but test works without it. */
50
# define setmode(f,m) zero ()
51
static int zero (void) { return 0; }
54
/* Return true if FD is open. */
58
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
59
/* On Win32, the initial state of unassigned standard file
60
descriptors is that they are open but point to an
61
INVALID_HANDLE_VALUE, and there is no fcntl. */
62
return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
65
# error Please port fcntl to your platform
67
return 0 <= fcntl (fd, F_GETFL);
71
/* Return true if FD is open and inheritable across exec/spawn. */
73
is_inheritable (int fd)
75
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
76
/* On Win32, the initial state of unassigned standard file
77
descriptors is that they are open but point to an
78
INVALID_HANDLE_VALUE, and there is no fcntl. */
79
HANDLE h = (HANDLE) _get_osfhandle (fd);
81
if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
83
return (flags & HANDLE_FLAG_INHERIT) != 0;
86
# error Please port fcntl to your platform
88
int i = fcntl (fd, F_GETFD);
89
return 0 <= i && (i & FD_CLOEXEC) == 0;
93
/* Return non-zero if FD is open in the given MODE, which is either
94
O_TEXT or O_BINARY. */
96
is_mode (int fd, int mode)
98
int value = setmode (fd, O_BINARY);
100
return mode == value;
103
/* Since native fcntl can have more supported operations than our
104
replacement is aware of, and since various operations assign
105
different types to the vararg argument, a wrapper around fcntl must
106
be able to pass a vararg of unknown type on through to the original
107
fcntl. Make sure that this works properly: func1 behaves like the
108
original fcntl interpreting the vararg as an int or a pointer to a
109
struct, and func2 behaves like rpl_fcntl that doesn't know what
123
i = va_arg (arg, int);
126
struct dummy_struct *s = va_arg (arg, struct dummy_struct *);
138
p = va_arg (arg, void *);
143
/* Ensure that all supported fcntl actions are distinct, and
144
usable in preprocessor expressions. */
154
case F_DUPFD_CLOEXEC:
217
const char *file = "test-fcntl.tmp";
220
/* Sanity check that rpl_fcntl is likely to work. */
221
ASSERT (func2 (1, 2) == 2);
222
ASSERT (func2 (2, -2) == -2);
223
ASSERT (func2 (3, 0x80000000) == 0x80000000);
225
struct dummy_struct s = { 0L, 4 };
226
ASSERT (func2 (4, &s) == 4);
230
/* Assume std descriptors were provided by invoker, and ignore fds
231
that might have been inherited. */
232
fd = creat (file, 0600);
233
ASSERT (STDERR_FILENO < fd);
237
/* For F_DUPFD*, the source must be valid. */
239
ASSERT (fcntl (-1, F_DUPFD, 0) == -1);
240
ASSERT (errno == EBADF);
242
ASSERT (fcntl (fd + 1, F_DUPFD, 0) == -1);
243
ASSERT (errno == EBADF);
245
ASSERT (fcntl (10000000, F_DUPFD, 0) == -1);
246
ASSERT (errno == EBADF);
248
ASSERT (fcntl (-1, F_DUPFD_CLOEXEC, 0) == -1);
249
ASSERT (errno == EBADF);
251
ASSERT (fcntl (fd + 1, F_DUPFD_CLOEXEC, 0) == -1);
252
ASSERT (errno == EBADF);
254
ASSERT (fcntl (10000000, F_DUPFD_CLOEXEC, 0) == -1);
255
ASSERT (errno == EBADF);
257
/* For F_DUPFD*, the destination must be valid. */
258
ASSERT (getdtablesize () < 10000000);
260
ASSERT (fcntl (fd, F_DUPFD, -1) == -1);
261
ASSERT (errno == EINVAL);
263
ASSERT (fcntl (fd, F_DUPFD, 10000000) == -1);
264
ASSERT (errno == EINVAL);
265
ASSERT (getdtablesize () < 10000000);
267
ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, -1) == -1);
268
ASSERT (errno == EINVAL);
270
ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, 10000000) == -1);
271
ASSERT (errno == EINVAL);
273
/* For F_DUPFD*, check for correct inheritance, as well as
274
preservation of text vs. binary. */
275
setmode (fd, O_BINARY);
276
ASSERT (is_open (fd));
277
ASSERT (!is_open (fd + 1));
278
ASSERT (!is_open (fd + 2));
279
ASSERT (is_inheritable (fd));
280
ASSERT (is_mode (fd, O_BINARY));
282
ASSERT (fcntl (fd, F_DUPFD, fd) == fd + 1);
283
ASSERT (is_open (fd));
284
ASSERT (is_open (fd + 1));
285
ASSERT (!is_open (fd + 2));
286
ASSERT (is_inheritable (fd + 1));
287
ASSERT (is_mode (fd, O_BINARY));
288
ASSERT (is_mode (fd + 1, O_BINARY));
289
ASSERT (close (fd + 1) == 0);
291
ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, fd + 2) == fd + 2);
292
ASSERT (is_open (fd));
293
ASSERT (!is_open (fd + 1));
294
ASSERT (is_open (fd + 2));
295
ASSERT (is_inheritable (fd));
296
ASSERT (!is_inheritable (fd + 2));
297
ASSERT (is_mode (fd, O_BINARY));
298
ASSERT (is_mode (fd + 2, O_BINARY));
299
ASSERT (close (fd) == 0);
301
setmode (fd + 2, O_TEXT);
302
ASSERT (fcntl (fd + 2, F_DUPFD, fd + 1) == fd + 1);
303
ASSERT (!is_open (fd));
304
ASSERT (is_open (fd + 1));
305
ASSERT (is_open (fd + 2));
306
ASSERT (is_inheritable (fd + 1));
307
ASSERT (!is_inheritable (fd + 2));
308
ASSERT (is_mode (fd + 1, O_TEXT));
309
ASSERT (is_mode (fd + 2, O_TEXT));
310
ASSERT (close (fd + 1) == 0);
312
ASSERT (fcntl (fd + 2, F_DUPFD_CLOEXEC, 0) == fd);
313
ASSERT (is_open (fd));
314
ASSERT (!is_open (fd + 1));
315
ASSERT (is_open (fd + 2));
316
ASSERT (!is_inheritable (fd));
317
ASSERT (!is_inheritable (fd + 2));
318
ASSERT (is_mode (fd, O_TEXT));
319
ASSERT (is_mode (fd + 2, O_TEXT));
320
ASSERT (close (fd + 2) == 0);
324
ASSERT (fcntl (-1, F_GETFD) == -1);
325
ASSERT (errno == EBADF);
327
ASSERT (fcntl (fd + 1, F_GETFD) == -1);
328
ASSERT (errno == EBADF);
330
ASSERT (fcntl (10000000, F_GETFD) == -1);
331
ASSERT (errno == EBADF);
333
int result = fcntl (fd, F_GETFD);
334
ASSERT (0 <= result);
335
ASSERT ((result & FD_CLOEXEC) == FD_CLOEXEC);
336
ASSERT (dup (fd) == fd + 1);
337
result = fcntl (fd + 1, F_GETFD);
338
ASSERT (0 <= result);
339
ASSERT ((result & FD_CLOEXEC) == 0);
340
ASSERT (close (fd + 1) == 0);
344
ASSERT (close (fd) == 0);
345
ASSERT (unlink (file) == 0);