1 /* Return the canonical absolute name of a given file.
2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
20 /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
21 optimizes away the name == NULL test below. */
22 # define _GL_ARG_NONNULL(params)
24 # include <libc-config.h>
38 #include <eloop-threshold.h>
42 #include <scratch_buffer.h>
45 # include <shlib-compat.h>
47 # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
49 # define __canonicalize_file_name canonicalize_file_name
50 # define __realpath realpath
52 # define __faccessat faccessat
53 # if defined _WIN32 && !defined __CYGWIN__
54 # define __getcwd _getcwd
57 /* When building the relocatable program wrapper, use the system's getcwd
58 function, not the gnulib override, otherwise we would get a link error.
62 # if defined VMS && !defined getcwd
63 /* We want the directory in Unix syntax, not in VMS syntax.
64 The gnulib override of 'getcwd' takes 2 arguments; the original VMS
65 'getcwd' takes 3 arguments. */
66 # define __getcwd(buf, max) getcwd (buf, max, 0)
68 # define __getcwd getcwd
71 # define __getcwd(buf, max) getwd (buf)
73 # define __mempcpy mempcpy
74 # define __pathconf pathconf
75 # define __rawmemchr rawmemchr
76 # define __readlink readlink
79 /* When building the relocatable program wrapper, use the system's memmove
80 function, not the gnulib override, otherwise we would get a link error.
86 /* Suppress bogus GCC -Wmaybe-uninitialized warnings. */
87 #if defined GCC_LINT || defined lint
88 # define IF_LINT(Code) Code
90 # define IF_LINT(Code) /* empty */
93 #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
94 # define DOUBLE_SLASH_IS_DISTINCT_ROOT false
97 #if defined _LIBC || !FUNC_REALPATH_WORKS
99 /* Return true if FILE's existence can be shown, false (setting errno)
100 otherwise. Follow symbolic links. */
102 file_accessible (char const *file)
104 # if defined _LIBC || HAVE_FACCESSAT
105 return __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0;
108 return __stat (file, &st) == 0 || errno == EOVERFLOW;
112 /* True if concatenating END as a suffix to a file name means that the
113 code needs to check that the file name is that of a searchable
114 directory, since the canonicalize_filename_mode_stk code won't
115 check this later anyway when it checks an ordinary file name
116 component within END. END must either be empty, or start with a
119 static bool _GL_ATTRIBUTE_PURE
120 suffix_requires_dir_check (char const *end)
122 /* If END does not start with a slash, the suffix is OK. */
123 while (ISSLASH (*end))
125 /* Two or more slashes act like a single slash. */
128 while (ISSLASH (*end));
132 default: return false; /* An ordinary file name component is OK. */
133 case '\0': return true; /* Trailing "/" is trouble. */
134 case '.': break; /* Possibly "." or "..". */
136 /* Trailing "/.", or "/.." even if not trailing, is trouble. */
137 if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1]))))
144 /* Append this to a file name to test whether it is a searchable directory.
145 On POSIX platforms "/" suffices, but "/./" is sometimes needed on
146 macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on
147 platforms like AIX 7.2 that need at least "/.". */
149 # if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
150 static char const dir_suffix[] = "/";
152 static char const dir_suffix[] = "/./";
155 /* Return true if DIR is a searchable dir, false (setting errno) otherwise.
156 DIREND points to the NUL byte at the end of the DIR string.
157 Store garbage into DIREND[0 .. strlen (dir_suffix)]. */
160 dir_check (char *dir, char *dirend)
162 strcpy (dirend, dir_suffix);
163 return file_accessible (dir);
170 long int path_max = PATH_MAX;
172 /* The caller invoked realpath with a null RESOLVED, even though
173 PATH_MAX is not defined as a constant. The glibc manual says
174 programs should not do this, and POSIX says the behavior is undefined.
175 Historically, glibc here used the result of pathconf, or 1024 if that
176 failed; stay consistent with this (dubious) historical practice. */
178 long int path_max = __pathconf ("/", _PC_PATH_MAX);
181 return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX;
184 /* Act like __realpath (see below), with an additional argument
185 rname_buf that can be used as temporary storage.
187 If GCC_LINT is defined, do not inline this function with GCC 10.1
188 and later, to avoid creating a pointer to the stack that GCC
189 -Wreturn-local-addr incorrectly complains about. See:
190 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644
191 Although the noinline attribute can hurt performance a bit, no better way
192 to pacify GCC is known; even an explicit #pragma does not pacify GCC.
193 When the GCC bug is fixed this workaround should be limited to the
194 broken GCC versions. */
195 # if __GNUC_PREREQ (10, 1)
196 # if defined GCC_LINT || defined lint
197 __attribute__ ((__noinline__))
198 # elif __OPTIMIZE__ && !__NO_INLINE__
199 # define GCC_BOGUS_WRETURN_LOCAL_ADDR
203 realpath_stk (const char *name, char *resolved,
204 struct scratch_buffer *rname_buf)
213 /* As per Single Unix Specification V2 we must return an error if
214 either parameter is a null pointer. We extend this to allow
215 the RESOLVED parameter to be NULL in case the we are expected to
216 allocate the room for the return value. */
217 __set_errno (EINVAL);
223 /* As per Single Unix Specification V2 we must return an error if
224 the name argument points to an empty string. */
225 __set_errno (ENOENT);
229 struct scratch_buffer extra_buffer, link_buffer;
230 scratch_buffer_init (&extra_buffer);
231 scratch_buffer_init (&link_buffer);
232 scratch_buffer_init (rname_buf);
233 char *rname_on_stack = rname_buf->data;
234 char *rname = rname_on_stack;
235 bool end_in_extra_buffer = false;
238 /* This is always zero for Posix hosts, but can be 2 for MS-Windows
239 and MS-DOS X:/foo/bar file names. */
240 idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
242 if (!IS_ABSOLUTE_FILE_NAME (name))
244 while (!__getcwd (rname, rname_buf->length))
251 if (!scratch_buffer_grow (rname_buf))
253 rname = rname_buf->data;
255 dest = __rawmemchr (rname, '\0');
257 prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
261 dest = __mempcpy (rname, name, prefix_len);
263 if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
265 if (prefix_len == 0 /* implies ISSLASH (name[0]) */
266 && ISSLASH (name[1]) && !ISSLASH (name[2]))
270 start = name + prefix_len;
273 for ( ; *start; start = end)
275 /* Skip sequence of multiple file name separators. */
276 while (ISSLASH (*start))
279 /* Find end of component. */
280 for (end = start; *end && !ISSLASH (*end); ++end)
283 /* Length of this file name component; it can be zero if a file
285 idx_t startlen = end - start;
289 else if (startlen == 1 && start[0] == '.')
291 else if (startlen == 2 && start[0] == '.' && start[1] == '.')
293 /* Back up to previous component, ignore if at root already. */
294 if (dest > rname + prefix_len + 1)
295 for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
297 if (DOUBLE_SLASH_IS_DISTINCT_ROOT
298 && dest == rname + 1 && !prefix_len
299 && ISSLASH (*dest) && !ISSLASH (dest[1]))
304 if (!ISSLASH (dest[-1]))
307 while (rname + rname_buf->length - dest
308 < startlen + sizeof dir_suffix)
310 idx_t dest_offset = dest - rname;
311 if (!scratch_buffer_grow_preserve (rname_buf))
313 rname = rname_buf->data;
314 dest = rname + dest_offset;
317 dest = __mempcpy (dest, start, startlen);
324 buf = link_buffer.data;
325 idx_t bufsize = link_buffer.length;
326 n = __readlink (rname, buf, bufsize - 1);
329 if (!scratch_buffer_grow (&link_buffer))
334 if (++num_links > __eloop_threshold ())
342 char *extra_buf = extra_buffer.data;
343 idx_t end_idx IF_LINT (= 0);
344 if (end_in_extra_buffer)
345 end_idx = end - extra_buf;
346 size_t len = strlen (end);
347 if (INT_ADD_OVERFLOW (len, n))
349 __set_errno (ENOMEM);
352 while (extra_buffer.length <= len + n)
354 if (!scratch_buffer_grow_preserve (&extra_buffer))
356 extra_buf = extra_buffer.data;
358 if (end_in_extra_buffer)
359 end = extra_buf + end_idx;
361 /* Careful here, end may be a pointer into extra_buf... */
362 memmove (&extra_buf[n], end, len + 1);
363 name = end = memcpy (extra_buf, buf, n);
364 end_in_extra_buffer = true;
366 if (IS_ABSOLUTE_FILE_NAME (buf))
368 idx_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
370 dest = __mempcpy (rname, buf, pfxlen);
371 *dest++ = '/'; /* It's an absolute symlink */
372 if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
374 if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
378 /* Install the new prefix to be in effect hereafter. */
383 /* Back up to previous component, ignore if at root
385 if (dest > rname + prefix_len + 1)
386 for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
388 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
389 && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
393 else if (! (suffix_requires_dir_check (end)
394 ? dir_check (rname, dest)
399 if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
401 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
402 && ISSLASH (*dest) && !ISSLASH (dest[1]))
408 if (resolved != NULL && dest - rname <= get_path_max ())
409 rname = strcpy (resolved, rname);
412 scratch_buffer_free (&extra_buffer);
413 scratch_buffer_free (&link_buffer);
415 if (failed || rname == resolved)
417 scratch_buffer_free (rname_buf);
418 return failed ? NULL : resolved;
421 return scratch_buffer_dupfree (rname_buf, dest - rname);
424 /* Return the canonical absolute name of file NAME. A canonical name
425 does not contain any ".", ".." components nor any repeated file name
426 separators ('/') or symlinks. All file name components must exist. If
427 RESOLVED is null, the result is malloc'd; otherwise, if the
428 canonical name is PATH_MAX chars or more, returns null with 'errno'
429 set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
430 returns the name in RESOLVED. If the name cannot be resolved and
431 RESOLVED is non-NULL, it contains the name of the first component
432 that cannot be resolved. If the name can be resolved, RESOLVED
433 holds the same value as the value returned. */
436 __realpath (const char *name, char *resolved)
438 #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR
439 #warning "GCC might issue a bogus -Wreturn-local-addr warning here."
440 #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>."
442 struct scratch_buffer rname_buffer;
443 return realpath_stk (name, resolved, &rname_buffer);
445 libc_hidden_def (__realpath)
446 versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
448 #endif /* defined _LIBC || !FUNC_REALPATH_WORKS */
451 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
453 attribute_compat_text_section
454 __old_realpath (const char *name, char *resolved)
456 if (resolved == NULL)
458 __set_errno (EINVAL);
462 return __realpath (name, resolved);
464 compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0);
469 __canonicalize_file_name (const char *name)
471 return __realpath (name, NULL);
473 weak_alias (__canonicalize_file_name, canonicalize_file_name)