git-merge-changelog: Simplify installation instructions.
[gnulib.git] / m4 / fcntl-o.m4
blob43aa132579d72763956c1327b40dca822692655a
1 # fcntl-o.m4
2 # serial 8
3 dnl Copyright (C) 2006, 2009-2024 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.
8 dnl Written by Paul Eggert.
10 AC_PREREQ([2.60])
12 # Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
13 # Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
14 # Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
15 AC_DEFUN([gl_FCNTL_O_FLAGS],
17   dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
18   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
20   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
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            ]GL_MDA_DEFINES[
37            #ifndef O_NOATIME
38             #define O_NOATIME 0
39            #endif
40            #ifndef O_NOFOLLOW
41             #define O_NOFOLLOW 0
42            #endif
43            static int const constants[] =
44             {
45               O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
46               O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
47             };
48           ]],
49           [[
50             int result = !constants;
51             #if HAVE_SYMLINK
52             {
53               static char const sym[] = "conftest.sym";
54               if (symlink ("/dev/null", sym) != 0)
55                 result |= 2;
56               else
57                 {
58                   int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0);
59                   if (fd >= 0)
60                     {
61                       close (fd);
62                       result |= 4;
63                     }
64                 }
65               if (unlink (sym) != 0 || symlink (".", sym) != 0)
66                 result |= 2;
67               else
68                 {
69                   int fd = open (sym, O_RDONLY | O_NOFOLLOW);
70                   if (fd >= 0)
71                     {
72                       close (fd);
73                       result |= 4;
74                     }
75                 }
76               unlink (sym);
77             }
78             #endif
79             {
80               static char const file[] = "confdefs.h";
81               int fd = open (file, O_RDONLY | O_NOATIME);
82               if (fd < 0)
83                 result |= 8;
84               else
85                 {
86                   struct stat st0;
87                   if (fstat (fd, &st0) != 0)
88                     result |= 16;
89                   else
90                     {
91                       char c;
92                       sleep (1);
93                       if (read (fd, &c, 1) != 1)
94                         result |= 24;
95                       else
96                         {
97                           if (close (fd) != 0)
98                             result |= 32;
99                           else
100                             {
101                               struct stat st1;
102                               if (stat (file, &st1) != 0)
103                                 result |= 40;
104                               else
105                                 if (st0.st_atime != st1.st_atime)
106                                   result |= 64;
107                             }
108                         }
109                     }
110                 }
111             }
112             return result;]])],
113        [gl_cv_header_working_fcntl_h=yes],
114        [case $? in #(
115         4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
116         64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
117         68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
118          *) gl_cv_header_working_fcntl_h='no';;
119         esac],
120        [case "$host_os" in
121                              # Guess 'no' on native Windows.
122           mingw* | windows*) gl_cv_header_working_fcntl_h='no' ;;
123           *)                 gl_cv_header_working_fcntl_h=cross-compiling ;;
124         esac
125        ])
126     ])
128   case $gl_cv_header_working_fcntl_h in #(
129   *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
130   *) ac_val=1;;
131   esac
132   AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val],
133     [Define to 1 if O_NOATIME works.])
135   case $gl_cv_header_working_fcntl_h in #(
136   *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
137   *) ac_val=1;;
138   esac
139   AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val],
140     [Define to 1 if O_NOFOLLOW works.])