1# fchownat.m4 serial 2
2dnl Copyright (C) 2004-2018 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
7# Written by Jim Meyering.
8
9# If we have the fchownat function, and it has the bug (in glibc-2.4)
10# that it dereferences symlinks even with AT_SYMLINK_NOFOLLOW, then
11# use the replacement function.
12# Also if the fchownat function, like chown, has the trailing slash bug,
13# use the replacement function.
14# Also use the replacement function if fchownat is simply not available.
15AC_DEFUN([gl_FUNC_FCHOWNAT],
16[
17  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
18  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
19  AC_REQUIRE([gl_FUNC_CHOWN])
20  AC_CHECK_FUNC([fchownat],
21    [gl_FUNC_FCHOWNAT_DEREF_BUG(
22       [REPLACE_FCHOWNAT=1
23        AC_DEFINE([FCHOWNAT_NOFOLLOW_BUG], [1],
24                  [Define to 1 if your platform has fchownat, but it cannot
25                   perform lchown tasks.])
26       ])
27     gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG(
28       [REPLACE_FCHOWNAT=1
29        AC_DEFINE([FCHOWNAT_EMPTY_FILENAME_BUG], [1],
30                  [Define to 1 if your platform has fchownat, but it does
31                   not reject an empty file name.])
32       ])
33     if test $REPLACE_CHOWN = 1; then
34       REPLACE_FCHOWNAT=1
35     fi],
36    [HAVE_FCHOWNAT=0])
37])
38
39# gl_FUNC_FCHOWNAT_DEREF_BUG([ACTION-IF-BUGGY[, ACTION-IF-NOT_BUGGY]])
40AC_DEFUN([gl_FUNC_FCHOWNAT_DEREF_BUG],
41[
42  dnl Persuade glibc's <unistd.h> to declare fchownat().
43  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
44
45  AC_CACHE_CHECK([whether fchownat works with AT_SYMLINK_NOFOLLOW],
46    [gl_cv_func_fchownat_nofollow_works],
47    [
48     gl_dangle=conftest.dangle
49     # Remove any remnants of a previous test.
50     rm -f $gl_dangle
51     # Arrange for deletion of the temporary file this test creates.
52     ac_clean_files="$ac_clean_files $gl_dangle"
53     ln -s conftest.no-such $gl_dangle
54     AC_RUN_IFELSE(
55       [AC_LANG_SOURCE(
56          [[
57#include <fcntl.h>
58#include <unistd.h>
59#include <stdlib.h>
60#include <errno.h>
61#include <sys/types.h>
62int
63main ()
64{
65  return (fchownat (AT_FDCWD, "$gl_dangle", -1, getgid (),
66                    AT_SYMLINK_NOFOLLOW) != 0
67          && errno == ENOENT);
68}
69          ]])],
70       [gl_cv_func_fchownat_nofollow_works=yes],
71       [gl_cv_func_fchownat_nofollow_works=no],
72       [gl_cv_func_fchownat_nofollow_works=no])
73  ])
74  AS_IF([test $gl_cv_func_fchownat_nofollow_works = no], [$1], [$2])
75])
76
77# gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG([ACTION-IF-BUGGY[, ACTION-IF-NOT_BUGGY]])
78AC_DEFUN([gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG],
79[
80  dnl Persuade glibc's <unistd.h> to declare fchownat().
81  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
82
83  AC_CACHE_CHECK([whether fchownat works with an empty file name],
84    [gl_cv_func_fchownat_empty_filename_works],
85    [AC_RUN_IFELSE(
86       [AC_LANG_PROGRAM(
87          [[#include <unistd.h>
88            #include <fcntl.h>
89          ]],
90          [[int fd;
91            int ret;
92            if (mkdir ("conftestdir", 0700) < 0)
93              return 2;
94            fd = open ("conftestdir", O_RDONLY);
95            if (fd < 0)
96              return 3;
97            ret = fchownat (fd, "", -1, -1, 0);
98            close (fd);
99            rmdir ("conftestdir");
100            return ret == 0;
101          ]])],
102       [gl_cv_func_fchownat_empty_filename_works=yes],
103       [gl_cv_func_fchownat_empty_filename_works=no],
104       [gl_cv_func_fchownat_empty_filename_works="guessing no"])
105    ])
106  AS_IF([test "$gl_cv_func_fchownat_empty_filename_works" != yes], [$1], [$2])
107])
108