1# serial 33
2
3# Copyright (C) 2001, 2003, 2005-2006, 2009-2022 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 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
79
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
135
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;
159
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;
166
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
208
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
255])
256