diff options
| author | Tom Tromey | 2013-07-12 18:44:13 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-07-12 18:44:13 -0600 |
| commit | b34a529f177a6ea32da5cb1254f91bf9d71838db (patch) | |
| tree | 477131abc15d3107b30b635223d87a22550b480b /lib | |
| parent | e6f63071a3f7721f55220514b6d9a8ee8c1232d8 (diff) | |
| parent | 5e301d7651c0691bb2bc7f3fbe711fdbe26ac471 (diff) | |
| download | emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.tar.gz emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.zip | |
Merge from trunk
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/binary-io.c | 3 | ||||
| -rw-r--r-- | lib/binary-io.h | 72 | ||||
| -rw-r--r-- | lib/fcntl.c | 311 | ||||
| -rw-r--r-- | lib/getdtablesize.c | 86 | ||||
| -rw-r--r-- | lib/gnulib.mk | 43 | ||||
| -rw-r--r-- | lib/ignore-value.h | 48 | ||||
| -rw-r--r-- | lib/pipe2.c | 168 | ||||
| -rw-r--r-- | lib/stdalign.in.h | 39 | ||||
| -rw-r--r-- | lib/verify.h | 112 |
9 files changed, 762 insertions, 120 deletions
diff --git a/lib/binary-io.c b/lib/binary-io.c new file mode 100644 index 00000000000..8bbdb44d121 --- /dev/null +++ b/lib/binary-io.c | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | #include <config.h> | ||
| 2 | #define BINARY_IO_INLINE _GL_EXTERN_INLINE | ||
| 3 | #include "binary-io.h" | ||
diff --git a/lib/binary-io.h b/lib/binary-io.h new file mode 100644 index 00000000000..317fe3d3c20 --- /dev/null +++ b/lib/binary-io.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* Binary mode I/O. | ||
| 2 | Copyright (C) 2001, 2003, 2005, 2008-2013 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 <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #ifndef _BINARY_H | ||
| 18 | #define _BINARY_H | ||
| 19 | |||
| 20 | /* For systems that distinguish between text and binary I/O. | ||
| 21 | O_BINARY is guaranteed by the gnulib <fcntl.h>. */ | ||
| 22 | #include <fcntl.h> | ||
| 23 | |||
| 24 | /* The MSVC7 <stdio.h> doesn't like to be included after '#define fileno ...', | ||
| 25 | so we include it here first. */ | ||
| 26 | #include <stdio.h> | ||
| 27 | |||
| 28 | _GL_INLINE_HEADER_BEGIN | ||
| 29 | #ifndef BINARY_IO_INLINE | ||
| 30 | # define BINARY_IO_INLINE _GL_INLINE | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /* set_binary_mode (fd, mode) | ||
| 34 | sets the binary/text I/O mode of file descriptor fd to the given mode | ||
| 35 | (must be O_BINARY or O_TEXT) and returns the previous mode. */ | ||
| 36 | #if O_BINARY | ||
| 37 | # if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__ | ||
| 38 | # include <io.h> /* declares setmode() */ | ||
| 39 | # define set_binary_mode setmode | ||
| 40 | # else | ||
| 41 | # define set_binary_mode _setmode | ||
| 42 | # undef fileno | ||
| 43 | # define fileno _fileno | ||
| 44 | # endif | ||
| 45 | #else | ||
| 46 | /* On reasonable systems, binary I/O is the only choice. */ | ||
| 47 | /* Use a function rather than a macro, to avoid gcc warnings | ||
| 48 | "warning: statement with no effect". */ | ||
| 49 | BINARY_IO_INLINE int | ||
| 50 | set_binary_mode (int fd, int mode) | ||
| 51 | { | ||
| 52 | (void) fd; | ||
| 53 | (void) mode; | ||
| 54 | return O_BINARY; | ||
| 55 | } | ||
| 56 | #endif | ||
| 57 | |||
| 58 | /* SET_BINARY (fd); | ||
| 59 | changes the file descriptor fd to perform binary I/O. */ | ||
| 60 | #ifdef __DJGPP__ | ||
| 61 | # include <unistd.h> /* declares isatty() */ | ||
| 62 | /* Avoid putting stdin/stdout in binary mode if it is connected to | ||
| 63 | the console, because that would make it impossible for the user | ||
| 64 | to interrupt the program through Ctrl-C or Ctrl-Break. */ | ||
| 65 | # define SET_BINARY(fd) ((void) (!isatty (fd) ? (set_binary_mode (fd, O_BINARY), 0) : 0)) | ||
| 66 | #else | ||
| 67 | # define SET_BINARY(fd) ((void) set_binary_mode (fd, O_BINARY)) | ||
| 68 | #endif | ||
| 69 | |||
| 70 | _GL_INLINE_HEADER_END | ||
| 71 | |||
| 72 | #endif /* _BINARY_H */ | ||
diff --git a/lib/fcntl.c b/lib/fcntl.c new file mode 100644 index 00000000000..735fa66f4d7 --- /dev/null +++ b/lib/fcntl.c | |||
| @@ -0,0 +1,311 @@ | |||
| 1 | /* Provide file descriptor control. | ||
| 2 | |||
| 3 | Copyright (C) 2009-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Eric Blake <ebb9@byu.net>. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | /* Specification. */ | ||
| 23 | #include <fcntl.h> | ||
| 24 | |||
| 25 | #include <errno.h> | ||
| 26 | #include <limits.h> | ||
| 27 | #include <stdarg.h> | ||
| 28 | #include <unistd.h> | ||
| 29 | |||
| 30 | #if !HAVE_FCNTL | ||
| 31 | # define rpl_fcntl fcntl | ||
| 32 | #endif | ||
| 33 | #undef fcntl | ||
| 34 | |||
| 35 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 36 | /* Get declarations of the native Windows API functions. */ | ||
| 37 | # define WIN32_LEAN_AND_MEAN | ||
| 38 | # include <windows.h> | ||
| 39 | |||
| 40 | /* Get _get_osfhandle. */ | ||
| 41 | # include "msvc-nothrow.h" | ||
| 42 | |||
| 43 | /* Upper bound on getdtablesize(). See lib/getdtablesize.c. */ | ||
| 44 | # define OPEN_MAX_MAX 0x10000 | ||
| 45 | |||
| 46 | /* Duplicate OLDFD into the first available slot of at least NEWFD, | ||
| 47 | which must be positive, with FLAGS determining whether the duplicate | ||
| 48 | will be inheritable. */ | ||
| 49 | static int | ||
| 50 | dupfd (int oldfd, int newfd, int flags) | ||
| 51 | { | ||
| 52 | /* Mingw has no way to create an arbitrary fd. Iterate until all | ||
| 53 | file descriptors less than newfd are filled up. */ | ||
| 54 | HANDLE curr_process = GetCurrentProcess (); | ||
| 55 | HANDLE old_handle = (HANDLE) _get_osfhandle (oldfd); | ||
| 56 | unsigned char fds_to_close[OPEN_MAX_MAX / CHAR_BIT]; | ||
| 57 | unsigned int fds_to_close_bound = 0; | ||
| 58 | int result; | ||
| 59 | BOOL inherit = flags & O_CLOEXEC ? FALSE : TRUE; | ||
| 60 | int mode; | ||
| 61 | |||
| 62 | if (newfd < 0 || getdtablesize () <= newfd) | ||
| 63 | { | ||
| 64 | errno = EINVAL; | ||
| 65 | return -1; | ||
| 66 | } | ||
| 67 | if (old_handle == INVALID_HANDLE_VALUE | ||
| 68 | || (mode = setmode (oldfd, O_BINARY)) == -1) | ||
| 69 | { | ||
| 70 | /* oldfd is not open, or is an unassigned standard file | ||
| 71 | descriptor. */ | ||
| 72 | errno = EBADF; | ||
| 73 | return -1; | ||
| 74 | } | ||
| 75 | setmode (oldfd, mode); | ||
| 76 | flags |= mode; | ||
| 77 | |||
| 78 | for (;;) | ||
| 79 | { | ||
| 80 | HANDLE new_handle; | ||
| 81 | int duplicated_fd; | ||
| 82 | unsigned int index; | ||
| 83 | |||
| 84 | if (!DuplicateHandle (curr_process, /* SourceProcessHandle */ | ||
| 85 | old_handle, /* SourceHandle */ | ||
| 86 | curr_process, /* TargetProcessHandle */ | ||
| 87 | (PHANDLE) &new_handle, /* TargetHandle */ | ||
| 88 | (DWORD) 0, /* DesiredAccess */ | ||
| 89 | inherit, /* InheritHandle */ | ||
| 90 | DUPLICATE_SAME_ACCESS)) /* Options */ | ||
| 91 | { | ||
| 92 | /* TODO: Translate GetLastError () into errno. */ | ||
| 93 | errno = EMFILE; | ||
| 94 | result = -1; | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | duplicated_fd = _open_osfhandle ((intptr_t) new_handle, flags); | ||
| 98 | if (duplicated_fd < 0) | ||
| 99 | { | ||
| 100 | CloseHandle (new_handle); | ||
| 101 | errno = EMFILE; | ||
| 102 | result = -1; | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | if (newfd <= duplicated_fd) | ||
| 106 | { | ||
| 107 | result = duplicated_fd; | ||
| 108 | break; | ||
| 109 | } | ||
| 110 | |||
| 111 | /* Set the bit duplicated_fd in fds_to_close[]. */ | ||
| 112 | index = (unsigned int) duplicated_fd / CHAR_BIT; | ||
| 113 | if (fds_to_close_bound <= index) | ||
| 114 | { | ||
| 115 | if (sizeof fds_to_close <= index) | ||
| 116 | /* Need to increase OPEN_MAX_MAX. */ | ||
| 117 | abort (); | ||
| 118 | memset (fds_to_close + fds_to_close_bound, '\0', | ||
| 119 | index + 1 - fds_to_close_bound); | ||
| 120 | fds_to_close_bound = index + 1; | ||
| 121 | } | ||
| 122 | fds_to_close[index] |= 1 << ((unsigned int) duplicated_fd % CHAR_BIT); | ||
| 123 | } | ||
| 124 | |||
| 125 | /* Close the previous fds that turned out to be too small. */ | ||
| 126 | { | ||
| 127 | int saved_errno = errno; | ||
| 128 | unsigned int duplicated_fd; | ||
| 129 | |||
| 130 | for (duplicated_fd = 0; | ||
| 131 | duplicated_fd < fds_to_close_bound * CHAR_BIT; | ||
| 132 | duplicated_fd++) | ||
| 133 | if ((fds_to_close[duplicated_fd / CHAR_BIT] | ||
| 134 | >> (duplicated_fd % CHAR_BIT)) | ||
| 135 | & 1) | ||
| 136 | close (duplicated_fd); | ||
| 137 | |||
| 138 | errno = saved_errno; | ||
| 139 | } | ||
| 140 | |||
| 141 | # if REPLACE_FCHDIR | ||
| 142 | if (0 <= result) | ||
| 143 | result = _gl_register_dup (oldfd, result); | ||
| 144 | # endif | ||
| 145 | return result; | ||
| 146 | } | ||
| 147 | #endif /* W32 */ | ||
| 148 | |||
| 149 | /* Perform the specified ACTION on the file descriptor FD, possibly | ||
| 150 | using the argument ARG further described below. This replacement | ||
| 151 | handles the following actions, and forwards all others on to the | ||
| 152 | native fcntl. An unrecognized ACTION returns -1 with errno set to | ||
| 153 | EINVAL. | ||
| 154 | |||
| 155 | F_DUPFD - duplicate FD, with int ARG being the minimum target fd. | ||
| 156 | If successful, return the duplicate, which will be inheritable; | ||
| 157 | otherwise return -1 and set errno. | ||
| 158 | |||
| 159 | F_DUPFD_CLOEXEC - duplicate FD, with int ARG being the minimum | ||
| 160 | target fd. If successful, return the duplicate, which will not be | ||
| 161 | inheritable; otherwise return -1 and set errno. | ||
| 162 | |||
| 163 | F_GETFD - ARG need not be present. If successful, return a | ||
| 164 | non-negative value containing the descriptor flags of FD (only | ||
| 165 | FD_CLOEXEC is portable, but other flags may be present); otherwise | ||
| 166 | return -1 and set errno. */ | ||
| 167 | |||
| 168 | int | ||
| 169 | rpl_fcntl (int fd, int action, /* arg */...) | ||
| 170 | { | ||
| 171 | va_list arg; | ||
| 172 | int result = -1; | ||
| 173 | va_start (arg, action); | ||
| 174 | switch (action) | ||
| 175 | { | ||
| 176 | |||
| 177 | #if !HAVE_FCNTL | ||
| 178 | case F_DUPFD: | ||
| 179 | { | ||
| 180 | int target = va_arg (arg, int); | ||
| 181 | result = dupfd (fd, target, 0); | ||
| 182 | break; | ||
| 183 | } | ||
| 184 | #elif FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR | ||
| 185 | case F_DUPFD: | ||
| 186 | { | ||
| 187 | int target = va_arg (arg, int); | ||
| 188 | /* Detect invalid target; needed for cygwin 1.5.x. */ | ||
| 189 | if (target < 0 || getdtablesize () <= target) | ||
| 190 | errno = EINVAL; | ||
| 191 | else | ||
| 192 | { | ||
| 193 | /* Haiku alpha 2 loses fd flags on original. */ | ||
| 194 | int flags = fcntl (fd, F_GETFD); | ||
| 195 | if (flags < 0) | ||
| 196 | { | ||
| 197 | result = -1; | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | result = fcntl (fd, action, target); | ||
| 201 | if (0 <= result && fcntl (fd, F_SETFD, flags) == -1) | ||
| 202 | { | ||
| 203 | int saved_errno = errno; | ||
| 204 | close (result); | ||
| 205 | result = -1; | ||
| 206 | errno = saved_errno; | ||
| 207 | } | ||
| 208 | # if REPLACE_FCHDIR | ||
| 209 | if (0 <= result) | ||
| 210 | result = _gl_register_dup (fd, result); | ||
| 211 | # endif | ||
| 212 | } | ||
| 213 | break; | ||
| 214 | } /* F_DUPFD */ | ||
| 215 | #endif /* FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR */ | ||
| 216 | |||
| 217 | case F_DUPFD_CLOEXEC: | ||
| 218 | { | ||
| 219 | int target = va_arg (arg, int); | ||
| 220 | |||
| 221 | #if !HAVE_FCNTL | ||
| 222 | result = dupfd (fd, target, O_CLOEXEC); | ||
| 223 | break; | ||
| 224 | #else /* HAVE_FCNTL */ | ||
| 225 | /* Try the system call first, if the headers claim it exists | ||
| 226 | (that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we | ||
| 227 | may be running with a glibc that has the macro but with an | ||
| 228 | older kernel that does not support it. Cache the | ||
| 229 | information on whether the system call really works, but | ||
| 230 | avoid caching failure if the corresponding F_DUPFD fails | ||
| 231 | for any reason. 0 = unknown, 1 = yes, -1 = no. */ | ||
| 232 | static int have_dupfd_cloexec = GNULIB_defined_F_DUPFD_CLOEXEC ? -1 : 0; | ||
| 233 | if (0 <= have_dupfd_cloexec) | ||
| 234 | { | ||
| 235 | result = fcntl (fd, action, target); | ||
| 236 | if (0 <= result || errno != EINVAL) | ||
| 237 | { | ||
| 238 | have_dupfd_cloexec = 1; | ||
| 239 | # if REPLACE_FCHDIR | ||
| 240 | if (0 <= result) | ||
| 241 | result = _gl_register_dup (fd, result); | ||
| 242 | # endif | ||
| 243 | } | ||
| 244 | else | ||
| 245 | { | ||
| 246 | result = rpl_fcntl (fd, F_DUPFD, target); | ||
| 247 | if (result < 0) | ||
| 248 | break; | ||
| 249 | have_dupfd_cloexec = -1; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | else | ||
| 253 | result = rpl_fcntl (fd, F_DUPFD, target); | ||
| 254 | if (0 <= result && have_dupfd_cloexec == -1) | ||
| 255 | { | ||
| 256 | int flags = fcntl (result, F_GETFD); | ||
| 257 | if (flags < 0 || fcntl (result, F_SETFD, flags | FD_CLOEXEC) == -1) | ||
| 258 | { | ||
| 259 | int saved_errno = errno; | ||
| 260 | close (result); | ||
| 261 | errno = saved_errno; | ||
| 262 | result = -1; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | break; | ||
| 266 | #endif /* HAVE_FCNTL */ | ||
| 267 | } /* F_DUPFD_CLOEXEC */ | ||
| 268 | |||
| 269 | #if !HAVE_FCNTL | ||
| 270 | case F_GETFD: | ||
| 271 | { | ||
| 272 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 273 | HANDLE handle = (HANDLE) _get_osfhandle (fd); | ||
| 274 | DWORD flags; | ||
| 275 | if (handle == INVALID_HANDLE_VALUE | ||
| 276 | || GetHandleInformation (handle, &flags) == 0) | ||
| 277 | errno = EBADF; | ||
| 278 | else | ||
| 279 | result = (flags & HANDLE_FLAG_INHERIT) ? 0 : FD_CLOEXEC; | ||
| 280 | # else /* !W32 */ | ||
| 281 | /* Use dup2 to reject invalid file descriptors. No way to | ||
| 282 | access this information, so punt. */ | ||
| 283 | if (0 <= dup2 (fd, fd)) | ||
| 284 | result = 0; | ||
| 285 | # endif /* !W32 */ | ||
| 286 | break; | ||
| 287 | } /* F_GETFD */ | ||
| 288 | #endif /* !HAVE_FCNTL */ | ||
| 289 | |||
| 290 | /* Implementing F_SETFD on mingw is not trivial - there is no | ||
| 291 | API for changing the O_NOINHERIT bit on an fd, and merely | ||
| 292 | changing the HANDLE_FLAG_INHERIT bit on the underlying handle | ||
| 293 | can lead to odd state. It may be possible by duplicating the | ||
| 294 | handle, using _open_osfhandle with the right flags, then | ||
| 295 | using dup2 to move the duplicate onto the original, but that | ||
| 296 | is not supported for now. */ | ||
| 297 | |||
| 298 | default: | ||
| 299 | { | ||
| 300 | #if HAVE_FCNTL | ||
| 301 | void *p = va_arg (arg, void *); | ||
| 302 | result = fcntl (fd, action, p); | ||
| 303 | #else | ||
| 304 | errno = EINVAL; | ||
| 305 | #endif | ||
| 306 | break; | ||
| 307 | } | ||
| 308 | } | ||
| 309 | va_end (arg); | ||
| 310 | return result; | ||
| 311 | } | ||
diff --git a/lib/getdtablesize.c b/lib/getdtablesize.c new file mode 100644 index 00000000000..9947405af61 --- /dev/null +++ b/lib/getdtablesize.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* getdtablesize() function for platforms that don't have it. | ||
| 2 | Copyright (C) 2008-2013 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include <unistd.h> | ||
| 22 | |||
| 23 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 24 | |||
| 25 | #include <stdio.h> | ||
| 26 | |||
| 27 | #include "msvc-inval.h" | ||
| 28 | |||
| 29 | #if HAVE_MSVC_INVALID_PARAMETER_HANDLER | ||
| 30 | static int | ||
| 31 | _setmaxstdio_nothrow (int newmax) | ||
| 32 | { | ||
| 33 | int result; | ||
| 34 | |||
| 35 | TRY_MSVC_INVAL | ||
| 36 | { | ||
| 37 | result = _setmaxstdio (newmax); | ||
| 38 | } | ||
| 39 | CATCH_MSVC_INVAL | ||
| 40 | { | ||
| 41 | result = -1; | ||
| 42 | } | ||
| 43 | DONE_MSVC_INVAL; | ||
| 44 | |||
| 45 | return result; | ||
| 46 | } | ||
| 47 | # define _setmaxstdio _setmaxstdio_nothrow | ||
| 48 | #endif | ||
| 49 | |||
| 50 | /* Cache for the previous getdtablesize () result. */ | ||
| 51 | static int dtablesize; | ||
| 52 | |||
| 53 | int | ||
| 54 | getdtablesize (void) | ||
| 55 | { | ||
| 56 | if (dtablesize == 0) | ||
| 57 | { | ||
| 58 | /* We are looking for the number N such that the valid file descriptors | ||
| 59 | are 0..N-1. It can be obtained through a loop as follows: | ||
| 60 | { | ||
| 61 | int fd; | ||
| 62 | for (fd = 3; fd < 65536; fd++) | ||
| 63 | if (dup2 (0, fd) == -1) | ||
| 64 | break; | ||
| 65 | return fd; | ||
| 66 | } | ||
| 67 | On Windows XP, the result is 2048. | ||
| 68 | The drawback of this loop is that it allocates memory for a libc | ||
| 69 | internal array that is never freed. | ||
| 70 | |||
| 71 | The number N can also be obtained as the upper bound for | ||
| 72 | _getmaxstdio (). _getmaxstdio () returns the maximum number of open | ||
| 73 | FILE objects. The sanity check in _setmaxstdio reveals the maximum | ||
| 74 | number of file descriptors. This too allocates memory, but it is | ||
| 75 | freed when we call _setmaxstdio with the original value. */ | ||
| 76 | int orig_max_stdio = _getmaxstdio (); | ||
| 77 | unsigned int bound; | ||
| 78 | for (bound = 0x10000; _setmaxstdio (bound) < 0; bound = bound / 2) | ||
| 79 | ; | ||
| 80 | _setmaxstdio (orig_max_stdio); | ||
| 81 | dtablesize = bound; | ||
| 82 | } | ||
| 83 | return dtablesize; | ||
| 84 | } | ||
| 85 | |||
| 86 | #endif | ||
diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 4a84b1db261..d053e15efc1 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | # the same distribution terms as the rest of that program. | 21 | # the same distribution terms as the rest of that program. |
| 22 | # | 22 | # |
| 23 | # Generated by gnulib-tool. | 23 | # Generated by gnulib-tool. |
| 24 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=dup --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings memrchr mktime pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings | 24 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | MOSTLYCLEANFILES += core *.stackdump | 27 | MOSTLYCLEANFILES += core *.stackdump |
| @@ -75,6 +75,12 @@ EXTRA_libgnu_a_SOURCES += openat-proc.c | |||
| 75 | 75 | ||
| 76 | ## end gnulib module at-internal | 76 | ## end gnulib module at-internal |
| 77 | 77 | ||
| 78 | ## begin gnulib module binary-io | ||
| 79 | |||
| 80 | libgnu_a_SOURCES += binary-io.h binary-io.c | ||
| 81 | |||
| 82 | ## end gnulib module binary-io | ||
| 83 | |||
| 78 | ## begin gnulib module c-ctype | 84 | ## begin gnulib module c-ctype |
| 79 | 85 | ||
| 80 | libgnu_a_SOURCES += c-ctype.h c-ctype.c | 86 | libgnu_a_SOURCES += c-ctype.h c-ctype.c |
| @@ -296,6 +302,15 @@ EXTRA_libgnu_a_SOURCES += at-func.c faccessat.c | |||
| 296 | 302 | ||
| 297 | ## end gnulib module faccessat | 303 | ## end gnulib module faccessat |
| 298 | 304 | ||
| 305 | ## begin gnulib module fcntl | ||
| 306 | |||
| 307 | |||
| 308 | EXTRA_DIST += fcntl.c | ||
| 309 | |||
| 310 | EXTRA_libgnu_a_SOURCES += fcntl.c | ||
| 311 | |||
| 312 | ## end gnulib module fcntl | ||
| 313 | |||
| 299 | ## begin gnulib module fcntl-h | 314 | ## begin gnulib module fcntl-h |
| 300 | 315 | ||
| 301 | BUILT_SOURCES += fcntl.h | 316 | BUILT_SOURCES += fcntl.h |
| @@ -384,6 +399,17 @@ EXTRA_libgnu_a_SOURCES += fsync.c | |||
| 384 | 399 | ||
| 385 | ## end gnulib module fsync | 400 | ## end gnulib module fsync |
| 386 | 401 | ||
| 402 | ## begin gnulib module getdtablesize | ||
| 403 | |||
| 404 | if gl_GNULIB_ENABLED_getdtablesize | ||
| 405 | |||
| 406 | endif | ||
| 407 | EXTRA_DIST += getdtablesize.c | ||
| 408 | |||
| 409 | EXTRA_libgnu_a_SOURCES += getdtablesize.c | ||
| 410 | |||
| 411 | ## end gnulib module getdtablesize | ||
| 412 | |||
| 387 | ## begin gnulib module getgroups | 413 | ## begin gnulib module getgroups |
| 388 | 414 | ||
| 389 | if gl_GNULIB_ENABLED_getgroups | 415 | if gl_GNULIB_ENABLED_getgroups |
| @@ -465,13 +491,6 @@ EXTRA_libgnu_a_SOURCES += group-member.c | |||
| 465 | 491 | ||
| 466 | ## end gnulib module group-member | 492 | ## end gnulib module group-member |
| 467 | 493 | ||
| 468 | ## begin gnulib module ignore-value | ||
| 469 | |||
| 470 | |||
| 471 | EXTRA_DIST += ignore-value.h | ||
| 472 | |||
| 473 | ## end gnulib module ignore-value | ||
| 474 | |||
| 475 | ## begin gnulib module intprops | 494 | ## begin gnulib module intprops |
| 476 | 495 | ||
| 477 | 496 | ||
| @@ -568,6 +587,12 @@ EXTRA_DIST += pathmax.h | |||
| 568 | 587 | ||
| 569 | ## end gnulib module pathmax | 588 | ## end gnulib module pathmax |
| 570 | 589 | ||
| 590 | ## begin gnulib module pipe2 | ||
| 591 | |||
| 592 | libgnu_a_SOURCES += pipe2.c | ||
| 593 | |||
| 594 | ## end gnulib module pipe2 | ||
| 595 | |||
| 571 | ## begin gnulib module pselect | 596 | ## begin gnulib module pselect |
| 572 | 597 | ||
| 573 | 598 | ||
| @@ -1704,9 +1729,7 @@ EXTRA_DIST += utimens.h | |||
| 1704 | 1729 | ||
| 1705 | ## begin gnulib module verify | 1730 | ## begin gnulib module verify |
| 1706 | 1731 | ||
| 1707 | if gl_GNULIB_ENABLED_verify | ||
| 1708 | 1732 | ||
| 1709 | endif | ||
| 1710 | EXTRA_DIST += verify.h | 1733 | EXTRA_DIST += verify.h |
| 1711 | 1734 | ||
| 1712 | ## end gnulib module verify | 1735 | ## end gnulib module verify |
diff --git a/lib/ignore-value.h b/lib/ignore-value.h deleted file mode 100644 index ebd6bf42f56..00000000000 --- a/lib/ignore-value.h +++ /dev/null | |||
| @@ -1,48 +0,0 @@ | |||
| 1 | /* ignore a function return without a compiler warning | ||
| 2 | |||
| 3 | Copyright (C) 2008-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Jim Meyering, Eric Blake and Pádraig Brady. */ | ||
| 19 | |||
| 20 | /* Use "ignore_value" to avoid a warning when using a function declared with | ||
| 21 | gcc's warn_unused_result attribute, but for which you really do want to | ||
| 22 | ignore the result. Traditionally, people have used a "(void)" cast to | ||
| 23 | indicate that a function's return value is deliberately unused. However, | ||
| 24 | if the function is declared with __attribute__((warn_unused_result)), | ||
| 25 | gcc issues a warning even with the cast. | ||
| 26 | |||
| 27 | Caution: most of the time, you really should heed gcc's warning, and | ||
| 28 | check the return value. However, in those exceptional cases in which | ||
| 29 | you're sure you know what you're doing, use this function. | ||
| 30 | |||
| 31 | For the record, here's one of the ignorable warnings: | ||
| 32 | "copy.c:233: warning: ignoring return value of 'fchown', | ||
| 33 | declared with attribute warn_unused_result". */ | ||
| 34 | |||
| 35 | #ifndef _GL_IGNORE_VALUE_H | ||
| 36 | #define _GL_IGNORE_VALUE_H | ||
| 37 | |||
| 38 | /* The __attribute__((__warn_unused_result__)) feature | ||
| 39 | is available in gcc versions 3.4 and newer, | ||
| 40 | while the typeof feature has been available since 2.7 at least. */ | ||
| 41 | #if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) | ||
| 42 | # define ignore_value(x) \ | ||
| 43 | (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; })) | ||
| 44 | #else | ||
| 45 | # define ignore_value(x) ((void) (x)) | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #endif | ||
diff --git a/lib/pipe2.c b/lib/pipe2.c new file mode 100644 index 00000000000..211d75545c0 --- /dev/null +++ b/lib/pipe2.c | |||
| @@ -0,0 +1,168 @@ | |||
| 1 | /* Create a pipe, with specific opening flags. | ||
| 2 | Copyright (C) 2009-2013 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 along | ||
| 15 | with this program; if not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Specification. */ | ||
| 20 | #include <unistd.h> | ||
| 21 | |||
| 22 | #include <errno.h> | ||
| 23 | #include <fcntl.h> | ||
| 24 | |||
| 25 | #include "binary-io.h" | ||
| 26 | #include "verify.h" | ||
| 27 | |||
| 28 | #if GNULIB_defined_O_NONBLOCK | ||
| 29 | # include "nonblocking.h" | ||
| 30 | #endif | ||
| 31 | |||
| 32 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 33 | /* Native Windows API. */ | ||
| 34 | |||
| 35 | # include <io.h> | ||
| 36 | |||
| 37 | #endif | ||
| 38 | |||
| 39 | int | ||
| 40 | pipe2 (int fd[2], int flags) | ||
| 41 | { | ||
| 42 | /* Mingw _pipe() corrupts fd on failure; also, if we succeed at | ||
| 43 | creating the pipe but later fail at changing fcntl, we want | ||
| 44 | to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ | ||
| 45 | int tmp[2]; | ||
| 46 | tmp[0] = fd[0]; | ||
| 47 | tmp[1] = fd[1]; | ||
| 48 | |||
| 49 | #if HAVE_PIPE2 | ||
| 50 | # undef pipe2 | ||
| 51 | /* Try the system call first, if it exists. (We may be running with a glibc | ||
| 52 | that has the function but with an older kernel that lacks it.) */ | ||
| 53 | { | ||
| 54 | /* Cache the information whether the system call really exists. */ | ||
| 55 | static int have_pipe2_really; /* 0 = unknown, 1 = yes, -1 = no */ | ||
| 56 | if (have_pipe2_really >= 0) | ||
| 57 | { | ||
| 58 | int result = pipe2 (fd, flags); | ||
| 59 | if (!(result < 0 && errno == ENOSYS)) | ||
| 60 | { | ||
| 61 | have_pipe2_really = 1; | ||
| 62 | return result; | ||
| 63 | } | ||
| 64 | have_pipe2_really = -1; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | #endif | ||
| 68 | |||
| 69 | /* Check the supported flags. */ | ||
| 70 | if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0) | ||
| 71 | { | ||
| 72 | errno = EINVAL; | ||
| 73 | return -1; | ||
| 74 | } | ||
| 75 | |||
| 76 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 77 | /* Native Windows API. */ | ||
| 78 | |||
| 79 | if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0) | ||
| 80 | { | ||
| 81 | fd[0] = tmp[0]; | ||
| 82 | fd[1] = tmp[1]; | ||
| 83 | return -1; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* O_NONBLOCK handling. | ||
| 87 | On native Windows platforms, O_NONBLOCK is defined by gnulib. Use the | ||
| 88 | functions defined by the gnulib module 'nonblocking'. */ | ||
| 89 | # if GNULIB_defined_O_NONBLOCK | ||
| 90 | if (flags & O_NONBLOCK) | ||
| 91 | { | ||
| 92 | if (set_nonblocking_flag (fd[0], true) != 0 | ||
| 93 | || set_nonblocking_flag (fd[1], true) != 0) | ||
| 94 | goto fail; | ||
| 95 | } | ||
| 96 | # else | ||
| 97 | { | ||
| 98 | verify (O_NONBLOCK == 0); | ||
| 99 | } | ||
| 100 | # endif | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | |||
| 104 | #else | ||
| 105 | /* Unix API. */ | ||
| 106 | |||
| 107 | if (pipe (fd) < 0) | ||
| 108 | return -1; | ||
| 109 | |||
| 110 | /* POSIX <http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html> | ||
| 111 | says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on | ||
| 112 | both fd[0] and fd[1]. */ | ||
| 113 | |||
| 114 | /* O_NONBLOCK handling. | ||
| 115 | On Unix platforms, O_NONBLOCK is defined by the system. Use fcntl(). */ | ||
| 116 | if (flags & O_NONBLOCK) | ||
| 117 | { | ||
| 118 | int fcntl_flags; | ||
| 119 | |||
| 120 | if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0 | ||
| 121 | || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1 | ||
| 122 | || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0 | ||
| 123 | || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1) | ||
| 124 | goto fail; | ||
| 125 | } | ||
| 126 | |||
| 127 | if (flags & O_CLOEXEC) | ||
| 128 | { | ||
| 129 | int fcntl_flags; | ||
| 130 | |||
| 131 | if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0 | ||
| 132 | || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1 | ||
| 133 | || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0 | ||
| 134 | || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) | ||
| 135 | goto fail; | ||
| 136 | } | ||
| 137 | |||
| 138 | # if O_BINARY | ||
| 139 | if (flags & O_BINARY) | ||
| 140 | { | ||
| 141 | set_binary_mode (fd[1], O_BINARY); | ||
| 142 | set_binary_mode (fd[0], O_BINARY); | ||
| 143 | } | ||
| 144 | else if (flags & O_TEXT) | ||
| 145 | { | ||
| 146 | set_binary_mode (fd[1], O_TEXT); | ||
| 147 | set_binary_mode (fd[0], O_TEXT); | ||
| 148 | } | ||
| 149 | # endif | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | |||
| 153 | #endif | ||
| 154 | |||
| 155 | #if GNULIB_defined_O_NONBLOCK || \ | ||
| 156 | !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) | ||
| 157 | fail: | ||
| 158 | { | ||
| 159 | int saved_errno = errno; | ||
| 160 | close (fd[0]); | ||
| 161 | close (fd[1]); | ||
| 162 | fd[0] = tmp[0]; | ||
| 163 | fd[1] = tmp[1]; | ||
| 164 | errno = saved_errno; | ||
| 165 | return -1; | ||
| 166 | } | ||
| 167 | #endif | ||
| 168 | } | ||
diff --git a/lib/stdalign.in.h b/lib/stdalign.in.h index c3a67321b0e..7254a3dec17 100644 --- a/lib/stdalign.in.h +++ b/lib/stdalign.in.h | |||
| @@ -41,13 +41,28 @@ | |||
| 41 | are 4 unless the option '-malign-double' is used. | 41 | are 4 unless the option '-malign-double' is used. |
| 42 | 42 | ||
| 43 | The result cannot be used as a value for an 'enum' constant, if you | 43 | The result cannot be used as a value for an 'enum' constant, if you |
| 44 | want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */ | 44 | want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. |
| 45 | |||
| 46 | Include <stddef.h> for offsetof. */ | ||
| 45 | #include <stddef.h> | 47 | #include <stddef.h> |
| 46 | #if defined __cplusplus | 48 | |
| 49 | /* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other | ||
| 50 | standard headers, defines conflicting implementations of _Alignas | ||
| 51 | and _Alignof that are no better than ours; override them. */ | ||
| 52 | #undef _Alignas | ||
| 53 | #undef _Alignof | ||
| 54 | |||
| 55 | #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 | ||
| 56 | # ifdef __cplusplus | ||
| 57 | # if 201103 <= __cplusplus | ||
| 58 | # define _Alignof(type) alignof (type) | ||
| 59 | # else | ||
| 47 | template <class __t> struct __alignof_helper { char __a; __t __b; }; | 60 | template <class __t> struct __alignof_helper { char __a; __t __b; }; |
| 48 | # define _Alignof(type) offsetof (__alignof_helper<type>, __b) | 61 | # define _Alignof(type) offsetof (__alignof_helper<type>, __b) |
| 49 | #else | 62 | # endif |
| 50 | # define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) | 63 | # else |
| 64 | # define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) | ||
| 65 | # endif | ||
| 51 | #endif | 66 | #endif |
| 52 | #define alignof _Alignof | 67 | #define alignof _Alignof |
| 53 | #define __alignof_is_defined 1 | 68 | #define __alignof_is_defined 1 |
| @@ -77,12 +92,16 @@ | |||
| 77 | 92 | ||
| 78 | */ | 93 | */ |
| 79 | 94 | ||
| 80 | #if __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C | 95 | #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 |
| 81 | # define _Alignas(a) __attribute__ ((__aligned__ (a))) | 96 | # if defined __cplusplus && 201103 <= __cplusplus |
| 82 | #elif 1300 <= _MSC_VER | 97 | # define _Alignas(a) alignas (a) |
| 83 | # define _Alignas(a) __declspec (align (a)) | 98 | # elif __GNUC__ || __IBMC__ || __IBMCPP__ || __ICC || 0x5110 <= __SUNPRO_C |
| 99 | # define _Alignas(a) __attribute__ ((__aligned__ (a))) | ||
| 100 | # elif 1300 <= _MSC_VER | ||
| 101 | # define _Alignas(a) __declspec (align (a)) | ||
| 102 | # endif | ||
| 84 | #endif | 103 | #endif |
| 85 | #ifdef _Alignas | 104 | #if defined _Alignas || (defined __STDC_VERSION && 201112 <= __STDC_VERSION__) |
| 86 | # define alignas _Alignas | 105 | # define alignas _Alignas |
| 87 | # define __alignas_is_defined 1 | 106 | # define __alignas_is_defined 1 |
| 88 | #endif | 107 | #endif |
diff --git a/lib/verify.h b/lib/verify.h index 03492efcd3f..d42d0750ee1 100644 --- a/lib/verify.h +++ b/lib/verify.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ | 18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ |
| 19 | 19 | ||
| 20 | #ifndef _GL_VERIFY_H | 20 | #ifndef _GL_VERIFY_H |
| 21 | # define _GL_VERIFY_H | 21 | #define _GL_VERIFY_H |
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. | 24 | /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. |
| @@ -31,16 +31,24 @@ | |||
| 31 | Use this only with GCC. If we were willing to slow 'configure' | 31 | Use this only with GCC. If we were willing to slow 'configure' |
| 32 | down we could also use it with other compilers, but since this | 32 | down we could also use it with other compilers, but since this |
| 33 | affects only the quality of diagnostics, why bother? */ | 33 | affects only the quality of diagnostics, why bother? */ |
| 34 | # if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \ | 34 | #if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \ |
| 35 | && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \ | 35 | && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \ |
| 36 | && !defined __cplusplus) | 36 | && !defined __cplusplus) |
| 37 | # define _GL_HAVE__STATIC_ASSERT 1 | 37 | # define _GL_HAVE__STATIC_ASSERT 1 |
| 38 | # endif | 38 | #endif |
| 39 | /* The condition (99 < __GNUC__) is temporary, until we know about the | 39 | /* The condition (99 < __GNUC__) is temporary, until we know about the |
| 40 | first G++ release that supports static_assert. */ | 40 | first G++ release that supports static_assert. */ |
| 41 | # if (99 < __GNUC__) && defined __cplusplus | 41 | #if (99 < __GNUC__) && defined __cplusplus |
| 42 | # define _GL_HAVE_STATIC_ASSERT 1 | 42 | # define _GL_HAVE_STATIC_ASSERT 1 |
| 43 | # endif | 43 | #endif |
| 44 | |||
| 45 | /* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other | ||
| 46 | system headers, defines a conflicting _Static_assert that is no | ||
| 47 | better than ours; override it. */ | ||
| 48 | #ifndef _GL_HAVE_STATIC_ASSERT | ||
| 49 | # include <stddef.h> | ||
| 50 | # undef _Static_assert | ||
| 51 | #endif | ||
| 44 | 52 | ||
| 45 | /* Each of these macros verifies that its argument R is nonzero. To | 53 | /* Each of these macros verifies that its argument R is nonzero. To |
| 46 | be portable, R should be an integer constant expression. Unlike | 54 | be portable, R should be an integer constant expression. Unlike |
| @@ -143,50 +151,50 @@ | |||
| 143 | Use a template type to work around the problem. */ | 151 | Use a template type to work around the problem. */ |
| 144 | 152 | ||
| 145 | /* Concatenate two preprocessor tokens. */ | 153 | /* Concatenate two preprocessor tokens. */ |
| 146 | # define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) | 154 | #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) |
| 147 | # define _GL_CONCAT0(x, y) x##y | 155 | #define _GL_CONCAT0(x, y) x##y |
| 148 | 156 | ||
| 149 | /* _GL_COUNTER is an integer, preferably one that changes each time we | 157 | /* _GL_COUNTER is an integer, preferably one that changes each time we |
| 150 | use it. Use __COUNTER__ if it works, falling back on __LINE__ | 158 | use it. Use __COUNTER__ if it works, falling back on __LINE__ |
| 151 | otherwise. __LINE__ isn't perfect, but it's better than a | 159 | otherwise. __LINE__ isn't perfect, but it's better than a |
| 152 | constant. */ | 160 | constant. */ |
| 153 | # if defined __COUNTER__ && __COUNTER__ != __COUNTER__ | 161 | #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ |
| 154 | # define _GL_COUNTER __COUNTER__ | 162 | # define _GL_COUNTER __COUNTER__ |
| 155 | # else | 163 | #else |
| 156 | # define _GL_COUNTER __LINE__ | 164 | # define _GL_COUNTER __LINE__ |
| 157 | # endif | 165 | #endif |
| 158 | 166 | ||
| 159 | /* Generate a symbol with the given prefix, making it unique if | 167 | /* Generate a symbol with the given prefix, making it unique if |
| 160 | possible. */ | 168 | possible. */ |
| 161 | # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) | 169 | #define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) |
| 162 | 170 | ||
| 163 | /* Verify requirement R at compile-time, as an integer constant expression | 171 | /* Verify requirement R at compile-time, as an integer constant expression |
| 164 | that returns 1. If R is false, fail at compile-time, preferably | 172 | that returns 1. If R is false, fail at compile-time, preferably |
| 165 | with a diagnostic that includes the string-literal DIAGNOSTIC. */ | 173 | with a diagnostic that includes the string-literal DIAGNOSTIC. */ |
| 166 | 174 | ||
| 167 | # define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ | 175 | #define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ |
| 168 | (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) | 176 | (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) |
| 169 | 177 | ||
| 170 | # ifdef __cplusplus | 178 | #ifdef __cplusplus |
| 171 | # if !GNULIB_defined_struct__gl_verify_type | 179 | # if !GNULIB_defined_struct__gl_verify_type |
| 172 | template <int w> | 180 | template <int w> |
| 173 | struct _gl_verify_type { | 181 | struct _gl_verify_type { |
| 174 | unsigned int _gl_verify_error_if_negative: w; | 182 | unsigned int _gl_verify_error_if_negative: w; |
| 175 | }; | 183 | }; |
| 176 | # define GNULIB_defined_struct__gl_verify_type 1 | 184 | # define GNULIB_defined_struct__gl_verify_type 1 |
| 177 | # endif | ||
| 178 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | ||
| 179 | _gl_verify_type<(R) ? 1 : -1> | ||
| 180 | # elif defined _GL_HAVE__STATIC_ASSERT | ||
| 181 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | ||
| 182 | struct { \ | ||
| 183 | _Static_assert (R, DIAGNOSTIC); \ | ||
| 184 | int _gl_dummy; \ | ||
| 185 | } | ||
| 186 | # else | ||
| 187 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | ||
| 188 | struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } | ||
| 189 | # endif | 185 | # endif |
| 186 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | ||
| 187 | _gl_verify_type<(R) ? 1 : -1> | ||
| 188 | #elif defined _GL_HAVE__STATIC_ASSERT | ||
| 189 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | ||
| 190 | struct { \ | ||
| 191 | _Static_assert (R, DIAGNOSTIC); \ | ||
| 192 | int _gl_dummy; \ | ||
| 193 | } | ||
| 194 | #else | ||
| 195 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | ||
| 196 | struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } | ||
| 197 | #endif | ||
| 190 | 198 | ||
| 191 | /* Verify requirement R at compile-time, as a declaration without a | 199 | /* Verify requirement R at compile-time, as a declaration without a |
| 192 | trailing ';'. If R is false, fail at compile-time, preferably | 200 | trailing ';'. If R is false, fail at compile-time, preferably |
| @@ -195,23 +203,23 @@ template <int w> | |||
| 195 | Unfortunately, unlike C11, this implementation must appear as an | 203 | Unfortunately, unlike C11, this implementation must appear as an |
| 196 | ordinary declaration, and cannot appear inside struct { ... }. */ | 204 | ordinary declaration, and cannot appear inside struct { ... }. */ |
| 197 | 205 | ||
| 198 | # ifdef _GL_HAVE__STATIC_ASSERT | 206 | #ifdef _GL_HAVE__STATIC_ASSERT |
| 199 | # define _GL_VERIFY _Static_assert | 207 | # define _GL_VERIFY _Static_assert |
| 200 | # else | 208 | #else |
| 201 | # define _GL_VERIFY(R, DIAGNOSTIC) \ | 209 | # define _GL_VERIFY(R, DIAGNOSTIC) \ |
| 202 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ | 210 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ |
| 203 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] | 211 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] |
| 204 | # endif | 212 | #endif |
| 205 | 213 | ||
| 206 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ | 214 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
| 207 | # ifdef _GL_STATIC_ASSERT_H | 215 | #ifdef _GL_STATIC_ASSERT_H |
| 208 | # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert | 216 | # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert |
| 209 | # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) | 217 | # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) |
| 210 | # endif | 218 | # endif |
| 211 | # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert | 219 | # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert |
| 212 | # define static_assert _Static_assert /* C11 requires this #define. */ | 220 | # define static_assert _Static_assert /* C11 requires this #define. */ |
| 213 | # endif | ||
| 214 | # endif | 221 | # endif |
| 222 | #endif | ||
| 215 | 223 | ||
| 216 | /* @assert.h omit start@ */ | 224 | /* @assert.h omit start@ */ |
| 217 | 225 | ||
| @@ -229,18 +237,18 @@ template <int w> | |||
| 229 | 237 | ||
| 230 | verify_true is obsolescent; please use verify_expr instead. */ | 238 | verify_true is obsolescent; please use verify_expr instead. */ |
| 231 | 239 | ||
| 232 | # define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") | 240 | #define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") |
| 233 | 241 | ||
| 234 | /* Verify requirement R at compile-time. Return the value of the | 242 | /* Verify requirement R at compile-time. Return the value of the |
| 235 | expression E. */ | 243 | expression E. */ |
| 236 | 244 | ||
| 237 | # define verify_expr(R, E) \ | 245 | #define verify_expr(R, E) \ |
| 238 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) | 246 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) |
| 239 | 247 | ||
| 240 | /* Verify requirement R at compile-time, as a declaration without a | 248 | /* Verify requirement R at compile-time, as a declaration without a |
| 241 | trailing ';'. */ | 249 | trailing ';'. */ |
| 242 | 250 | ||
| 243 | # define verify(R) _GL_VERIFY (R, "verify (" #R ")") | 251 | #define verify(R) _GL_VERIFY (R, "verify (" #R ")") |
| 244 | 252 | ||
| 245 | /* @assert.h omit end@ */ | 253 | /* @assert.h omit end@ */ |
| 246 | 254 | ||