fcntl: support F_DUPFD_CLOEXEC on systems with fcntl
[gnulib.git] / m4 / fcntl_h.m4
1 # serial 7
2 # Configure fcntl.h.
3 dnl Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
7
8 dnl Written by Paul Eggert.
9
10 AC_DEFUN([gl_FCNTL_H],
11 [
12   AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
13   AC_REQUIRE([gl_FCNTL_O_FLAGS])
14   gl_CHECK_NEXT_HEADERS([fcntl.h])
15 ])
16
17 # Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
18 # Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
19 # Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
20 AC_DEFUN([gl_FCNTL_O_FLAGS],
21 [
22   dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
23   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
24   AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h],
25     [AC_RUN_IFELSE(
26        [AC_LANG_PROGRAM(
27           [[#include <sys/types.h>
28            #include <sys/stat.h>
29            #include <unistd.h>
30            #include <fcntl.h>
31            #ifndef O_NOATIME
32             #define O_NOATIME 0
33            #endif
34            #ifndef O_NOFOLLOW
35             #define O_NOFOLLOW 0
36            #endif
37            static int const constants[] =
38             {
39               O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
40               O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
41             };
42           ]],
43           [[
44             int status = !constants;
45             {
46               static char const sym[] = "conftest.sym";
47               if (symlink (".", sym) != 0
48                   || close (open (sym, O_RDONLY | O_NOFOLLOW)) == 0)
49                 status |= 32;
50               unlink (sym);
51             }
52             {
53               static char const file[] = "confdefs.h";
54               int fd = open (file, O_RDONLY | O_NOATIME);
55               char c;
56               struct stat st0, st1;
57               if (fd < 0
58                   || fstat (fd, &st0) != 0
59                   || sleep (1) != 0
60                   || read (fd, &c, 1) != 1
61                   || close (fd) != 0
62                   || stat (file, &st1) != 0
63                   || st0.st_atime != st1.st_atime)
64                 status |= 64;
65             }
66             return status;]])],
67        [gl_cv_header_working_fcntl_h=yes],
68        [case $? in #(
69         32) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
70         64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
71         96) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
72          *) gl_cv_header_working_fcntl_h='no';;
73         esac],
74        [gl_cv_header_working_fcntl_h=cross-compiling])])
75
76   case $gl_cv_header_working_fcntl_h in #(
77   *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
78   *) ac_val=1;;
79   esac
80   AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val],
81     [Define to 1 if O_NOATIME works.])
82
83   case $gl_cv_header_working_fcntl_h in #(
84   *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
85   *) ac_val=1;;
86   esac
87   AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val],
88     [Define to 1 if O_NOFOLLOW works.])
89 ])
90
91 AC_DEFUN([gl_FCNTL_MODULE_INDICATOR],
92 [
93   dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
94   AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
95   GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
96 ])
97
98 AC_DEFUN([gl_FCNTL_H_DEFAULTS],
99 [
100   GNULIB_FCNTL=0;   AC_SUBST([GNULIB_FCNTL])
101   GNULIB_OPEN=0;    AC_SUBST([GNULIB_OPEN])
102   GNULIB_OPENAT=0;  AC_SUBST([GNULIB_OPENAT])
103   dnl Assume proper GNU behavior unless another module says otherwise.
104   HAVE_OPENAT=1;    AC_SUBST([HAVE_OPENAT])
105   REPLACE_FCNTL=0;  AC_SUBST([REPLACE_FCNTL])
106   REPLACE_OPEN=0;   AC_SUBST([REPLACE_OPEN])
107   REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT])
108 ])