Mercurial > hg > octave-jordi > gnulib-hg
annotate tests/test-dup3.c @ 17682:68b0a0f80871
pthread_sigmask, timer-time: use gl_THREADLIB only if needed
Without this fix, Emacs would sometimes call sigprocmask instead
of pthread_sigmask, which is a no-no in multithreaded applications.
Problem reported by Jorgen Schaefer in <http://bugs.gnu.org/17561>.
* m4/pthread_sigmask.m4 (gl_FUNC_PTHREAD_SIGMASK):
Suppress check for pthread_sigmask working without -lpthread if
the application always links with -lpthread. Do not link with
$LIBMULTITHREAD if gl_THREADLIB is not defined.
* m4/timer_time.m4 (gl_TIMER_TIME):
Require gl_THREADLIB only if it is defined. Do not append
$LIBMULTITHREAD to LIB_TIMER_TIME if gl_THREADLIB is not defined.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Wed, 28 May 2014 21:04:04 -0700 |
parents | 344018b6e5d7 |
children | ab58d4870664 |
rev | line source |
---|---|
11887 | 1 /* Test duplicating file descriptors. |
17587 | 2 Copyright (C) 2009-2014 Free Software Foundation, Inc. |
11887 | 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 and Bruno Haible <bruno@clisp.org>, 2009. */ | |
19 | |
20 #include <config.h> | |
21 | |
22 #include <unistd.h> | |
23 | |
12489 | 24 #include "signature.h" |
25 SIGNATURE_CHECK (dup3, int, (int, int, int)); | |
26 | |
11887 | 27 #include <errno.h> |
28 #include <fcntl.h> | |
29 #include <stdbool.h> | |
30 | |
31 #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
|
32 /* Get declarations of the native Windows API functions. */ |
11887 | 33 # define WIN32_LEAN_AND_MEAN |
34 # include <windows.h> | |
15752
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
35 /* Get _get_osfhandle. */ |
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
36 # include "msvc-nothrow.h" |
11887 | 37 #endif |
38 | |
39 #include "binary-io.h" | |
12496
a48d3d749ca5
Refactor common macros used in tests.
Bruno Haible <bruno@clisp.org>
parents:
12489
diff
changeset
|
40 #include "macros.h" |
11887 | 41 |
42 /* Return true if FD is open. */ | |
43 static bool | |
44 is_open (int fd) | |
45 { | |
46 #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
|
47 /* On native Windows, the initial state of unassigned standard file |
11887 | 48 descriptors is that they are open but point to an |
49 INVALID_HANDLE_VALUE, and there is no fcntl. */ | |
50 return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE; | |
51 #else | |
52 # ifndef F_GETFL | |
53 # error Please port fcntl to your platform | |
54 # endif | |
55 return 0 <= fcntl (fd, F_GETFL); | |
56 #endif | |
57 } | |
58 | |
59 /* Return true if FD is not inherited to child processes. */ | |
60 static bool | |
61 is_cloexec (int fd) | |
62 { | |
63 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | |
64 HANDLE h = (HANDLE) _get_osfhandle (fd); | |
65 DWORD flags; | |
66 ASSERT (GetHandleInformation (h, &flags)); | |
67 return (flags & HANDLE_FLAG_INHERIT) == 0; | |
68 #else | |
69 int flags; | |
70 ASSERT ((flags = fcntl (fd, F_GETFD)) >= 0); | |
71 return (flags & FD_CLOEXEC) != 0; | |
72 #endif | |
73 } | |
74 | |
75 int | |
76 main () | |
77 { | |
78 int use_cloexec; | |
17384
160b88fd4691
tests: don't assume getdtablesize () <= 10000000
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
79 int bad_fd = getdtablesize (); |
11887 | 80 |
13664
241057e2e60f
fcntl-h: define O_CLOEXEC and O_EXEC if not defined; use new defines
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
81 #if O_CLOEXEC |
11887 | 82 for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++) |
83 #else | |
84 use_cloexec = 0; | |
85 #endif | |
86 { | |
87 const char *file = "test-dup3.tmp"; | |
88 int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600); | |
89 int o_flags; | |
90 char buffer[1]; | |
91 | |
92 o_flags = 0; | |
13664
241057e2e60f
fcntl-h: define O_CLOEXEC and O_EXEC if not defined; use new defines
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
93 #if O_CLOEXEC |
11887 | 94 if (use_cloexec) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11887
diff
changeset
|
95 o_flags |= O_CLOEXEC; |
11887 | 96 #endif |
97 | |
98 /* Assume std descriptors were provided by invoker. */ | |
99 ASSERT (STDERR_FILENO < fd); | |
100 ASSERT (is_open (fd)); | |
101 /* Ignore any other fd's leaked into this process. */ | |
102 close (fd + 1); | |
103 close (fd + 2); | |
104 ASSERT (!is_open (fd + 1)); | |
105 ASSERT (!is_open (fd + 2)); | |
106 | |
107 /* Assigning to self is invalid. */ | |
108 errno = 0; | |
109 ASSERT (dup3 (fd, fd, o_flags) == -1); | |
110 ASSERT (errno == EINVAL); | |
111 ASSERT (is_open (fd)); | |
112 | |
113 /* If the source is not open, then the destination is unaffected. */ | |
114 errno = 0; | |
115 ASSERT (dup3 (fd + 1, fd + 2, o_flags) == -1); | |
116 ASSERT (errno == EBADF); | |
117 ASSERT (!is_open (fd + 2)); | |
118 errno = 0; | |
119 ASSERT (dup3 (fd + 1, fd, o_flags) == -1); | |
120 ASSERT (errno == EBADF); | |
121 ASSERT (is_open (fd)); | |
122 | |
123 /* The destination must be valid. */ | |
124 errno = 0; | |
125 ASSERT (dup3 (fd, -2, o_flags) == -1); | |
126 ASSERT (errno == EBADF); | |
17509
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
127 if (bad_fd > 256) |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
128 { |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
129 ASSERT (dup3 (fd, 255, 0) == 255); |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
130 ASSERT (dup3 (fd, 256, 0) == 256); |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
131 ASSERT (close (255) == 0); |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
132 ASSERT (close (256) == 0); |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
133 } |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
134 ASSERT (dup3 (fd, bad_fd - 1, 0) == bad_fd - 1); |
7fadcfb1189f
dup2, dup3: work around another cygwin crasher
Eric Blake <eblake@redhat.com>
parents:
17384
diff
changeset
|
135 ASSERT (close (bad_fd - 1) == 0); |
11887 | 136 errno = 0; |
17384
160b88fd4691
tests: don't assume getdtablesize () <= 10000000
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
137 ASSERT (dup3 (fd, bad_fd, o_flags) == -1); |
11887 | 138 ASSERT (errno == EBADF); |
139 | |
140 /* Using dup3 can skip fds. */ | |
141 ASSERT (dup3 (fd, fd + 2, o_flags) == fd + 2); | |
142 ASSERT (is_open (fd)); | |
143 ASSERT (!is_open (fd + 1)); | |
144 ASSERT (is_open (fd + 2)); | |
145 if (use_cloexec) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11887
diff
changeset
|
146 ASSERT (is_cloexec (fd + 2)); |
11887 | 147 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11887
diff
changeset
|
148 ASSERT (!is_cloexec (fd + 2)); |
11887 | 149 |
150 /* Verify that dup3 closes the previous occupant of a fd. */ | |
151 ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1); | |
152 ASSERT (dup3 (fd + 1, fd, o_flags) == fd); | |
153 ASSERT (close (fd + 1) == 0); | |
154 ASSERT (write (fd, "1", 1) == 1); | |
155 ASSERT (dup3 (fd + 2, fd, o_flags) == fd); | |
156 ASSERT (lseek (fd, 0, SEEK_END) == 0); | |
157 ASSERT (write (fd + 2, "2", 1) == 1); | |
158 ASSERT (lseek (fd, 0, SEEK_SET) == 0); | |
159 ASSERT (read (fd, buffer, 1) == 1); | |
160 ASSERT (*buffer == '2'); | |
161 | |
162 /* Clean up. */ | |
163 ASSERT (close (fd + 2) == 0); | |
164 ASSERT (close (fd) == 0); | |
165 ASSERT (unlink (file) == 0); | |
166 } | |
167 | |
168 return 0; | |
169 } |