Next: , Previous: Header Portability, Up: Header Files


5.6.2 Particular Header Checks

These macros check for particular system header files—whether they exist, and in some cases whether they declare certain symbols.

— Macro: AC_HEADER_DIRENT

Check for the following header files. For the first one that is found and defines `DIR', define the listed C preprocessor macro:

dirent.h HAVE_DIRENT_H
sys/ndir.h HAVE_SYS_NDIR_H
sys/dir.h HAVE_SYS_DIR_H
ndir.h HAVE_NDIR_H

The directory-library declarations in your source code should look something like the following:

          #if HAVE_DIRENT_H
          # include <dirent.h>
          # define NAMLEN(dirent) strlen((dirent)->d_name)
          #else
          # define dirent direct
          # define NAMLEN(dirent) (dirent)->d_namlen
          # if HAVE_SYS_NDIR_H
          #  include <sys/ndir.h>
          # endif
          # if HAVE_SYS_DIR_H
          #  include <sys/dir.h>
          # endif
          # if HAVE_NDIR_H
          #  include <ndir.h>
          # endif
          #endif
     

Using the above declarations, the program would declare variables to be of type struct dirent, not struct direct, and would access the length of a directory entry name by passing a pointer to a struct dirent to the NAMLEN macro.

This macro also checks for the SCO Xenix dir and x libraries.

— Macro: AC_HEADER_MAJOR

If sys/types.h does not define major, minor, and makedev, but sys/mkdev.h does, define MAJOR_IN_MKDEV; otherwise, if sys/sysmacros.h does, define MAJOR_IN_SYSMACROS.

— Macro: AC_HEADER_STAT

If the macros S_ISDIR, S_ISREG, etc. defined in sys/stat.h do not work properly (returning false positives), define STAT_MACROS_BROKEN. This is the case on Tektronix UTekV, Amdahl UTS and Motorola System V/88.

— Macro: AC_HEADER_STDBOOL

If stdbool.h exists and is conformant to C99, define HAVE_STDBOOL_H to 1; if the type _Bool is defined, define HAVE__BOOL to 1. To fulfill the C99 requirements, your system.h should contain the following code:

     
     #if HAVE_STDBOOL_H
     # include <stdbool.h>
     #else
     # if ! HAVE__BOOL
     #  ifdef __cplusplus
     typedef bool _Bool;
     #  else
     typedef unsigned char _Bool;
     #  endif
     # endif
     # define bool _Bool
     # define false 0
     # define true 1
     # define __bool_true_false_are_defined 1
     #endif

— Macro: AC_HEADER_STDC

Define STDC_HEADERS if the system has ANSI C header files. Specifically, this macro checks for stdlib.h, stdarg.h, string.h, and float.h; if the system has those, it probably has the rest of the ANSI C header files. This macro also checks whether string.h declares memchr (and thus presumably the other mem functions), whether stdlib.h declare free (and thus presumably malloc and other related functions), and whether the ctype.h macros work on characters with the high bit set, as ANSI C requires.

Use STDC_HEADERS instead of __STDC__ to determine whether the system has ANSI-compliant header files (and probably C library functions) because many systems that have GCC do not have ANSI C header files.

On systems without ANSI C headers, there is so much variation that it is probably easier to declare the functions you use than to figure out exactly what the system header files declare. Some systems contain a mix of functions from ANSI and BSD; some are mostly ANSI but lack `memmove'; some define the BSD functions as macros in string.h or strings.h; some have only the BSD functions but string.h; some declare the memory functions in memory.h, some in string.h; etc. It is probably sufficient to check for one string function and one memory function; if the library has the ANSI versions of those then it probably has most of the others. If you put the following in configure.ac:

          AC_HEADER_STDC
          AC_CHECK_FUNCS(strchr memcpy)
     

then, in your code, you can use declarations like this:

          #if STDC_HEADERS
          # include <string.h>
          #else
          # if !HAVE_STRCHR
          #  define strchr index
          #  define strrchr rindex
          # endif
          char *strchr (), *strrchr ();
          # if !HAVE_MEMCPY
          #  define memcpy(d, s, n) bcopy ((s), (d), (n))
          #  define memmove(d, s, n) bcopy ((s), (d), (n))
          # endif
          #endif
     

If you use a function like memchr, memset, strtok, or strspn, which have no BSD equivalent, then macros won't suffice; you must provide an implementation of each function. An easy way to incorporate your implementations only when needed (since the ones in system C libraries may be hand optimized) is to, taking memchr for example, put it in memchr.c and use `AC_REPLACE_FUNCS(memchr)'.

— Macro: AC_HEADER_SYS_WAIT

If sys/wait.h exists and is compatible with POSIX, define HAVE_SYS_WAIT_H. Incompatibility can occur if sys/wait.h does not exist, or if it uses the old BSD union wait instead of int to store a status value. If sys/wait.h is not POSIX compatible, then instead of including it, define the POSIX macros with their usual interpretations. Here is an example:

          #include <sys/types.h>
          #if HAVE_SYS_WAIT_H
          # include <sys/wait.h>
          #endif
          #ifndef WEXITSTATUS
          # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
          #endif
          #ifndef WIFEXITED
          # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
          #endif
     

_POSIX_VERSION is defined when unistd.h is included on POSIX systems. If there is no unistd.h, it is definitely not a POSIX system. However, some non-POSIX systems do have unistd.h.

The way to check if the system supports POSIX is:

     #if HAVE_UNISTD_H
     # include <sys/types.h>
     # include <unistd.h>
     #endif
     
     #ifdef _POSIX_VERSION
     /* Code for POSIX systems.  */
     #endif
— Macro: AC_HEADER_TIME

If a program may include both time.h and sys/time.h, define TIME_WITH_SYS_TIME. On some older systems, sys/time.h includes time.h, but time.h is not protected against multiple inclusion, so programs should not explicitly include both files. This macro is useful in programs that use, for example, struct timeval as well as struct tm. It is best used in conjunction with HAVE_SYS_TIME_H, which can be checked for using AC_CHECK_HEADERS(sys/time.h).

          #if TIME_WITH_SYS_TIME
          # include <sys/time.h>
          # include <time.h>
          #else
          # if HAVE_SYS_TIME_H
          #  include <sys/time.h>
          # else
          #  include <time.h>
          # endif
          #endif
     
— Macro: AC_HEADER_TIOCGWINSZ

If the use of TIOCGWINSZ requires <sys/ioctl.h>, then define GWINSZ_IN_SYS_IOCTL. Otherwise TIOCGWINSZ can be found in <termios.h>.

Use:

          #if HAVE_TERMIOS_H
          # include <termios.h>
          #endif
          
          #if GWINSZ_IN_SYS_IOCTL
          # include <sys/ioctl.h>
          #endif