1
0
mirror of https://git.savannah.gnu.org/git/gnulib.git synced 2026-10-24 00:48:56 +03:00
Files
gnulib/m4/chown.m4
Paul Eggert 892264dea5 chown: use AC_CHECK_HEADERS_ONCE on standard headers
* m4/chown.m4 (AC_FUNC_CHOWN):
* m4/size_max.m4 (gl_SIZE_MAX):
* m4/xsize.m4 (gl_XSIZE): Prefer AC_CHECK_HEADERS_ONCE to
AC_CHECK_HEADERS for standard headers that Autoconf will use
AC_CHECK_HEADERS_ONCE on anyway.
2026-05-10 15:56:14 -07:00

224 lines
7.4 KiB
Plaintext

# chown.m4
# serial 40
dnl Copyright (C) 1997-2001, 2003-2005, 2007, 2009-2026 Free Software
dnl Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This file is offered as-is, without any warranty.
# Determine whether we need the chown wrapper.
# chown should accept arguments of -1 for uid and gid, and it should
# dereference symlinks. If it doesn't, arrange to use the replacement
# function.
# From Jim Meyering.
# This is taken from the following Autoconf patch:
# https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9
AC_DEFUN([AC_FUNC_CHOWN],
[
AC_REQUIRE([AC_TYPE_UID_T])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
AC_CHECK_HEADERS_ONCE([unistd.h])
AC_CACHE_CHECK([for working chown],
[ac_cv_func_chown_works],
[AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[AC_INCLUDES_DEFAULT
[#include <fcntl.h>
]GL_MDA_DEFINES],
[[
char *f = "conftest.chown";
struct stat before, after;
if (creat (f, 0600) < 0)
return 1;
if (stat (f, &before) < 0)
return 1;
if (chown (f, (uid_t) -1, (gid_t) -1) == -1)
return 1;
if (stat (f, &after) < 0)
return 1;
return ! (before.st_uid == after.st_uid && before.st_gid == after.st_gid);
]])
],
[ac_cv_func_chown_works=yes],
[ac_cv_func_chown_works=no],
[case "$host_os" in # ((
# Guess yes on Linux systems.
linux-* | linux) ac_cv_func_chown_works="guessing yes" ;;
# Guess yes on glibc systems.
*-gnu* | gnu*) ac_cv_func_chown_works="guessing yes" ;;
# Guess no on native Windows.
mingw* | windows*) ac_cv_func_chown_works="guessing no" ;;
# If we don't know, obey --enable-cross-guesses.
*) ac_cv_func_chown_works="$gl_cross_guess_normal" ;;
esac
])
rm -f conftest.chown
])
case "$ac_cv_func_chown_works" in
*yes)
AC_DEFINE([HAVE_CHOWN], [1],
[Define to 1 if your system has a working `chown' function.])
;;
esac
])# AC_FUNC_CHOWN
AC_DEFUN_ONCE([gl_FUNC_CHOWN],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
AC_REQUIRE([AC_TYPE_UID_T])
AC_REQUIRE([AC_FUNC_CHOWN])
AC_REQUIRE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CHECK_FUNCS_ONCE([chown fchown])
dnl mingw lacks chown altogether.
if test $ac_cv_func_chown = no; then
HAVE_CHOWN=0
else
dnl Some old systems treated chown like lchown.
case "$gl_cv_func_chown_follows_symlink" in
*yes) ;;
*) REPLACE_CHOWN=1 ;;
esac
dnl Some old systems tried to use uid/gid -1 literally.
case "$ac_cv_func_chown_works" in
*no)
AC_DEFINE([CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE], [1],
[Define if chown is not POSIX compliant regarding IDs of -1.])
REPLACE_CHOWN=1
;;
esac
dnl Solaris 9 ignores trailing slash.
dnl FreeBSD 7.2 mishandles trailing slash on symlinks.
dnl Likewise for AIX 7.1.
AC_CACHE_CHECK([whether chown honors trailing slash],
[gl_cv_func_chown_slash_works],
[touch conftest.file && rm -f conftest.link
AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
]GL_MDA_DEFINES],
[[if (symlink ("conftest.file", "conftest.link")) return 1;
if (chown ("conftest.link/", getuid (), getgid ()) == 0) return 2;
]])],
[gl_cv_func_chown_slash_works=yes],
[gl_cv_func_chown_slash_works=no],
[case "$host_os" in
# Guess yes on glibc systems.
*-gnu*) gl_cv_func_chown_slash_works="guessing yes" ;;
# Guess yes on musl systems.
*-musl*) gl_cv_func_chown_slash_works="guessing yes" ;;
# If we don't know, obey --enable-cross-guesses.
*) gl_cv_func_chown_slash_works="$gl_cross_guess_normal" ;;
esac
])
rm -f conftest.link conftest.file])
case "$gl_cv_func_chown_slash_works" in
*yes) ;;
*)
AC_DEFINE([CHOWN_TRAILING_SLASH_BUG], [1],
[Define to 1 if chown mishandles trailing slash.])
REPLACE_CHOWN=1
;;
esac
dnl OpenBSD fails to update ctime if ownership does not change.
AC_CACHE_CHECK([whether chown updates ctime per POSIX],
[gl_cv_func_chown_ctime_works],
[dnl This test is tricky as it depends on timing and file timestamp
dnl resolution, and there were false positives when configuring with
dnl Linux fakeroot. Since the problem occurs only on OpenBSD and Cygwin,
dnl test only on these platforms.
AS_CASE([$host_os],
[openbsd* | cygwin*],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
]GL_MDA_DEFINES],
[[struct stat st1, st2;
if (close (creat ("conftest.file", 0600))) return 1;
if (stat ("conftest.file", &st1)) return 2;
sleep (1);
if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3;
if (stat ("conftest.file", &st2)) return 4;
if (st2.st_ctime <= st1.st_ctime) return 5;
]])],
[gl_cv_func_chown_ctime_works=yes],
[gl_cv_func_chown_ctime_works=no],
[# Obey --enable-cross-guesses.
gl_cv_func_chown_ctime_works="$gl_cross_guess_normal"
])
rm -f conftest.file
],
[gl_cv_func_chown_ctime_works=yes])
])
case "$gl_cv_func_chown_ctime_works" in
*yes) ;;
*)
gl_CHECK_FUNCS_ANDROID([utimensat], [[#include <sys/stat.h>]])
AC_DEFINE([CHOWN_CHANGE_TIME_BUG], [1], [Define to 1 if chown fails
to change ctime when at least one argument was not -1.])
REPLACE_CHOWN=1
;;
esac
fi
])
# Determine whether chown follows symlinks (it should).
AC_DEFUN_ONCE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK],
[
AC_CACHE_CHECK(
[whether chown dereferences symlinks],
[gl_cv_func_chown_follows_symlink],
[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
]GL_MDA_DEFINES[
int
main ()
{
int result = 0;
char const *dangling_symlink = "conftest.dangle";
unlink (dangling_symlink);
if (symlink ("conftest.no-such", dangling_symlink))
abort ();
/* Exit successfully on a conforming system,
i.e., where chown must fail with ENOENT. */
if (chown (dangling_symlink, getuid (), getgid ()) == 0)
result |= 1;
if (errno != ENOENT)
result |= 2;
return result;
}
]])],
[gl_cv_func_chown_follows_symlink=yes],
[gl_cv_func_chown_follows_symlink=no],
[gl_cv_func_chown_follows_symlink="guessing yes"]
)
]
)
case "$gl_cv_func_chown_follows_symlink" in
*yes) ;;
*)
AC_DEFINE([CHOWN_MODIFIES_SYMLINK], [1],
[Define if chown modifies symlinks.])
;;
esac
])