NEWS.stable: log cherry-pick [8b18afa]->[c948e19] sys_select: Avoid a syntax error...
[gnulib.git] / m4 / chown.m4
1 # serial 25
2 # Determine whether we need the chown wrapper.
3
4 dnl Copyright (C) 1997-2001, 2003-2005, 2007, 2009-2011 Free Software
5 dnl Foundation, Inc.
6
7 dnl This file is free software; the Free Software Foundation
8 dnl gives unlimited permission to copy and/or distribute it,
9 dnl 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 AC_DEFUN_ONCE([gl_FUNC_CHOWN],
18 [
19   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
20   AC_REQUIRE([AC_TYPE_UID_T])
21   AC_REQUIRE([AC_FUNC_CHOWN])
22   AC_REQUIRE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK])
23   AC_CHECK_FUNCS_ONCE([chown fchown])
24
25   dnl mingw lacks chown altogether.
26   if test $ac_cv_func_chown = no; then
27     HAVE_CHOWN=0
28   else
29     dnl Some old systems treated chown like lchown.
30     if test $gl_cv_func_chown_follows_symlink = no; then
31       REPLACE_CHOWN=1
32     fi
33
34     dnl Some old systems tried to use uid/gid -1 literally.
35     if test $ac_cv_func_chown_works = no; then
36       AC_DEFINE([CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE], [1],
37         [Define if chown is not POSIX compliant regarding IDs of -1.])
38       REPLACE_CHOWN=1
39     fi
40
41     dnl Solaris 9 ignores trailing slash.
42     dnl FreeBSD 7.2 mishandles trailing slash on symlinks.
43     dnl Likewise for AIX 7.1.
44     AC_CACHE_CHECK([whether chown honors trailing slash],
45       [gl_cv_func_chown_slash_works],
46       [touch conftest.file && rm -f conftest.link
47        AC_RUN_IFELSE([AC_LANG_PROGRAM([[
48 #include <unistd.h>
49 #include <stdlib.h>
50 #include <errno.h>
51 ]], [[    if (symlink ("conftest.file", "conftest.link")) return 1;
52           if (chown ("conftest.link/", getuid (), getgid ()) == 0) return 2;
53         ]])],
54         [gl_cv_func_chown_slash_works=yes],
55         [gl_cv_func_chown_slash_works=no],
56         [gl_cv_func_chown_slash_works="guessing no"])
57       rm -f conftest.link conftest.file])
58     if test "$gl_cv_func_chown_slash_works" != yes; then
59       AC_DEFINE([CHOWN_TRAILING_SLASH_BUG], [1],
60         [Define to 1 if chown mishandles trailing slash.])
61       REPLACE_CHOWN=1
62     fi
63
64     dnl OpenBSD fails to update ctime if ownership does not change.
65     AC_CACHE_CHECK([whether chown always updates ctime],
66       [gl_cv_func_chown_ctime_works],
67       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
68 #include <unistd.h>
69 #include <stdlib.h>
70 #include <errno.h>
71 #include <fcntl.h>
72 #include <sys/stat.h>
73 ]], [[    struct stat st1, st2;
74           if (close (creat ("conftest.file", 0600))) return 1;
75           if (stat ("conftest.file", &st1)) return 2;
76           sleep (1);
77           if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3;
78           if (stat ("conftest.file", &st2)) return 4;
79           if (st2.st_ctime <= st1.st_ctime) return 5;
80         ]])],
81         [gl_cv_func_chown_ctime_works=yes],
82         [gl_cv_func_chown_ctime_works=no],
83         [gl_cv_func_chown_ctime_works="guessing no"])
84       rm -f conftest.file])
85     if test "$gl_cv_func_chown_ctime_works" != yes; then
86       AC_DEFINE([CHOWN_CHANGE_TIME_BUG], [1], [Define to 1 if chown fails
87         to change ctime when at least one argument was not -1.])
88       REPLACE_CHOWN=1
89     fi
90   fi
91 ])
92
93 # Determine whether chown follows symlinks (it should).
94 AC_DEFUN_ONCE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK],
95 [
96   AC_CACHE_CHECK(
97     [whether chown dereferences symlinks],
98     [gl_cv_func_chown_follows_symlink],
99     [
100       AC_RUN_IFELSE([AC_LANG_SOURCE([[
101 #include <unistd.h>
102 #include <stdlib.h>
103 #include <errno.h>
104
105         int
106         main ()
107         {
108           int result = 0;
109           char const *dangling_symlink = "conftest.dangle";
110
111           unlink (dangling_symlink);
112           if (symlink ("conftest.no-such", dangling_symlink))
113             abort ();
114
115           /* Exit successfully on a conforming system,
116              i.e., where chown must fail with ENOENT.  */
117           if (chown (dangling_symlink, getuid (), getgid ()) == 0)
118             result |= 1;
119           if (errno != ENOENT)
120             result |= 2;
121           return result;
122         }
123         ]])],
124         [gl_cv_func_chown_follows_symlink=yes],
125         [gl_cv_func_chown_follows_symlink=no],
126         [gl_cv_func_chown_follows_symlink=yes]
127       )
128     ]
129   )
130
131   if test $gl_cv_func_chown_follows_symlink = no; then
132     AC_DEFINE([CHOWN_MODIFIES_SYMLINK], [1],
133       [Define if chown modifies symlinks.])
134   fi
135 ])