xref: /netbsd-src/external/gpl3/gdb/dist/gnulib/import/m4/chown.m4 (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
1# serial 35
2# Determine whether we need the chown wrapper.
3
4dnl Copyright (C) 1997-2001, 2003-2005, 2007, 2009-2022 Free Software
5dnl Foundation, Inc.
6
7dnl This file is free software; the Free Software Foundation
8dnl gives unlimited permission to copy and/or distribute it,
9dnl with or without modifications, as long as this notice is preserved.
10
11# chown should accept arguments of -1 for uid and gid, and it should
12# dereference symlinks.  If it doesn't, arrange to use the replacement
13# function.
14
15# From Jim Meyering.
16
17# This is taken from the following Autoconf patch:
18# https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9
19AC_DEFUN([AC_FUNC_CHOWN],
20[
21  AC_REQUIRE([AC_TYPE_UID_T])dnl
22  AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
23  AC_CHECK_HEADERS([unistd.h])
24  AC_CACHE_CHECK([for working chown],
25    [ac_cv_func_chown_works],
26    [AC_RUN_IFELSE(
27       [AC_LANG_PROGRAM(
28          [AC_INCLUDES_DEFAULT
29           [#include <fcntl.h>
30          ]GL_MDA_DEFINES],
31          [[
32            char *f = "conftest.chown";
33            struct stat before, after;
34
35            if (creat (f, 0600) < 0)
36              return 1;
37            if (stat (f, &before) < 0)
38              return 1;
39            if (chown (f, (uid_t) -1, (gid_t) -1) == -1)
40              return 1;
41            if (stat (f, &after) < 0)
42              return 1;
43            return ! (before.st_uid == after.st_uid && before.st_gid == after.st_gid);
44          ]])
45       ],
46       [ac_cv_func_chown_works=yes],
47       [ac_cv_func_chown_works=no],
48       [case "$host_os" in # ((
49                           # Guess yes on Linux systems.
50          linux-* | linux) ac_cv_func_chown_works="guessing yes" ;;
51                           # Guess yes on glibc systems.
52          *-gnu* | gnu*)   ac_cv_func_chown_works="guessing yes" ;;
53                           # Guess no on native Windows.
54          mingw*)          ac_cv_func_chown_works="guessing no" ;;
55                           # If we don't know, obey --enable-cross-guesses.
56          *)               ac_cv_func_chown_works="$gl_cross_guess_normal" ;;
57        esac
58       ])
59     rm -f conftest.chown
60    ])
61  case "$ac_cv_func_chown_works" in
62    *yes)
63      AC_DEFINE([HAVE_CHOWN], [1],
64        [Define to 1 if your system has a working `chown' function.])
65      ;;
66  esac
67])# AC_FUNC_CHOWN
68
69AC_DEFUN_ONCE([gl_FUNC_CHOWN],
70[
71  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
72  AC_REQUIRE([AC_TYPE_UID_T])
73  AC_REQUIRE([AC_FUNC_CHOWN])
74  AC_REQUIRE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK])
75  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
76  AC_CHECK_FUNCS_ONCE([chown fchown])
77
78  dnl mingw lacks chown altogether.
79  if test $ac_cv_func_chown = no; then
80    HAVE_CHOWN=0
81  else
82    dnl Some old systems treated chown like lchown.
83    case "$gl_cv_func_chown_follows_symlink" in
84      *yes) ;;
85      *) REPLACE_CHOWN=1 ;;
86    esac
87
88    dnl Some old systems tried to use uid/gid -1 literally.
89    case "$ac_cv_func_chown_works" in
90      *no)
91        AC_DEFINE([CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE], [1],
92          [Define if chown is not POSIX compliant regarding IDs of -1.])
93        REPLACE_CHOWN=1
94        ;;
95    esac
96
97    dnl Solaris 9 ignores trailing slash.
98    dnl FreeBSD 7.2 mishandles trailing slash on symlinks.
99    dnl Likewise for AIX 7.1.
100    AC_CACHE_CHECK([whether chown honors trailing slash],
101      [gl_cv_func_chown_slash_works],
102      [touch conftest.file && rm -f conftest.link
103       AC_RUN_IFELSE([AC_LANG_PROGRAM([[
104#include <unistd.h>
105#include <stdlib.h>
106#include <errno.h>
107]GL_MDA_DEFINES],
108        [[if (symlink ("conftest.file", "conftest.link")) return 1;
109          if (chown ("conftest.link/", getuid (), getgid ()) == 0) return 2;
110        ]])],
111        [gl_cv_func_chown_slash_works=yes],
112        [gl_cv_func_chown_slash_works=no],
113        [case "$host_os" in
114                    # Guess yes on glibc systems.
115           *-gnu*)  gl_cv_func_chown_slash_works="guessing yes" ;;
116                    # Guess yes on musl systems.
117           *-musl*) gl_cv_func_chown_slash_works="guessing yes" ;;
118                    # If we don't know, obey --enable-cross-guesses.
119           *)       gl_cv_func_chown_slash_works="$gl_cross_guess_normal" ;;
120         esac
121        ])
122      rm -f conftest.link conftest.file])
123    case "$gl_cv_func_chown_slash_works" in
124      *yes) ;;
125      *)
126        AC_DEFINE([CHOWN_TRAILING_SLASH_BUG], [1],
127          [Define to 1 if chown mishandles trailing slash.])
128        REPLACE_CHOWN=1
129        ;;
130    esac
131
132    dnl OpenBSD fails to update ctime if ownership does not change.
133    AC_CACHE_CHECK([whether chown always updates ctime],
134      [gl_cv_func_chown_ctime_works],
135      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
136#include <unistd.h>
137#include <stdlib.h>
138#include <errno.h>
139#include <fcntl.h>
140#include <sys/stat.h>
141]GL_MDA_DEFINES],
142        [[struct stat st1, st2;
143          if (close (creat ("conftest.file", 0600))) return 1;
144          if (stat ("conftest.file", &st1)) return 2;
145          sleep (1);
146          if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3;
147          if (stat ("conftest.file", &st2)) return 4;
148          if (st2.st_ctime <= st1.st_ctime) return 5;
149        ]])],
150        [gl_cv_func_chown_ctime_works=yes],
151        [gl_cv_func_chown_ctime_works=no],
152        [case "$host_os" in
153                    # Guess yes on glibc systems.
154           *-gnu*)  gl_cv_func_chown_ctime_works="guessing yes" ;;
155                    # Guess yes on musl systems.
156           *-musl*) gl_cv_func_chown_ctime_works="guessing yes" ;;
157                    # If we don't know, obey --enable-cross-guesses.
158           *)       gl_cv_func_chown_ctime_works="$gl_cross_guess_normal" ;;
159         esac
160        ])
161      rm -f conftest.file])
162    case "$gl_cv_func_chown_ctime_works" in
163      *yes) ;;
164      *)
165        AC_DEFINE([CHOWN_CHANGE_TIME_BUG], [1], [Define to 1 if chown fails
166          to change ctime when at least one argument was not -1.])
167        REPLACE_CHOWN=1
168        ;;
169    esac
170  fi
171])
172
173# Determine whether chown follows symlinks (it should).
174AC_DEFUN_ONCE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK],
175[
176  AC_CACHE_CHECK(
177    [whether chown dereferences symlinks],
178    [gl_cv_func_chown_follows_symlink],
179    [
180      AC_RUN_IFELSE([AC_LANG_SOURCE([[
181#include <unistd.h>
182#include <stdlib.h>
183#include <errno.h>
184]GL_MDA_DEFINES[
185        int
186        main ()
187        {
188          int result = 0;
189          char const *dangling_symlink = "conftest.dangle";
190
191          unlink (dangling_symlink);
192          if (symlink ("conftest.no-such", dangling_symlink))
193            abort ();
194
195          /* Exit successfully on a conforming system,
196             i.e., where chown must fail with ENOENT.  */
197          if (chown (dangling_symlink, getuid (), getgid ()) == 0)
198            result |= 1;
199          if (errno != ENOENT)
200            result |= 2;
201          return result;
202        }
203        ]])],
204        [gl_cv_func_chown_follows_symlink=yes],
205        [gl_cv_func_chown_follows_symlink=no],
206        [gl_cv_func_chown_follows_symlink="guessing yes"]
207      )
208    ]
209  )
210
211  case "$gl_cv_func_chown_follows_symlink" in
212    *yes) ;;
213    *)
214      AC_DEFINE([CHOWN_MODIFIES_SYMLINK], [1],
215        [Define if chown modifies symlinks.])
216      ;;
217  esac
218])
219