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