immutable: Add tests.
[gnulib.git] / m4 / fchmodat.m4
blob66c0e308fcc88ecdd2eb681b1605cf72413d210c
1 # fchmodat.m4 serial 6
2 dnl Copyright (C) 2004-2021 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
7 # Written by Jim Meyering.
9 AC_DEFUN([gl_FUNC_FCHMODAT],
11   AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
12   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
13   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
14   AC_CHECK_FUNCS_ONCE([fchmodat lchmod])
15   if test $ac_cv_func_fchmodat != yes; then
16     HAVE_FCHMODAT=0
17   else
18     AC_CACHE_CHECK(
19       [whether fchmodat works],
20       [gl_cv_func_fchmodat_works],
21       [AC_RUN_IFELSE(
22          [AC_LANG_PROGRAM(
23             [
24               AC_INCLUDES_DEFAULT[
25               #include <fcntl.h>
26               #ifndef S_IRUSR
27                #define S_IRUSR 0400
28               #endif
29               #ifndef S_IWUSR
30                #define S_IWUSR 0200
31               #endif
32               #ifndef S_IRWXU
33                #define S_IRWXU 0700
34               #endif
35               #ifndef S_IRWXG
36                #define S_IRWXG 0070
37               #endif
38               #ifndef S_IRWXO
39                #define S_IRWXO 0007
40               #endif
41             ]GL_MDA_DEFINES],
42             [[
43               int permissive = S_IRWXU | S_IRWXG | S_IRWXO;
44               int desired = S_IRUSR | S_IWUSR;
45               int result = 0;
46               #define file "conftest.fchmodat"
47               struct stat st;
48               if (creat (file, permissive) < 0)
49                 return 1;
50               /* Test whether fchmodat rejects a trailing slash on a non-directory.
51                  This test fails on AIX 7.2.  */
52               if (fchmodat (AT_FDCWD, file "/", desired, 0) == 0)
53                 result |= 2;
54               /* Test whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks.
55                  This test fails on GNU/Linux with glibc 2.31 (but not on
56                  GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9.  */
57               if (fchmodat (AT_FDCWD, file, desired, AT_SYMLINK_NOFOLLOW) != 0)
58                 result |= 4;
59               if (stat (file, &st) != 0)
60                 return 1;
61               if ((st.st_mode & permissive) != desired)
62                 result |= 4;
63               return result;
64             ]])],
65          [gl_cv_func_fchmodat_works=yes],
66          [case $? in
67             2) gl_cv_func_fchmodat_works='nearly' ;;
68             *) gl_cv_func_fchmodat_works=no ;;
69           esac
70          ],
71          [case "$host_os" in
72                                   # Guess no on Linux with glibc and Cygwin.
73             linux-gnu* | cygwin*) gl_cv_func_fchmodat_works="guessing no" ;;
74                                   # Guess 'nearly' on AIX.
75             aix*)                 gl_cv_func_fchmodat_works="guessing nearly" ;;
76                                   # If we don't know, obey --enable-cross-guesses.
77             *)                    gl_cv_func_fchmodat_works="$gl_cross_guess_normal" ;;
78           esac
79          ])
80        rm -f conftest.fchmodat])
81     case "$gl_cv_func_fchmodat_works" in
82       *yes) ;;
83       *nearly)
84         AC_DEFINE([HAVE_NEARLY_WORKING_FCHMODAT], [1],
85           [Define to 1 if fchmodat works, except for the trailing slash handling.])
86         REPLACE_FCHMODAT=1
87         ;;
88       *)
89         AC_DEFINE([NEED_FCHMODAT_NONSYMLINK_FIX], [1],
90           [Define to 1 if fchmodat+AT_SYMLINK_NOFOLLOW does not work right on non-symlinks.])
91         REPLACE_FCHMODAT=1
92         ;;
93     esac
94   fi
97 # Prerequisites of lib/fchmodat.c.
98 AC_DEFUN([gl_PREREQ_FCHMODAT],
100   AC_CHECK_FUNCS_ONCE([lchmod])
101   :