Mercurial > gnulib
annotate tests/test-dup2.c @ 17363:5a51fb7777a9
sys_select, sys_time: port 2013-01-30 Solaris 2.6 fix to Cygwin
Problem reported by Marco Atzeri in
<http://lists.gnu.org/archive/html/bug-gnulib/2013-03/msg00000.html>.
* lib/sys_select.in.h [HAVE_SYS_SELECT_H && _CYGWIN_SYS_TIME_H]:
Simply delegate to the system <sys/select.h> in this case too.
Also, pay attention to _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H only
if OSF/1, since otherwise Cygwin breaks, and it doesn't seem to
be needed on Solaris either.
* lib/sys_time.in.h [_CYGWIN_SYS_TIME_H]:
Simply delgate to the system <sys/time.h> in this case.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Tue, 19 Mar 2013 09:08:47 -0700 |
parents | 3a09cc104f4c |
children | 160b88fd4691 |
rev | line source |
---|---|
11727 | 1 /* Test duplicating file descriptors. |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16214
diff
changeset
|
2 Copyright (C) 2009-2013 Free Software Foundation, Inc. |
11727 | 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 <http://www.gnu.org/licenses/>. */ | |
16 | |
17 /* Written by Eric Blake <ebb9@byu.net>, 2009. */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #include <unistd.h> | |
22 | |
12489 | 23 #include "signature.h" |
24 SIGNATURE_CHECK (dup2, int, (int, int)); | |
25 | |
11727 | 26 #include <errno.h> |
27 #include <fcntl.h> | |
28 | |
12398
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
29 #include "binary-io.h" |
12512 | 30 |
13073
03de1efbfdd3
Resolve conflict between the two kinds of module indicators.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
31 #if GNULIB_TEST_CLOEXEC |
12512 | 32 # include "cloexec.h" |
33 #endif | |
12391 | 34 |
11727 | 35 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
36 /* Get declarations of the native Windows API functions. */ |
11727 | 37 # define WIN32_LEAN_AND_MEAN |
38 # include <windows.h> | |
15752
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
15684
diff
changeset
|
39 /* Get _get_osfhandle. */ |
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
15684
diff
changeset
|
40 # include "msvc-nothrow.h" |
11727 | 41 #endif |
42 | |
12496
a48d3d749ca5
Refactor common macros used in tests.
Bruno Haible <bruno@clisp.org>
parents:
12489
diff
changeset
|
43 #include "macros.h" |
11727 | 44 |
45 /* Return non-zero if FD is open. */ | |
46 static int | |
47 is_open (int fd) | |
48 { | |
49 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
50 /* On native Windows, the initial state of unassigned standard file |
11727 | 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 | |
13073
03de1efbfdd3
Resolve conflict between the two kinds of module indicators.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
62 #if GNULIB_TEST_CLOEXEC |
12391 | 63 /* Return non-zero if FD is open and inheritable across exec/spawn. */ |
64 static int | |
65 is_inheritable (int fd) | |
66 { | |
12553
5e5b39c63885
test-dup2: avoid compiler warning
Eric Blake <ebb9@byu.net>
parents:
12512
diff
changeset
|
67 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
68 /* On native Windows, the initial state of unassigned standard file |
12391 | 69 descriptors is that they are open but point to an |
70 INVALID_HANDLE_VALUE, and there is no fcntl. */ | |
71 HANDLE h = (HANDLE) _get_osfhandle (fd); | |
72 DWORD flags; | |
73 if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0) | |
74 return 0; | |
75 return (flags & HANDLE_FLAG_INHERIT) != 0; | |
12553
5e5b39c63885
test-dup2: avoid compiler warning
Eric Blake <ebb9@byu.net>
parents:
12512
diff
changeset
|
76 # else |
5e5b39c63885
test-dup2: avoid compiler warning
Eric Blake <ebb9@byu.net>
parents:
12512
diff
changeset
|
77 # ifndef F_GETFD |
5e5b39c63885
test-dup2: avoid compiler warning
Eric Blake <ebb9@byu.net>
parents:
12512
diff
changeset
|
78 # error Please port fcntl to your platform |
5e5b39c63885
test-dup2: avoid compiler warning
Eric Blake <ebb9@byu.net>
parents:
12512
diff
changeset
|
79 # endif |
12391 | 80 int i = fcntl (fd, F_GETFD); |
81 return 0 <= i && (i & FD_CLOEXEC) == 0; | |
12553
5e5b39c63885
test-dup2: avoid compiler warning
Eric Blake <ebb9@byu.net>
parents:
12512
diff
changeset
|
82 # endif |
12391 | 83 } |
13073
03de1efbfdd3
Resolve conflict between the two kinds of module indicators.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
84 #endif /* GNULIB_TEST_CLOEXEC */ |
12391 | 85 |
12398
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
86 #if !O_BINARY |
12399 | 87 # define setmode(f,m) zero () |
88 static int zero (void) { return 0; } | |
12398
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
89 #endif |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
90 |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
91 /* Return non-zero if FD is open in the given MODE, which is either |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
92 O_TEXT or O_BINARY. */ |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
93 static int |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
94 is_mode (int fd, int mode) |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
95 { |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
96 int value = setmode (fd, O_BINARY); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
97 setmode (fd, value); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
98 return mode == value; |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
99 } |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
100 |
11727 | 101 int |
12197
e45d9bb2233e
tests: avoid several compiler warnings
Eric Blake <ebb9@byu.net>
parents:
12154
diff
changeset
|
102 main (void) |
11727 | 103 { |
104 const char *file = "test-dup2.tmp"; | |
105 char buffer[1]; | |
11885 | 106 int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600); |
11727 | 107 |
11825 | 108 /* Assume std descriptors were provided by invoker. */ |
109 ASSERT (STDERR_FILENO < fd); | |
11727 | 110 ASSERT (is_open (fd)); |
11825 | 111 /* Ignore any other fd's leaked into this process. */ |
112 close (fd + 1); | |
113 close (fd + 2); | |
11727 | 114 ASSERT (!is_open (fd + 1)); |
115 ASSERT (!is_open (fd + 2)); | |
116 | |
117 /* Assigning to self must be a no-op. */ | |
118 ASSERT (dup2 (fd, fd) == fd); | |
119 ASSERT (is_open (fd)); | |
120 | |
12154 | 121 /* The source must be valid. */ |
122 errno = 0; | |
123 ASSERT (dup2 (-1, fd) == -1); | |
124 ASSERT (errno == EBADF); | |
17292
3a09cc104f4c
tests: don't assume fd 99 is closed
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
125 close (99); |
12154 | 126 errno = 0; |
15684 | 127 ASSERT (dup2 (99, fd) == -1); |
128 ASSERT (errno == EBADF); | |
129 errno = 0; | |
12154 | 130 ASSERT (dup2 (AT_FDCWD, fd) == -1); |
131 ASSERT (errno == EBADF); | |
132 ASSERT (is_open (fd)); | |
133 | |
11727 | 134 /* If the source is not open, then the destination is unaffected. */ |
135 errno = 0; | |
136 ASSERT (dup2 (fd + 1, fd + 1) == -1); | |
137 ASSERT (errno == EBADF); | |
138 ASSERT (!is_open (fd + 1)); | |
139 errno = 0; | |
140 ASSERT (dup2 (fd + 1, fd) == -1); | |
141 ASSERT (errno == EBADF); | |
142 ASSERT (is_open (fd)); | |
143 | |
144 /* The destination must be valid. */ | |
145 errno = 0; | |
146 ASSERT (dup2 (fd, -2) == -1); | |
147 ASSERT (errno == EBADF); | |
11885 | 148 errno = 0; |
149 ASSERT (dup2 (fd, 10000000) == -1); | |
150 ASSERT (errno == EBADF); | |
11727 | 151 |
152 /* Using dup2 can skip fds. */ | |
153 ASSERT (dup2 (fd, fd + 2) == fd + 2); | |
154 ASSERT (is_open (fd)); | |
155 ASSERT (!is_open (fd + 1)); | |
156 ASSERT (is_open (fd + 2)); | |
157 | |
11885 | 158 /* Verify that dup2 closes the previous occupant of a fd. */ |
11727 | 159 ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1); |
160 ASSERT (dup2 (fd + 1, fd) == fd); | |
161 ASSERT (close (fd + 1) == 0); | |
162 ASSERT (write (fd, "1", 1) == 1); | |
163 ASSERT (dup2 (fd + 2, fd) == fd); | |
11885 | 164 ASSERT (lseek (fd, 0, SEEK_END) == 0); |
11727 | 165 ASSERT (write (fd + 2, "2", 1) == 1); |
11885 | 166 ASSERT (lseek (fd, 0, SEEK_SET) == 0); |
11727 | 167 ASSERT (read (fd, buffer, 1) == 1); |
168 ASSERT (*buffer == '2'); | |
169 | |
13073
03de1efbfdd3
Resolve conflict between the two kinds of module indicators.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
170 #if GNULIB_TEST_CLOEXEC |
12391 | 171 /* Any new fd created by dup2 must not be cloexec. */ |
172 ASSERT (close (fd + 2) == 0); | |
173 ASSERT (dup_cloexec (fd) == fd + 1); | |
174 ASSERT (!is_inheritable (fd + 1)); | |
175 ASSERT (dup2 (fd + 1, fd + 1) == fd + 1); | |
176 ASSERT (!is_inheritable (fd + 1)); | |
177 ASSERT (dup2 (fd + 1, fd + 2) == fd + 2); | |
14255
dfb3316e7c70
dup2: work around Haiku bug
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
178 ASSERT (!is_inheritable (fd + 1)); |
12391 | 179 ASSERT (is_inheritable (fd + 2)); |
14255
dfb3316e7c70
dup2: work around Haiku bug
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
180 errno = 0; |
dfb3316e7c70
dup2: work around Haiku bug
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
181 ASSERT (dup2 (fd + 1, -1) == -1); |
dfb3316e7c70
dup2: work around Haiku bug
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
182 ASSERT (errno == EBADF); |
dfb3316e7c70
dup2: work around Haiku bug
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
183 ASSERT (!is_inheritable (fd + 1)); |
12512 | 184 #endif |
12391 | 185 |
12398
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
186 /* On systems that distinguish between text and binary mode, dup2 |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
187 reuses the mode of the source. */ |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
188 setmode (fd, O_BINARY); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
189 ASSERT (is_mode (fd, O_BINARY)); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
190 ASSERT (dup2 (fd, fd + 1) == fd + 1); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
191 ASSERT (is_mode (fd + 1, O_BINARY)); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
192 setmode (fd, O_TEXT); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
193 ASSERT (is_mode (fd, O_TEXT)); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
194 ASSERT (dup2 (fd, fd + 1) == fd + 1); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
195 ASSERT (is_mode (fd + 1, O_TEXT)); |
8700bea78e67
cloexec: preserve text vs. binary across dup_cloexec
Eric Blake <ebb9@byu.net>
parents:
12391
diff
changeset
|
196 |
11727 | 197 /* Clean up. */ |
198 ASSERT (close (fd + 2) == 0); | |
12391 | 199 ASSERT (close (fd + 1) == 0); |
11727 | 200 ASSERT (close (fd) == 0); |
201 ASSERT (unlink (file) == 0); | |
202 | |
203 return 0; | |
204 } |