immutable: Add tests.
[gnulib.git] / m4 / rename.m4
blob8a95b8aee974a8dbf750dbe911580a787a6e5e96
1 # serial 33
3 # Copyright (C) 2001, 2003, 2005-2006, 2009-2021 Free Software Foundation, Inc.
4 # This file is free software; the Free Software Foundation
5 # gives unlimited permission to copy and/or distribute it,
6 # with or without modifications, as long as this notice is preserved.
8 dnl From Volker Borchert.
9 dnl Determine whether rename works for source file names with a trailing slash.
10 dnl The rename from SunOS 4.1.1_U1 doesn't.
11 dnl
12 dnl If it doesn't, then define RENAME_TRAILING_SLASH_BUG and arrange
13 dnl to compile the wrapper function.
14 dnl
16 AC_DEFUN([gl_FUNC_RENAME],
18   AC_REQUIRE([AC_CANONICAL_HOST])
19   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
20   AC_CHECK_FUNCS_ONCE([lstat])
22   dnl Solaris 11.3, AIX 7.1 mistakenly allow rename("file","name/").
23   dnl NetBSD 1.6 mistakenly forbids rename("dir","name/").
24   dnl FreeBSD 7.2 mistakenly allows rename("file","link-to-file/").
25   dnl The Solaris bug can be worked around without stripping
26   dnl trailing slash, while the NetBSD bug requires stripping;
27   dnl the two conditions can be distinguished by whether hard
28   dnl links are also broken.
29   AC_CACHE_CHECK([whether rename honors trailing slash on destination],
30     [gl_cv_func_rename_slash_dst_works],
31     [rm -rf conftest.f conftest.f1 conftest.f2 conftest.d1 conftest.d2 conftest.lnk
32     touch conftest.f && touch conftest.f1 && mkdir conftest.d1 ||
33       AC_MSG_ERROR([cannot create temporary files])
34     # Assume that if we have lstat, we can also check symlinks.
35     if test $ac_cv_func_lstat = yes; then
36       ln -s conftest.f conftest.lnk
37     fi
38     AC_RUN_IFELSE(
39       [AC_LANG_PROGRAM([[
40 #        include <stdio.h>
41 #        include <stdlib.h>
42          ]],
43          [[int result = 0;
44            if (rename ("conftest.f1", "conftest.f2/") == 0)
45              result |= 1;
46            if (rename ("conftest.d1", "conftest.d2/") != 0)
47              result |= 2;
48 #if HAVE_LSTAT
49            if (rename ("conftest.f", "conftest.lnk/") == 0)
50              result |= 4;
51 #endif
52            return result;
53          ]])],
54       [gl_cv_func_rename_slash_dst_works=yes],
55       [gl_cv_func_rename_slash_dst_works=no],
56       dnl When crosscompiling, assume rename is broken.
57       [case "$host_os" in
58                           # Guess yes on Linux systems.
59          linux-* | linux) gl_cv_func_rename_slash_dst_works="guessing yes" ;;
60                           # Guess yes on glibc systems.
61          *-gnu*)          gl_cv_func_rename_slash_dst_works="guessing yes" ;;
62                           # Guess no on native Windows.
63          mingw*)          gl_cv_func_rename_slash_dst_works="guessing no" ;;
64                           # If we don't know, obey --enable-cross-guesses.
65          *)               gl_cv_func_rename_slash_dst_works="$gl_cross_guess_normal" ;;
66        esac
67       ])
68     rm -rf conftest.f conftest.f1 conftest.f2 conftest.d1 conftest.d2 conftest.lnk
69   ])
70   case "$gl_cv_func_rename_slash_dst_works" in
71     *yes) ;;
72     *)
73       REPLACE_RENAME=1
74       AC_DEFINE([RENAME_TRAILING_SLASH_DEST_BUG], [1],
75         [Define if rename does not correctly handle slashes on the destination
76          argument, such as on Solaris 11 or NetBSD 1.6.])
77       ;;
78   esac
80   dnl SunOS 4.1.1_U1 mistakenly forbids rename("dir/","name").
81   dnl Solaris 9 mistakenly allows rename("file/","name").
82   dnl FreeBSD 7.2 mistakenly allows rename("link-to-file/","name").
83   dnl These bugs require stripping trailing slash to avoid corrupting
84   dnl symlinks with a trailing slash.
85   AC_CACHE_CHECK([whether rename honors trailing slash on source],
86     [gl_cv_func_rename_slash_src_works],
87     [rm -rf conftest.f conftest.f1 conftest.d1 conftest.d2 conftest.d3 conftest.lnk
88     touch conftest.f && touch conftest.f1 && mkdir conftest.d1 ||
89       AC_MSG_ERROR([cannot create temporary files])
90     # Assume that if we have lstat, we can also check symlinks.
91     if test $ac_cv_func_lstat = yes; then
92       ln -s conftest.f conftest.lnk
93     fi
94     AC_RUN_IFELSE(
95       [AC_LANG_PROGRAM([[
96 #        include <stdio.h>
97 #        include <stdlib.h>
98          ]],
99          [[int result = 0;
100            if (rename ("conftest.f1/", "conftest.d3") == 0)
101              result |= 1;
102            if (rename ("conftest.d1/", "conftest.d2") != 0)
103              result |= 2;
104 #if HAVE_LSTAT
105            if (rename ("conftest.lnk/", "conftest.f") == 0)
106              result |= 4;
107 #endif
108            return result;
109          ]])],
110       [gl_cv_func_rename_slash_src_works=yes],
111       [gl_cv_func_rename_slash_src_works=no],
112       dnl When crosscompiling, assume rename is broken.
113       [case "$host_os" in
114                           # Guess yes on Linux systems.
115          linux-* | linux) gl_cv_func_rename_slash_src_works="guessing yes" ;;
116                           # Guess yes on glibc systems.
117          *-gnu*)          gl_cv_func_rename_slash_src_works="guessing yes" ;;
118                           # Guess yes on native Windows.
119          mingw*)          gl_cv_func_rename_slash_src_works="guessing yes" ;;
120                           # If we don't know, obey --enable-cross-guesses.
121          *)               gl_cv_func_rename_slash_src_works="$gl_cross_guess_normal" ;;
122        esac
123       ])
124     rm -rf conftest.f conftest.f1 conftest.d1 conftest.d2 conftest.d3 conftest.lnk
125   ])
126   case "$gl_cv_func_rename_slash_src_works" in
127     *yes) ;;
128     *)
129       REPLACE_RENAME=1
130       AC_DEFINE([RENAME_TRAILING_SLASH_SOURCE_BUG], [1],
131         [Define if rename does not correctly handle slashes on the source
132          argument, such as on Solaris 9 or cygwin 1.5.])
133       ;;
134   esac
136   dnl NetBSD 1.6 and cygwin 1.5.x mistakenly reduce hard link count
137   dnl on rename("h1","h2").
138   dnl This bug requires stat'ting targets prior to attempting rename.
139   AC_CHECK_FUNCS_ONCE([link])
140   AC_CACHE_CHECK([whether rename manages hard links correctly],
141     [gl_cv_func_rename_link_works],
142     [if test $ac_cv_func_link = yes; then
143        if test $cross_compiling != yes; then
144          rm -rf conftest.f conftest.f1 conftest.f2
145          if touch conftest.f conftest.f2 && ln conftest.f conftest.f1 &&
146              set x `ls -i conftest.f conftest.f1` && test "$2" = "$4"; then
147            AC_RUN_IFELSE(
148              [AC_LANG_PROGRAM([[
149 #               include <errno.h>
150 #               include <stdio.h>
151 #               include <stdlib.h>
152 #               include <unistd.h>
153                 ]GL_MDA_DEFINES],
154                 [[int result = 0;
155                   if (rename ("conftest.f", "conftest.f1"))
156                     result |= 1;
157                   if (unlink ("conftest.f1"))
158                     result |= 2;
160                   /* Allow either the POSIX-required behavior, where the
161                      previous rename kept conftest.f, or the (better) NetBSD
162                      behavior, where it removed conftest.f.  */
163                   if (rename ("conftest.f", "conftest.f") != 0
164                       && errno != ENOENT)
165                     result |= 4;
167                   if (rename ("conftest.f1", "conftest.f1") == 0)
168                     result |= 8;
169                   if (rename ("conftest.f2", "conftest.f2") != 0)
170                     result |= 16;
171                   return result;
172                 ]])],
173              [gl_cv_func_rename_link_works=yes],
174              [gl_cv_func_rename_link_works=no],
175              [dnl We don't get here.
176               :
177              ])
178          else
179            gl_cv_func_rename_link_works="guessing no"
180          fi
181          rm -rf conftest.f conftest.f1 conftest.f2
182        else
183          dnl When crosscompiling, assume rename is broken.
184          case "$host_os" in
185                             # Guess yes on Linux systems.
186            linux-* | linux) gl_cv_func_rename_link_works="guessing yes" ;;
187                             # Guess yes on glibc systems.
188            *-gnu*)          gl_cv_func_rename_link_works="guessing yes" ;;
189                             # Guess yes on native Windows.
190            mingw*)          gl_cv_func_rename_link_works="guessing yes" ;;
191                             # If we don't know, obey --enable-cross-guesses.
192            *)               gl_cv_func_rename_link_works="$gl_cross_guess_normal" ;;
193          esac
194        fi
195      else
196        gl_cv_func_rename_link_works=yes
197      fi
198     ])
199   case "$gl_cv_func_rename_link_works" in
200     *yes) ;;
201     *)
202       REPLACE_RENAME=1
203       AC_DEFINE([RENAME_HARD_LINK_BUG], [1],
204         [Define if rename fails to leave hard links alone, as on NetBSD 1.6
205          or Cygwin 1.5.])
206       ;;
207   esac
209   dnl Cygwin 1.5.x mistakenly allows rename("dir","file").
210   dnl mingw mistakenly forbids rename("dir1","dir2").
211   dnl These bugs require stripping trailing slash to avoid corrupting
212   dnl symlinks with a trailing slash.
213   AC_CACHE_CHECK([whether rename manages existing destinations correctly],
214     [gl_cv_func_rename_dest_works],
215     [rm -rf conftest.f conftest.d1 conftest.d2
216     touch conftest.f && mkdir conftest.d1 conftest.d2 ||
217       AC_MSG_ERROR([cannot create temporary files])
218     AC_RUN_IFELSE(
219       [AC_LANG_PROGRAM([[
220 #        include <stdio.h>
221 #        include <stdlib.h>
222          ]],
223          [[int result = 0;
224            if (rename ("conftest.d1", "conftest.d2") != 0)
225              result |= 1;
226            if (rename ("conftest.d2", "conftest.f") == 0)
227              result |= 2;
228            return result;
229          ]])],
230       [gl_cv_func_rename_dest_works=yes],
231       [gl_cv_func_rename_dest_works=no],
232       dnl When crosscompiling, assume rename is broken.
233       [case "$host_os" in
234                           # Guess yes on Linux systems.
235          linux-* | linux) gl_cv_func_rename_dest_works="guessing yes" ;;
236                           # Guess yes on glibc systems.
237          *-gnu*)          gl_cv_func_rename_dest_works="guessing yes" ;;
238                           # Guess no on native Windows.
239          mingw*)          gl_cv_func_rename_dest_works="guessing no" ;;
240                           # If we don't know, obey --enable-cross-guesses.
241          *)               gl_cv_func_rename_dest_works="$gl_cross_guess_normal" ;;
242        esac
243       ])
244     rm -rf conftest.f conftest.d1 conftest.d2
245   ])
246   case "$gl_cv_func_rename_dest_works" in
247     *yes) ;;
248     *)
249       REPLACE_RENAME=1
250       AC_DEFINE([RENAME_DEST_EXISTS_BUG], [1],
251         [Define if rename does not work when the destination file exists,
252          as on Cygwin 1.5 or Windows.])
253       ;;
254   esac