annotate lib/canonicalize.c @ 40057:b06060465f09

maint: Run 'make update-copyright'
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 01 Jan 2019 00:25:11 +0100
parents 10eb9086bea0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
1 /* Return the canonical absolute name of a given file.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
2 Copyright (C) 1996-2019 Free Software Foundation, Inc.
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
3
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9233
diff changeset
4 This program is free software: you can redistribute it and/or modify
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9233
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9233
diff changeset
7 (at your option) any later version.
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
8
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
12 GNU General Public License for more details.
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
13
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 19028
diff changeset
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
16
7302
8a1a9361108c * _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents: 6275
diff changeset
17 #include <config.h>
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
18
5866
d284693d309c * lib/canonicalize.c: Include canonicalize.h first, to test interface.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
19 #include "canonicalize.h"
d284693d309c * lib/canonicalize.c: Include canonicalize.h first, to test interface.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
20
12012
556a7580132e canonicalize: avoid resolvepath
Eric Blake <ebb9@byu.net>
parents: 12011
diff changeset
21 #include <errno.h>
6275
fd0ccce602e4 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5907
diff changeset
22 #include <stdlib.h>
fd0ccce602e4 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5907
diff changeset
23 #include <string.h>
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
24 #include <sys/stat.h>
6275
fd0ccce602e4 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5907
diff changeset
25 #include <unistd.h>
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
26
12010
e5fd78d17104 canonicalize: simplify errno handling
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
27 #include "areadlink.h"
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
28 #include "file-set.h"
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
29 #include "hash-triple.h"
12010
e5fd78d17104 canonicalize: simplify errno handling
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
30 #include "pathmax.h"
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
31 #include "xalloc.h"
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
32 #include "xgetcwd.h"
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
33 #include "dosname.h"
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
34
16193
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
35 #define MULTIPLE_BITS_SET(i) (((i) & ((i) - 1)) != 0)
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
36
15496
451ec8bd8a1c pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
37 /* In this file, we cannot handle file names longer than PATH_MAX.
451ec8bd8a1c pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
38 On systems with no file name length limit, use a fallback. */
451ec8bd8a1c pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
39 #ifndef PATH_MAX
451ec8bd8a1c pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
40 # define PATH_MAX 8192
451ec8bd8a1c pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
41 #endif
451ec8bd8a1c pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
42
12019
4e6951cd4f33 canonicalize, canonicalize-lgpl: honor // if distinct from /
Eric Blake <ebb9@byu.net>
parents: 12018
diff changeset
43 #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
4e6951cd4f33 canonicalize, canonicalize-lgpl: honor // if distinct from /
Eric Blake <ebb9@byu.net>
parents: 12018
diff changeset
44 # define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
4e6951cd4f33 canonicalize, canonicalize-lgpl: honor // if distinct from /
Eric Blake <ebb9@byu.net>
parents: 12018
diff changeset
45 #endif
4e6951cd4f33 canonicalize, canonicalize-lgpl: honor // if distinct from /
Eric Blake <ebb9@byu.net>
parents: 12018
diff changeset
46
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
47 #if ISSLASH ('\\')
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
48 # define SLASHES "/\\"
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
49 #else
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
50 # define SLASHES "/"
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
51 #endif
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
52
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
53 #if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS) \
12018
586fda772b8f canonicalize-lgpl: fix glibc bug with trailing slash
Eric Blake <ebb9@byu.net>
parents: 12012
diff changeset
54 || GNULIB_CANONICALIZE_LGPL)
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
55 /* Return the canonical absolute name of file NAME. A canonical name
16235
18a38c9615f0 In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents: 16208
diff changeset
56 does not contain any ".", ".." components nor any repeated file name
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
57 separators ('/') or symlinks. All components must exist.
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
58 The result is malloc'd. */
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
59
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
60 char *
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
61 canonicalize_file_name (const char *name)
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
62 {
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
63 return canonicalize_filename_mode (name, CAN_EXISTING);
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
64 }
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
65 #endif /* !HAVE_CANONICALIZE_FILE_NAME */
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
66
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
67 /* Return true if we've already seen the triple, <FILENAME, dev, ino>.
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
68 If *HT is not initialized, initialize it. */
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
69 static bool
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
70 seen_triple (Hash_table **ht, char const *filename, struct stat const *st)
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
71 {
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
72 if (*ht == NULL)
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
73 {
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
74 size_t initial_capacity = 7;
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
75 *ht = hash_initialize (initial_capacity,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
76 NULL,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
77 triple_hash,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
78 triple_compare_ino_str,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
79 triple_free);
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
80 if (*ht == NULL)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
81 xalloc_die ();
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
82 }
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
83
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
84 if (seen_file (*ht, filename, st))
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
85 return true;
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
86
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
87 record_file (*ht, filename, st);
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
88 return false;
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
89 }
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
90
12012
556a7580132e canonicalize: avoid resolvepath
Eric Blake <ebb9@byu.net>
parents: 12011
diff changeset
91 /* Return the canonical absolute name of file NAME, while treating
556a7580132e canonicalize: avoid resolvepath
Eric Blake <ebb9@byu.net>
parents: 12011
diff changeset
92 missing elements according to CAN_MODE. A canonical name
16235
18a38c9615f0 In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents: 16208
diff changeset
93 does not contain any ".", ".." components nor any repeated file name
16208
b9e251ade13d canonicalize: Tweak 2011-12-29 commit.
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
94 separators ('/') or, depending on other CAN_MODE flags, symlinks.
16193
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
95 Whether components must exist or not depends on canonicalize mode.
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
96 The result is malloc'd. */
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
97
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
98 char *
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
99 canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode)
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
100 {
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
101 char *rname, *dest, *extra_buf = NULL;
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
102 char const *start;
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
103 char const *end;
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
104 char const *rname_limit;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
105 size_t extra_len = 0;
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
106 Hash_table *ht = NULL;
12011
d8660f7d216a canonicalize: don't lose errno
Eric Blake <ebb9@byu.net>
parents: 12010
diff changeset
107 int saved_errno;
16193
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
108 int can_flags = can_mode & ~CAN_MODE_MASK;
17131
21634d7a1e29 canonicalize: fix C89 compilation
Pádraig Brady <P@draigBrady.com>
parents: 16357
diff changeset
109 bool logical = can_flags & CAN_NOLINKS;
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
110 size_t prefix_len;
17131
21634d7a1e29 canonicalize: fix C89 compilation
Pádraig Brady <P@draigBrady.com>
parents: 16357
diff changeset
111
16193
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
112 can_mode &= CAN_MODE_MASK;
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
113
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
114 if (MULTIPLE_BITS_SET (can_mode))
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
115 {
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
116 errno = EINVAL;
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
117 return NULL;
0b2b4b60945f canonicalize: add support for not resolving symlinks
Pádraig Brady <P@draigBrady.com>
parents: 15496
diff changeset
118 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
119
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
120 if (name == NULL)
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
121 {
12010
e5fd78d17104 canonicalize: simplify errno handling
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
122 errno = EINVAL;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
123 return NULL;
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
124 }
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
125
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
126 if (name[0] == '\0')
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
127 {
12010
e5fd78d17104 canonicalize: simplify errno handling
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
128 errno = ENOENT;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
129 return NULL;
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
130 }
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
131
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
132 /* This is always zero for Posix hosts, but can be 2 for MS-Windows
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
133 and MS-DOS X:/foo/bar file names. */
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
134 prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
135
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
136 if (!IS_ABSOLUTE_FILE_NAME (name))
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
137 {
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
138 rname = xgetcwd ();
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
139 if (!rname)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
140 return NULL;
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
141 dest = strchr (rname, '\0');
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
142 if (dest - rname < PATH_MAX)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
143 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
144 char *p = xrealloc (rname, PATH_MAX);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
145 dest = p + (dest - rname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
146 rname = p;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
147 rname_limit = rname + PATH_MAX;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
148 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
149 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
150 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
151 rname_limit = dest;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
152 }
17203
60ac4a074708 canonicalize, canonicalize-lgpl: Microsoft Windows prefix fixes
Eli Zaretskii <eliz@gnu.org>
parents: 17161
diff changeset
153 start = name;
60ac4a074708 canonicalize, canonicalize-lgpl: Microsoft Windows prefix fixes
Eli Zaretskii <eliz@gnu.org>
parents: 17161
diff changeset
154 prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
155 }
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
156 else
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
157 {
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
158 rname = xmalloc (PATH_MAX);
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
159 rname_limit = rname + PATH_MAX;
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
160 dest = rname;
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
161 if (prefix_len)
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
162 {
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
163 memcpy (rname, name, prefix_len);
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
164 dest += prefix_len;
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
165 }
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
166 *dest++ = '/';
16357
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
167 if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
168 {
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
169 if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
16357
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
170 *dest++ = '/';
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
171 *dest = '\0';
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
172 }
17203
60ac4a074708 canonicalize, canonicalize-lgpl: Microsoft Windows prefix fixes
Eli Zaretskii <eliz@gnu.org>
parents: 17161
diff changeset
173 start = name + prefix_len;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
174 }
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
175
17203
60ac4a074708 canonicalize, canonicalize-lgpl: Microsoft Windows prefix fixes
Eli Zaretskii <eliz@gnu.org>
parents: 17161
diff changeset
176 for ( ; *start; start = end)
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
177 {
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
178 /* Skip sequence of multiple file name separators. */
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
179 while (ISSLASH (*start))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
180 ++start;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
181
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
182 /* Find end of component. */
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
183 for (end = start; *end && !ISSLASH (*end); ++end)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
184 /* Nothing. */;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
185
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
186 if (end - start == 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
187 break;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
188 else if (end - start == 1 && start[0] == '.')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
189 /* nothing */;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
190 else if (end - start == 2 && start[0] == '.' && start[1] == '.')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
191 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
192 /* Back up to previous component, ignore if at root already. */
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
193 if (dest > rname + prefix_len + 1)
17203
60ac4a074708 canonicalize, canonicalize-lgpl: Microsoft Windows prefix fixes
Eli Zaretskii <eliz@gnu.org>
parents: 17161
diff changeset
194 for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
195 continue;
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
196 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
197 && !prefix_len && ISSLASH (*dest) && !ISSLASH (dest[1]))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
198 dest++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
199 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
200 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
201 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
202 struct stat st;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
203
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
204 if (!ISSLASH (dest[-1]))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
205 *dest++ = '/';
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
206
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
207 if (dest + (end - start) >= rname_limit)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
208 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
209 ptrdiff_t dest_offset = dest - rname;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
210 size_t new_size = rname_limit - rname;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
211
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
212 if (end - start + 1 > PATH_MAX)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
213 new_size += end - start + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
214 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
215 new_size += PATH_MAX;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
216 rname = xrealloc (rname, new_size);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
217 rname_limit = rname + new_size;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
218
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
219 dest = rname + dest_offset;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
220 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
221
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
222 dest = memcpy (dest, start, end - start);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
223 dest += end - start;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
224 *dest = '\0';
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
225
16199
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
226 if (logical && (can_mode == CAN_MISSING))
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
227 {
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
228 /* Avoid the stat in this case as it's inconsequential.
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
229 i.e. we're neither resolving symlinks or testing
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
230 component existence. */
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
231 st.st_mode = 0;
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
232 }
162e917fdda6 canonicalize: only stat() when required
Pádraig Brady <P@draigBrady.com>
parents: 16196
diff changeset
233 else if ((logical ? stat (rname, &st) : lstat (rname, &st)) != 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
234 {
19028
6d6cf502b0a6 canonicalize: fix EOVERFLOW commentary
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
235 /* FIXME: If errno == EOVERFLOW here, the entry exists. */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
236 saved_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
237 if (can_mode == CAN_EXISTING)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
238 goto error;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
239 if (can_mode == CAN_ALL_BUT_LAST)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
240 {
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
241 if (end[strspn (end, SLASHES)] || saved_errno != ENOENT)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
242 goto error;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
243 continue;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
244 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
245 st.st_mode = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
246 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
247
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
248 if (S_ISLNK (st.st_mode))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
249 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
250 char *buf;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
251 size_t n, len;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
252
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
253 /* Detect loops. We cannot use the cycle-check module here,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
254 since it's actually possible to encounter the same symlink
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
255 more than once in a given traversal. However, encountering
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
256 the same symlink,NAME pair twice does indicate a loop. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
257 if (seen_triple (&ht, name, &st))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
258 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
259 if (can_mode == CAN_MISSING)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
260 continue;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
261 saved_errno = ELOOP;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
262 goto error;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
263 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
264
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
265 buf = areadlink_with_size (rname, st.st_size);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
266 if (!buf)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
267 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
268 if (can_mode == CAN_MISSING && errno != ENOMEM)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
269 continue;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
270 saved_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
271 goto error;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
272 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
273
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
274 n = strlen (buf);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
275 len = strlen (end);
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
276
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
277 if (!extra_len)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
278 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
279 extra_len =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
280 ((n + len + 1) > PATH_MAX) ? (n + len + 1) : PATH_MAX;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
281 extra_buf = xmalloc (extra_len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
282 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
283 else if ((n + len + 1) > extra_len)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
284 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
285 extra_len = n + len + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
286 extra_buf = xrealloc (extra_buf, extra_len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
287 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
288
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
289 /* Careful here, end may be a pointer into extra_buf... */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
290 memmove (&extra_buf[n], end, len + 1);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
291 name = end = memcpy (extra_buf, buf, n);
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
292
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
293 if (IS_ABSOLUTE_FILE_NAME (buf))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
294 {
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
295 size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
296
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
297 if (pfxlen)
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
298 memcpy (rname, buf, pfxlen);
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
299 dest = rname + pfxlen;
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
300 *dest++ = '/'; /* It's an absolute symlink */
16357
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
301 if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
302 {
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
303 if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
16357
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
304 *dest++ = '/';
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
305 *dest = '\0';
fb977cbd79e9 canonicalize: avoid uninitialized memory use
Eric Blake <eblake@redhat.com>
parents: 16351
diff changeset
306 }
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
307 /* Install the new prefix to be in effect hereafter. */
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
308 prefix_len = pfxlen;
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
309 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
310 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
311 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
312 /* Back up to previous component, ignore if at root
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
313 already: */
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
314 if (dest > rname + prefix_len + 1)
17203
60ac4a074708 canonicalize, canonicalize-lgpl: Microsoft Windows prefix fixes
Eli Zaretskii <eliz@gnu.org>
parents: 17161
diff changeset
315 for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
316 continue;
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
317 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
318 && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
319 dest++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
320 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
321
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
322 free (buf);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
323 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
324 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
325 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
326 if (!S_ISDIR (st.st_mode) && *end && (can_mode != CAN_MISSING))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
327 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
328 saved_errno = ENOTDIR;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
329 goto error;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
330 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
331 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12020
diff changeset
332 }
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
333 }
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
334 if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
335 --dest;
17161
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
336 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
a111021312db canonicalize, canonicalize-lgpl: support MS-Windows file names
Eli Zaretskii <eliz@gnu.org>
parents: 17131
diff changeset
337 && ISSLASH (*dest) && !ISSLASH (dest[1]))
12019
4e6951cd4f33 canonicalize, canonicalize-lgpl: honor // if distinct from /
Eric Blake <ebb9@byu.net>
parents: 12018
diff changeset
338 dest++;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
339 *dest = '\0';
12461
673d93dccba1 canonicalize: reduce memory usage
Eric Blake <ebb9@byu.net>
parents: 12421
diff changeset
340 if (rname_limit != dest + 1)
673d93dccba1 canonicalize: reduce memory usage
Eric Blake <ebb9@byu.net>
parents: 12421
diff changeset
341 rname = xrealloc (rname, dest - rname + 1);
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
342
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
343 free (extra_buf);
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
344 if (ht)
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
345 hash_free (ht);
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
346 return rname;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
347
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
348 error:
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
349 free (extra_buf);
5907
c47674a83a78 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5866
diff changeset
350 free (rname);
9227
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
351 if (ht)
484ada1ccebf canonicalize: Avoid a false-positive cycle failure.
Jim Meyering <jim@meyering.net>
parents: 9169
diff changeset
352 hash_free (ht);
12011
d8660f7d216a canonicalize: don't lose errno
Eric Blake <ebb9@byu.net>
parents: 12010
diff changeset
353 errno = saved_errno;
5131
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
354 return NULL;
5ae20cfe1a13 New module, from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
355 }