1# fcntl-o.m4 serial 4
2dnl Copyright (C) 2006, 2009-2012 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7dnl Written by Paul Eggert.
8
9# Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
10# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
11# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
12AC_DEFUN([gl_FCNTL_O_FLAGS],
13[
14  dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
15  dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
16  dnl AC_GNU_SOURCE.
17  m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
18    [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
19    [AC_REQUIRE([AC_GNU_SOURCE])])
20
21  AC_CHECK_HEADERS_ONCE([unistd.h])
22  AC_CHECK_FUNCS_ONCE([symlink])
23  AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h],
24    [AC_RUN_IFELSE(
25       [AC_LANG_PROGRAM(
26          [[#include <sys/types.h>
27           #include <sys/stat.h>
28           #if HAVE_UNISTD_H
29           # include <unistd.h>
30           #else /* on Windows with MSVC */
31           # include <io.h>
32           # include <stdlib.h>
33           # defined sleep(n) _sleep ((n) * 1000)
34           #endif
35           #include <fcntl.h>
36           #ifndef O_NOATIME
37            #define O_NOATIME 0
38           #endif
39           #ifndef O_NOFOLLOW
40            #define O_NOFOLLOW 0
41           #endif
42           static int const constants[] =
43            {
44              O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
45              O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
46            };
47          ]],
48          [[
49            int result = !constants;
50            #if HAVE_SYMLINK
51            {
52              static char const sym[] = "conftest.sym";
53              if (symlink ("/dev/null", sym) != 0)
54                result |= 2;
55              else
56                {
57                  int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0);
58                  if (fd >= 0)
59                    {
60                      close (fd);
61                      result |= 4;
62                    }
63                }
64              if (unlink (sym) != 0 || symlink (".", sym) != 0)
65                result |= 2;
66              else
67                {
68                  int fd = open (sym, O_RDONLY | O_NOFOLLOW);
69                  if (fd >= 0)
70                    {
71                      close (fd);
72                      result |= 4;
73                    }
74                }
75              unlink (sym);
76            }
77            #endif
78            {
79              static char const file[] = "confdefs.h";
80              int fd = open (file, O_RDONLY | O_NOATIME);
81              if (fd < 0)
82                result |= 8;
83              else
84                {
85                  struct stat st0;
86                  if (fstat (fd, &st0) != 0)
87                    result |= 16;
88                  else
89                    {
90                      char c;
91                      sleep (1);
92                      if (read (fd, &c, 1) != 1)
93                        result |= 24;
94                      else
95                        {
96                          if (close (fd) != 0)
97                            result |= 32;
98                          else
99                            {
100                              struct stat st1;
101                              if (stat (file, &st1) != 0)
102                                result |= 40;
103                              else
104                                if (st0.st_atime != st1.st_atime)
105                                  result |= 64;
106                            }
107                        }
108                    }
109                }
110            }
111            return result;]])],
112       [gl_cv_header_working_fcntl_h=yes],
113       [case $? in #(
114        4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
115        64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
116        68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
117         *) gl_cv_header_working_fcntl_h='no';;
118        esac],
119       [gl_cv_header_working_fcntl_h=cross-compiling])])
120
121  case $gl_cv_header_working_fcntl_h in #(
122  *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
123  *) ac_val=1;;
124  esac
125  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val],
126    [Define to 1 if O_NOATIME works.])
127
128  case $gl_cv_header_working_fcntl_h in #(
129  *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
130  *) ac_val=1;;
131  esac
132  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val],
133    [Define to 1 if O_NOFOLLOW works.])
134])
135