[BZ #1978]
[glibc.git] / posix / annexc.c
blobdf5913aedde0cb60629aaeadcdee71dbdbb7504e
1 /* Copyright (C) 1998, 2000, 2002, 2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library 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 GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
19 #include <ctype.h>
20 #include <fnmatch.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <sys/wait.h>
28 #define HEADER_MAX 256
30 static const char *macrofile;
32 /* <aio.h>. */
33 static const char *const aio_syms[] =
35 "AIO_ALLDONE", "AIO_CANCELED", "AIO_NOTCANCELED", "LIO_NOP", "LIO_NOWAIT",
36 "LIO_READ", "LIO_WAIT", "LIO_WRITE",
37 /* From <fcntl.h>. */
38 "FD_CLOEXEC", "F_DUPFD", "F_GETFD", "F_GETFL", "F_GETLK", "F_RDLCK",
39 "F_SETFD", "F_SETFL", "F_SETLK", "F_SETLKW", "F_UNLCK", "F_WRLCK",
40 "O_ACCMODE", "O_APPEND", "O_CREAT", "O_DSYNC", "O_EXCL", "O_NOCTTY",
41 "O_NONBLOCK", "O_RDONLY", "O_RDWR", "O_RSYNC", "O_SYNC", "O_TRUNC",
42 "O_WRONLY",
43 /* From <signal.h>. */
44 "SA_NOCLDSTOP", "SA_SIGINFO", "SIGABRT", "SIGALRM", "SIGBUS", "SIGCHLD",
45 "SIGCONT", "SIGEV_NONE", "SIGEV_SIGNAL", "SIGEV_SIGNAL", "SIGEV_THREAD",
46 "SIGFPE", "SIGHUP", "SIGILL", "SIGINT", "SIGKILL", "SIGPIPE", "SIGQUIT",
47 "SIGRTMAX", "SIGRTMIN", "SIGSEGV", "SIGSTOP", "SIGTERM", "SIGTSTP",
48 "SIGTTIN", "SIGTTOU", "SIGUSR1", "SIGUSR2", "SIG_BLOCK", "SIG_DFL",
49 "SIG_ERR", "SIG_IGN", "SIG_SETMASK", "SIG_UNBLOCK", "SI_ASYNCIO",
50 "SI_MESGQ", "SI_QUEUE", "SI_TIMER", "SI_USER"
52 static const char *const aio_maybe[] =
54 "aio_cancel", "aio_error", "aio_fsync", "aio_read", "aio_return",
55 "aio_suspend", "aio_write", "lio_listio",
56 /* From <fcntl.h>. */
57 "creat", "fcntl", "open", "SEEK_CUR", "SEEK_END", "SEEK_SET", "S_IRGRP",
58 "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU", "S_ISBLK",
59 "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG", "S_ISUID",
60 "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH", "S_IXUSR",
61 /* From <signal.h>. */
62 "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset",
63 "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask",
64 "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo"
67 /* <assert.h>. */
68 static const char *const assert_syms[] =
70 "assert"
72 static const char *const assert_maybe[] =
76 /* <ctype.h>. */
77 static const char *const ctype_syms[] =
80 static const char *const ctype_maybe[] =
82 "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower",
83 "isprint", "ispunct", "isspace", "isupper", "isxdigit", "tolower",
84 "toupper"
87 /* <dirent.h>. */
88 static const char *const dirent_syms[] =
91 static const char *const dirent_maybe[] =
93 "closedir", "opendir", "readdir", "readdir_r", "rewinddir"
96 /* <errno.h>. */
97 static const char *const errno_syms[] =
99 "E2BIG", "EACCES", "EAGAIN", "EBADF", "EBADMSG", "EBUSY", "ECANCELED",
100 "ECHILD", "EDEADLK", "EDOM", "EEXIST", "EFAULT", "EFBIG", "EINPROGRESS",
101 "EINTR", "EINVAL", "EIO", "EISDIR", "EMFILE", "EMLINK", "EMSGSIZE",
102 "ENAMETOOLONG", "ENFILE", "ENODEV", "ENOENT", "ENOEXEC", "ENOLCK",
103 "ENOMEM", "ENOSPC", "ENOSYS", "ENOTDIR", "ENOTEMPTY", "ENOTSUP",
104 "ENOTTY", "ENXIO", "EPERM", "EPIPE", "ERANGE", "EROFS", "ESPIPE",
105 "ESRCH", "ETIMEDOUT", "EXDEV"
107 static const char *const errno_maybe[] =
109 "errno", "E*"
112 /* <fcntl.h>. */
113 static const char *const fcntl_syms[] =
115 "FD_CLOEXEC", "F_DUPFD", "F_GETFD", "F_GETFL", "F_GETLK", "F_RDLCK",
116 "F_SETFD", "F_SETFL", "F_SETLK", "F_SETLKW", "F_UNLCK", "F_WRLCK",
117 "O_ACCMODE", "O_APPEND", "O_CREAT", "O_DSYNC", "O_EXCL", "O_NOCTTY",
118 "O_NONBLOCK", "O_RDONLY", "O_RDWR", "O_RSYNC", "O_SYNC", "O_TRUNC",
119 "O_WRONLY"
121 static const char *const fcntl_maybe[] =
123 "creat", "fcntl", "open", "SEEK_CUR", "SEEK_END", "SEEK_SET", "S_IRGRP",
124 "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU", "S_ISBLK",
125 "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG", "S_ISUID",
126 "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH", "S_IXUSR"
129 /* <float.h>. */
130 static const char *const float_syms[] =
132 "DBL_DIG", "DBL_EPSILON", "DBL_MANT_DIG", "DBL_MAX", "DBL_MAX_10_EXP",
133 "DBL_MAX_EXP", "DBL_MIN", "DBL_MIN_10_EXP", "DBL_MIN_EXP", "FLT_DIG",
134 "FLT_EPSILON", "FLT_MANT_DIG", "FLT_MAX", "FLT_MAX_10_EXP", "FLT_MAX_EXP",
135 "FLT_MIN", "FLT_MIN_10_EXP", "FLT_MIN_EXP", "FLT_RADIX", "FLT_ROUNDS",
136 "LDBL_DIG", "LDBL_EPSILON", "LDBL_MANT_DIG", "LDBL_MAX", "LDBL_MAX_10_EXP",
137 "LDBL_MAX_EXP", "LDBL_MIN", "LDBL_MIN_10_EXP", "LDBL_MIN_EXP"
139 static const char *const float_maybe[] =
143 /* <grp.h>. */
144 static const char *const grp_syms[] =
147 static const char *const grp_maybe[] =
149 "getgrgid", "getgrgid_r", "getgrnam", "getgrnam_r"
152 /* <limits.h>. */
153 static const char *const limits_syms[] =
155 "_POSIX_AIO_LISTIO_MAX", "_POSIX_AIO_MAX", "_POSIX_ARG_MAX",
156 "_POSIX_CHILD_MAX", "_POSIX_CLOCKRES_MAX", "_POSIX_DELAYTIMER_MAX",
157 "_POSIX_LINK_MAX", "_POSIX_LOGIN_NAME_MAX", "_POSIX_MAX_CANON",
158 "_POSIX_MAX_INPUT", "_POSIX_MQ_OPEN_MAX", "_POSIX_MQ_PRIO_MAX",
159 "_POSIX_NAME_MAX", "_POSIX_NGROUPS_MAX", "_POSIX_OPEN_MAX",
160 "_POSIX_PATH_MAX", "_POSIX_PIPE_BUF", "_POSIX_RTSIG_MAX",
161 "_POSIX_SEM_NSEMS_MAX", "_POSIX_SEM_VALUE_MAX", "_POSIX_SIGQUEUE_MAX",
162 "_POSIX_SSIZE_MAX", "_POSIX_STREAM_MAX",
163 "_POSIX_THREAD_DESTRUCTOR_ITERATIONS", "_POSIX_THREAD_KEYS_MAX",
164 "_POSIX_THREAD_THREADS_MAX", "_POSIX_TIMER_MAX", "_POSIX_TTY_NAME_MAX",
165 "_POSIX_TZNAME_MAX", "_POSIX_THREAD_DESTRUCTOR_ITERATIONS",
166 "CHAR_BIT", "CHAR_MAX", "CHAR_MIN", "INT_MAX", "INT_MIN", "LONG_MAX",
167 "LONG_MIN", "MB_LEN_MAX", "NGROUPS_MAX", "PAGESIZE", "SCHAR_MAX",
168 "SCHAR_MIN", "SHRT_MAX", "SHRT_MIN", "UCHAR_MAX", "UINT_MAX",
169 "ULONG_MAX", "USHRT_MAX"
171 static const char *const limits_maybe[] =
173 "AIO_LISTIO_MAX", "AIO_MAX", "ARG_MAX", "CHILD_MAX", "DELAYTIMER_MAX",
174 "LINK_MAX", "LOGIN_NAME_MAX", "LONG_MAX", "LONG_MIN", "MAX_CANON",
175 "MAX_INPUT", "MQ_OPEN_MAX", "MQ_PRIO_MAX", "NAME_MAX", "OPEN_MAX",
176 "PATH_MAX", "PIPE_BUF", "RTSIG_MAX", "PTHREAD_DESTRUCTOR_ITERATIONS",
177 "PTHREAD_KEYS_MAX", "PTHREAD_STACK_MIN", "PTHREAD_THREADS_MAX"
180 /* <locale.h>. */
181 static const char *const locale_syms[] =
183 "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC",
184 "LC_TIME", "NULL"
186 static const char *const locale_maybe[] =
188 "LC_*", "localeconv", "setlocale"
191 /* <math.h>. */
192 static const char *const math_syms[] =
194 "HUGE_VAL"
196 static const char *const math_maybe[] =
198 "acos", "asin", "atan2", "atan", "ceil", "cos", "cosh", "exp",
199 "fabs", "floor", "fmod", "frexp", "ldexp", "log10", "log", "modf",
200 "pow", "sin", "sinh", "sqrt", "tan", "tanh",
201 "acosf", "asinf", "atan2f", "atanf", "ceilf", "cosf", "coshf", "expf",
202 "fabsf", "floorf", "fmodf", "frexpf", "ldexpf", "log10f", "logf", "modff",
203 "powf", "sinf", "sinhf", "sqrtf", "tanf", "tanhf",
204 "acosl", "asinl", "atan2l", "atanl", "ceill", "cosl", "coshl", "expl",
205 "fabsl", "floorl", "fmodl", "frexpl", "ldexpl", "log10l", "logl", "modfl",
206 "powl", "sinl", "sinhl", "sqrtl", "tanl", "tanhl"
209 /* <mqueue.h>. */
210 static const char *const mqueue_syms[] =
213 static const char *const mqueue_maybe[] =
215 "mq_close", "mq_getattr", "mq_notify", "mq_open", "mq_receive",
216 "mq_send", "mq_setattr", "mq_unlink"
219 /* <pthread.h>. */
220 static const char *const pthread_syms[] =
222 "PTHREAD_CANCELED", "PTHREAD_CANCEL_ASYNCHRONOUS",
223 "PTHREAD_CANCEL_DEFERRED", "PTHREAD_CANCEL_DISABLE", "PTHREAD_CANCEL_ENABLE",
224 "PTHREAD_COND_INITIALIZER", "PTHREAD_CREATE_DETACHED",
225 "PTHREAD_CREATE_JOINABLE", "PTHREAD_EXPLICIT_SCHED",
226 "PTHREAD_INHERIT_SCHED", "PTHREAD_MUTEX_INITIALIZER",
227 "PTHREAD_ONCE_INIT", "PTHREAD_PRIO_INHERIT", "PTHREAD_PRIO_NONE",
228 "PTHREAD_PRIO_PROTECT", "PTHREAD_PROCESS_PRIVATE",
229 "PTHREAD_PROCESS_SHARED", "PTHREAD_SCOPE_PROCESS", "PTHREAD_SCOPE_SYSTEM",
230 /* These come from <sched.h>. */
231 "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
232 /* These come from <time.h>. */
233 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
235 static const char *const pthread_maybe[] =
237 "pthread_atfork", "pthread_attr_destroy", "pthread_attr_getdetachstate",
238 "pthread_attr_getinheritsched", "pthread_attr_getschedparam",
239 "pthread_attr_getschedpolicy", "pthread_attr_getscope",
240 "pthread_attr_getstackaddr", "pthread_attr_getstacksize",
241 "pthread_attr_init", "pthread_attr_setdetachstate",
242 "pthread_attr_setinheritsched", "pthread_attr_setschedparam",
243 "pthread_attr_setschedpolicy", "pthread_attr_setscope",
244 "pthread_attr_setstackaddr", "pthread_attr_setstacksize",
245 "pthread_cleanup_pop", "pthread_cleanup_push", "pthread_cond_broadcast",
246 "pthread_cond_destroy", "pthread_cond_init", "pthread_cond_signal",
247 "pthread_cond_timedwait", "pthread_cond_wait", "pthread_condattr_destroy",
248 "pthread_condattr_getpshared", "pthread_condattr_init",
249 "pthread_condattr_setpshared", "pthread_create", "pthread_detach",
250 "pthread_equal", "pthread_exit", "pthread_getspecific", "pthread_join",
251 "pthread_key_create", "pthread_key_destroy", "pthread_kill",
252 "pthread_mutex_destroy", "pthread_mutex_getprioceiling",
253 "pthread_mutex_init", "pthread_mutex_lock", "pthread_mutex_setprioceiling",
254 "pthread_mutex_trylock", "pthread_mutex_unlock", "pthread_mutexattr_destroy",
255 "pthread_mutexattr_getprioceiling", "pthread_mutexattr_getprotocol",
256 "pthread_mutexattr_getpshared", "pthread_mutexattr_init",
257 "pthread_mutexattr_setprioceiling", "pthread_mutexattr_setprotocol",
258 "pthread_mutexattr_setpshared", "pthread_once", "pthread_self",
259 "pthread_setcancelstate", "pthread_setcanceltype", "pthread_setspecific",
260 "pthread_sigmask", "pthread_testcancel"
261 /* These come from <sched.h>. */
262 "sched_get_priority_max", "sched_get_priority_min",
263 "sched_get_rr_interval", "sched_getparam", "sched_getscheduler",
264 "sched_setparam", "sched_setscheduler", "sched_yield",
265 /* These come from <time.h>. */
266 "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
267 "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
268 "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
269 "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
270 "timer_settime", "tzset"
273 /* <pwd.h>. */
274 static const char *const pwd_syms[] =
277 static const char *const pwd_maybe[] =
279 "getpwnam", "getpwnam_r", "getpwuid", "getpwuid_r"
282 /* <sched.h>. */
283 static const char *const sched_syms[] =
285 "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
287 static const char *const sched_maybe[] =
289 "sched_get_priority_max", "sched_get_priority_min",
290 "sched_get_rr_interval", "sched_getparam", "sched_getscheduler",
291 "sched_setparam", "sched_setscheduler", "sched_yield",
292 /* These come from <time.h>. */
293 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
294 "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
295 "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
296 "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
297 "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
298 "timer_settime", "tzset"
301 /* <semaphore.h>. */
302 static const char *const semaphore_syms[] =
305 static const char *const semaphore_maybe[] =
307 "sem_close", "sem_destroy", "sem_getvalue", "sem_init", "sem_open",
308 "sen_post", "sem_trywait", "sem_unlink", "sem_wait"
311 /* <setjmp.h>. */
312 static const char *const setjmp_syms[] =
315 static const char *const setjmp_maybe[] =
317 "longjmp", "setjmp", "siglongjmp", "sigsetjmp"
320 /* <signal.h>. */
321 static const char *const signal_syms[] =
323 "SA_NOCLDSTOP", "SA_SIGINFO", "SIGABRT", "SIGALRM", "SIGBUS", "SIGCHLD",
324 "SIGCONT", "SIGEV_NONE", "SIGEV_SIGNAL", "SIGEV_THREAD",
325 "SIGFPE", "SIGHUP", "SIGILL", "SIGINT", "SIGKILL", "SIGPIPE", "SIGQUIT",
326 "SIGRTMAX", "SIGRTMIN", "SIGSEGV", "SIGSTOP", "SIGTERM", "SIGTSTP",
327 "SIGTTIN", "SIGTTOU", "SIGUSR1", "SIGUSR2", "SIG_BLOCK", "SIG_DFL",
328 "SIG_ERR", "SIG_IGN", "SIG_SETMASK", "SIG_UNBLOCK", "SI_ASYNCIO",
329 "SI_MESGQ", "SI_QUEUE", "SI_TIMER", "SI_USER"
331 static const char *const signal_maybe[] =
333 "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset",
334 "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask",
335 "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo"
338 /* <stdarg.h>. */
339 static const char *const stdarg_syms[] =
341 "va_arg", "va_end", "va_start"
343 static const char *const stdarg_maybe[] =
345 "va_list"
348 /* <stddef.h>. */
349 static const char *const stddef_syms[] =
351 "NULL", "offsetof"
353 static const char *const stddef_maybe[] =
357 /* <stdio.h>. */
358 static const char *const stdio_syms[] =
360 "BUFSIZ", "EOF", "FILENAME_MAX", "FOPEN_MAX", "L_ctermid", "L_cuserid",
361 "L_tmpnam", "NULL", "SEEK_CUR", "SEEK_END", "SEEK_SET", "STREAM_MAX",
362 "TMP_MAX", "stderr", "stdin", "stdout", "_IOFBF", "_IOLBF", "_IONBF"
364 static const char *const stdio_maybe[] =
366 "clearerr", "fclose", "fdopen", "feof", "ferror", "fflush", "fgetc",
367 "fgetpos", "fgets", "fileno", "flockfile", "fopen", "fprintf", "fputc",
368 "fputs", "fread", "freopen", "fscanf", "fseek", "fsetpos", "ftell",
369 "ftrylockfile", "funlockfile", "fwrite", "getc", "getchar",
370 "getchar_unlocked", "getc_unlocked", "gets", "perror", "printf", "putc",
371 "putchar", "putchar_unlocked", "putc_unlocked", "puts", "remove", "rename",
372 "rewind", "scanf", "setbuf", "setvbuf", "sprintf", "sscanf", "tmpfile",
373 "tmpnam", "ungetc", "vfprintf", "vprintf", "vsprintf"
376 /* <stdlib.h>. */
377 static const char *const stdlib_syms[] =
379 "EXIT_FAILURE", "EXIT_SUCCESS", "MB_CUR_MAX", "NULL", "RAND_MAX"
381 static const char *const stdlib_maybe[] =
383 "abort", "abs", "atexit", "atof", "atoi", "atol", "bsearch", "calloc",
384 "div", "exit", "free", "getenv", "labs", "ldiv", "malloc", "mblen",
385 "mbstowcs", "mbtowc", "qsort", "rand", "rand_r", "realloc", "srand",
386 "strtod", "strtol", "strtoul", "system", "wcstombs", "wctomb"
389 /* <string.h>. */
390 static const char *const string_syms[] =
392 "NULL"
394 static const char *const string_maybe[] =
396 "memchr", "memcmp", "memcpy", "memmove", "memset", "strcat", "strchr",
397 "strcmp", "strcoll", "strcpy", "strcspn", "strerror", "strlen",
398 "strncat", "strncmp", "strncpy", "strpbrk", "strrchr", "strspn",
399 "strstr", "strtok", "strtok_r", "strxfrm"
402 /* <sys/mman.h>. */
403 static const char *const mman_syms[] =
405 "MAP_FAILED", "MAP_FIXED", "MAP_PRIVATE", "MAP_SHARED", "MCL_CURRENT",
406 "MCL_FUTURE", "MS_ASYNC", "MS_INVALIDATE", "MS_SYNC", "PROT_EXEC",
407 "PROT_NONE", "PROT_READ", "PROT_WRITE"
409 static const char *const mman_maybe[] =
411 "mlock", "mlockall", "mmap", "mprotect", "msync", "munlock", "munlockall",
412 "munmap", "shm_open", "shm_unlock"
415 /* <sys/stat.h>. */
416 static const char *const stat_syms[] =
418 "S_IRGRP", "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU",
419 "S_ISBLK", "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG",
420 "S_ISUID", "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH",
421 "S_IXUSR", "S_TYPEISMQ", "S_TYPEISSEM", "S_TYPEISSHM"
423 static const char *const stat_maybe[] =
425 "chmod", "fchmod", "fstat", "mkdir", "mkfifo", "stat", "umask"
428 /* <sys/times.h>. */
429 static const char *const times_syms[] =
432 static const char *const times_maybe[] =
434 "times"
437 /* <sys/types.h>. */
438 static const char *const types_syms[] =
441 static const char *const types_maybe[] =
445 /* <sys/utsname.h>. */
446 static const char *const utsname_syms[] =
449 static const char *const utsname_maybe[] =
451 "uname"
454 /* <sys/wait.h>. */
455 static const char *const wait_syms[] =
457 "WEXITSTATUS", "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG",
458 "WSTOPSIG", "WTERMSIG", "WUNTRACED"
460 static const char *const wait_maybe[] =
462 "wait", "waitpid"
465 /* <termios.h>. */
466 static const char *const termios_syms[] =
468 "B0", "B110", "B1200", "B134", "B150", "B1800", "B19200", "B200", "B2400",
469 "B300", "B38400", "B4800", "B50", "B600", "B75", "B9600", "BRKINT", "CLOCAL",
470 "CREAD", "CS5", "CS6", "CS7", "CS8", "CSIZE", "CSTOPN", "ECHO", "ECHOE",
471 "ECHOK", "ECHONL", "HUPCL", "ICANON", "ICRNL", "IEXTEN", "IGNBRK", "IGNCR",
472 "IGNPAR", "INCLR", "INPCK", "ISIG", "ISTRIP", "IXOFF", "IXON", "NCCS",
473 "NOFLSH", "OPOST", "PARENB", "PARMRK", "PARODD", "TCIFLUSH", "TCIOFF",
474 "TCIOFLUSH", "TCOFLUSH", "TCOOFF", "TCOON", "TCSADRAIN", "TCSAFLUSH",
475 "TCSANOW", "TOSTOP", "VEOF", "VEOL", "VERASE", "VINTR", "VKILL", "VMIN",
476 "VQUIT", "VSTART", "VSTOP", "VSUSP", "VTIME"
478 static const char *const termios_maybe[] =
480 "cfgetispeed", "cfgetospeed", "cfsetispeed", "cfsetospeed", "tcdrain",
481 "tcflow", "tcflush", "tcgetattr", "tcsendbrk", "tcsetattr"
484 /* <time.h>. */
485 static const char *const time_syms[] =
487 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
489 static const char *const time_maybe[] =
491 "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
492 "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
493 "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
494 "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
495 "timer_settime", "tzset"
498 /* <unistd.h>. */
499 static const char *const unistd_syms[] =
501 "F_OK", "NULL", "R_OK", "SEEK_CUR", "SEEK_END", "SEEK_SET", "STDERR_FILENO",
502 "STDIN_FILENO", "STDOUT_FILENO", "W_OK", "X_OK",
503 "_PC_ASYNC_IO", "_PC_CHOWN_RESTRICTED", "_PC_LINK_MAX", "_PC_MAX_CANON",
504 "_PC_MAX_INPUT", "_PC_NAME_MAX", "_PC_NO_TRUNC", "_PC_PATH_MAX",
505 "_PC_PIPE_BUF", "_PC_PRIO_IO", "_PC_SYNC_IO", "_PC_VDISABLE",
506 "_SC_AIO_LISTIO_MAX", "_SC_AIO_MAX", "_SC_AIO_PRIO_DELTA_MAX",
507 "_SC_ARG_MAX", "_SC_ASYNCHRONOUS_IO", "_SC_CHILD_MAX", "_SC_CLK_TCK",
508 "_SC_DELAYTIMER_MAX", "_SC_FSYNC", "_SC_GETGR_R_SIZE_MAX",
509 "_SC_GETPW_R_SIZE_MAX", "_SC_JOB_CONTROL", "_SC_LOGIN_NAME_MAX",
510 "_SC_MAPPED_FILES", "_SC_MEMLOCK", "_SC_MEMLOCK_RANGE",
511 "_SC_MEMORY_PROTECTION", "_SC_MESSAGE_PASSING", "_SC_MQ_OPEN_MAX",
512 "_SC_MQ_PRIO_MAX", "_SC_NGROUPS_MAX", "_SC_OPEN_MAX", "_SC_PAGESIZE",
513 "_SC_PRIORITIZED_IO", "_SC_PRIORITY_SCHEDULING", "_SC_REALTIME_SIGNALS",
514 "_SC_RTSIG_MAX", "_SC_SAVED_IDS", "_SC_SEMAPHORES", "_SC_SEM_NSEMS_MAX",
515 "_SC_SEM_VALUE_MAX", "_SC_SHARED_MEMORY_OBJECTS", "_SC_SIGQUEUE_MAX",
516 "_SC_STREAM_MAX", "_SC_SYNCHRONIZED_IO", "_SC_THREADS",
517 "_SC_THREAD_ATTR_STACKADDR", "_SC_THREAD_ATTR_STACKSIZE",
518 "_SC_THREAD_DESTRUCTOR_ITERATIONS", "_SC_THREAD_PRIO_INHERIT",
519 "_SC_THREAD_PRIORITY_SCHEDULING", "_SC_THREAD_PRIO_PROTECT",
520 "_SC_THREAD_PROCESS_SHARED", "_SC_THREAD_SAFE_FUNCTIONS",
521 "_SC_THREAD_STACK_MIN", "_SC_THREAD_THREADS_MAX", "_SC_TIMERS",
522 "_SC_TIMER_MAX", "_SC_TTY_NAME_MAX", "_SC_TZNAME_MAX", "_SC_VERSION"
524 static const char *const unistd_maybe[] =
526 "_POSIX_ASYNCHRONOUS_IO", "_POSIX_ASYNC_IO", "_POSIX_CHOWN_RESTRICTED",
527 "_POSIX_FSYNC", "_POSIX_JOB_CONTROL", "_POSIX_MAPPED_FILES",
528 "_POSIX_MEMLOCK", "_POSIX_MEMLOCK_RANGE", "_MEMORY_PROTECTION",
529 "_POSIX_MESSAGE_PASSING", "_POSIX_NO_TRUNC", "_POSIX_PRIORITIZED_IO",
530 "_POSIX_PRIORITY_SCHEDULING", "_POSIX_PRIO_IO", "_POSIX_REATIME_SIGNALS",
531 "_POSIX_SAVED_IDS", "_POSIX_SEMAPHORES", "_POSIX_SHARED_MEMORY_OBJECTS",
532 "_POSIX_SYNCHRONIZED_IO", "_POSIX_SYNC_IO", "_POSIX_THREADS",
533 "_POSIX_THREAD_ATTR_STACKADDR", "_POSIX_THREAD_ATTR_STACKSIZE",
534 "_POSIX_THREAD_PRIO_INHERIT", "_POSIX_THREAD_PRIO_PROTECT",
535 "_POSIX_THREAD_PROCESS_SHARED", "_POSIX_THREAD_SAFE_FUNCTIONS",
536 "_POSIX_THREAD_PRIORITY_SCHEDULING", "_POSIX_TIMERS",
537 "_POSIX_VDISABLE", "_POSIX_VERSION",
538 "_exit", "access", "alarm", "chdir", "chown", "close", "ctermid", "cuserid",
539 "dup2", "dup", "execl", "execle", "execlp", "execv", "execve", "execvp",
540 "fdatasync", "fork", "fpathconf", "fsync", "ftruncate", "getcwd", "getegid",
541 "geteuid", "getgid", "getgroups", "getlogin", "getlogin_r", "getpgrp",
542 "getpid", "getppid", "getuid", "isatty", "link", "lseek", "pathconf",
543 "pause", "pipe", "read", "rmdir", "setgid", "setgpid", "setsid", "setuid",
544 "sleep", "sleep", "sysconf", "tcgetpgrp", "tcsetpgrp", "ttyname",
545 "ttyname_r", "unlink", "write"
548 /* <utime.h>. */
549 static const char *const utime_syms[] =
552 static const char *const utime_maybe[] =
554 "utime"
558 static struct header
560 const char *name;
561 const char *const *syms;
562 size_t nsyms;
563 const char *const *maybe;
564 size_t nmaybe;
565 const char *subset;
566 } headers[] =
568 #define H(n) \
569 { #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
570 n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), NULL }
571 #define Hc(n, s) \
572 { #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
573 n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), s }
574 #define Hs(n) \
575 { "sys/" #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
576 n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), NULL }
577 H(aio),
578 H(assert),
579 H(ctype),
580 H(dirent),
581 H(errno),
582 H(fcntl),
583 H(float),
584 H(grp),
585 H(limits),
586 H(locale),
587 H(math),
588 Hc(mqueue, "_POSIX_MESSAGE_PASSING"),
589 H(pthread),
590 H(pwd),
591 H(sched),
592 H(semaphore),
593 H(setjmp),
594 H(signal),
595 H(stdarg),
596 H(stddef),
597 H(stdio),
598 H(stdlib),
599 H(string),
600 Hs(mman),
601 Hs(stat),
602 Hs(times),
603 Hs(types),
604 Hs(utsname),
605 Hs(wait),
606 H(termios),
607 H(time),
608 H(unistd),
609 H(utime)
612 #define NUMBER_OF_HEADERS (sizeof headers / sizeof *headers)
615 /* Format string to build command to invoke compiler. */
616 static const char fmt[] = "\
617 echo \"#include <%s>\" |\
618 %s -E -dM -D_POSIX_SOURCE %s \
619 -isystem `%s --print-prog-name=include` - > %s";
621 static const char testfmt[] = "\
622 echo \"#include <unistd.h>\n#if !defined %s || %s == -1\n#error not defined\n#endif\n\" |\
623 %s -E -dM -D_POSIX_SOURCE %s \
624 -isystem `%s --print-prog-name=include` - 2> /dev/null > %s";
627 /* The compiler we use (given on the command line). */
628 const char *CC;
629 /* The -I parameters for CC to find all headers. */
630 const char *INC;
632 static char *xstrndup (const char *, size_t);
633 static const char **get_null_defines (void);
634 static int check_header (const struct header *, const char **);
635 static int xsystem (const char *);
638 main (int argc, char *argv[])
640 int h;
641 int result = 0;
642 const char **ignore_list;
644 CC = argc > 1 ? argv[1] : "gcc";
645 INC = argc > 2 ? argv[2] : "";
647 if (system (NULL) == 0)
649 puts ("Sorry, no command processor.");
650 return EXIT_FAILURE;
653 /* First get list of symbols which are defined by the compiler. */
654 ignore_list = get_null_defines ();
656 fputs ("Tested files:\n", stdout);
658 for (h = 0; h < NUMBER_OF_HEADERS; ++h)
659 result |= check_header (&headers[h], ignore_list);
661 /* The test suite should return errors but for now this is not
662 practical. Give a warning and ask the user to correct the bugs. */
663 return result;
667 static char *
668 xstrndup (const char *s, size_t n)
670 size_t len = n;
671 char *new = malloc (len + 1);
673 if (new == NULL)
674 return NULL;
676 new[len] = '\0';
677 return memcpy (new, s, len);
681 /* Like system but propagate interrupt and quit signals. */
683 xsystem (const char *cmd)
685 int status;
687 status = system (cmd);
688 if (status != -1)
690 if (WIFSIGNALED (status))
692 if (WTERMSIG (status) == SIGINT || WTERMSIG (status) == SIGQUIT)
693 raise (WTERMSIG (status));
695 else if (WIFEXITED (status))
697 if (WEXITSTATUS (status) == SIGINT + 128
698 || WEXITSTATUS (status) == SIGQUIT + 128)
699 raise (WEXITSTATUS (status) - 128);
702 return status;
706 static const char **
707 get_null_defines (void)
709 char line[BUFSIZ], *command;
710 char **result = NULL;
711 size_t result_len = 0;
712 size_t result_max = 0;
713 FILE *input;
714 int first = 1;
716 macrofile = tmpnam (NULL);
718 command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC)
719 + strlen (INC) + strlen (macrofile));
721 if (command == NULL)
723 puts ("No more memory.");
724 exit (1);
727 sprintf (command, fmt, "/dev/null", CC, INC, CC, macrofile);
729 if (xsystem (command))
731 puts ("system() returned nonzero");
732 return NULL;
734 free (command);
735 input = fopen (macrofile, "r");
737 if (input == NULL)
739 printf ("Could not read %s: ", macrofile);
740 perror (NULL);
741 return NULL;
744 while (fgets (line, sizeof line, input) != NULL)
746 char *start;
747 if (strlen (line) < 9 || line[7] != ' ')
748 { /* "#define A" */
749 printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
750 line);
751 continue;
753 if (line[8] == '_')
754 /* It's a safe identifier. */
755 continue;
756 if (result_len == result_max)
758 result_max += 10;
759 result = realloc (result, result_max * sizeof (char **));
760 if (result == NULL)
762 puts ("No more memory.");
763 exit (1);
766 start = &line[8];
767 result[result_len++] = xstrndup (start, strcspn (start, " ("));
769 if (first)
771 fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout);
772 first = 0;
774 puts (result[result_len - 1]);
776 if (result_len == result_max)
778 result_max += 1;
779 result = realloc (result, result_max * sizeof (char **));
780 if (result == NULL)
782 puts ("No more memory.");
783 exit (1);
786 result[result_len] = NULL;
787 fclose (input);
788 remove (macrofile);
790 return (const char **) result;
794 static int
795 check_header (const struct header *header, const char **except)
797 char line[BUFSIZ], command[sizeof fmt + strlen (header->name)
798 + 2 * strlen (CC)
799 + strlen (INC) + strlen (macrofile)];
800 FILE *input;
801 int result = 0;
802 int found[header->nsyms];
803 int i;
805 memset (found, '\0', header->nsyms * sizeof (int));
807 printf ("=== %s ===\n", header->name);
808 sprintf (command, fmt, header->name, CC, INC, CC, macrofile);
810 /* First see whether this subset is supported at all. */
811 if (header->subset != NULL)
813 sprintf (line, testfmt, header->subset, header->subset, CC, INC, CC,
814 macrofile);
815 if (xsystem (line))
817 printf ("!! not available\n");
818 return 0;
822 if (xsystem (command))
824 puts ("system() returned nonzero");
825 result = 1;
827 input = fopen (macrofile, "r");
829 if (input == NULL)
831 printf ("Could not read %s: ", macrofile);
832 perror (NULL);
833 return 1;
836 while (fgets (line, sizeof line, input) != NULL)
838 const char **ignore;
839 if (strlen (line) < 9 || line[7] != ' ')
840 { /* "#define A" */
841 printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
842 line);
843 result = 1;
844 continue;
847 /* Find next char after the macro identifier; this can be either
848 a space or an open parenthesis. */
849 line[8 + strcspn (&line[8], " (")] = '\0';
851 /* Now check whether it's one of the required macros. */
852 for (i = 0; i < header->nsyms; ++i)
853 if (!strcmp (&line[8], header->syms[i]))
854 break;
855 if (i < header->nsyms)
857 found[i] = 1;
858 continue;
861 /* Symbols starting with "_" are ok. */
862 if (line[8] == '_')
863 continue;
865 /* Maybe one of the symbols which are always defined. */
866 for (ignore = except; *ignore != NULL; ++ignore)
867 if (! strcmp (&line[8], *ignore))
868 break;
869 if (*ignore != NULL)
870 continue;
872 /* Otherwise the symbol better should match one of the following. */
873 for (i = 0; i < header->nmaybe; ++i)
874 if (fnmatch (header->maybe[i], &line[8], 0) == 0)
875 break;
876 if (i < header->nmaybe)
877 continue;
879 printf ("* invalid macro `%s'\n", &line[8]);
880 result |= 1;
882 fclose (input);
883 remove (macrofile);
885 for (i = 0; i < header->nsyms; ++i)
886 if (found[i] == 0)
887 printf ("** macro `%s' not defined\n", header->syms[i]);
889 return result;