Mercurial > gnulib
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 |
rev | line source |
---|---|
5131 | 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 | 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 | 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 | 8 |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
19190 | 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
5131 | 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 | 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 | 22 #include <stdlib.h> |
23 #include <string.h> | |
5131 | 24 #include <sys/stat.h> |
6275 | 25 #include <unistd.h> |
5131 | 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 | 31 #include "xalloc.h" |
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 | 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 | 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 | 57 separators ('/') or symlinks. All components must exist. |
5131 | 58 The result is malloc'd. */ |
59 | |
60 char * | |
61 canonicalize_file_name (const char *name) | |
62 { | |
63 return canonicalize_filename_mode (name, CAN_EXISTING); | |
64 } | |
65 #endif /* !HAVE_CANONICALIZE_FILE_NAME */ | |
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 | 97 |
98 char * | |
99 canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode) | |
100 { | |
5907 | 101 char *rname, *dest, *extra_buf = NULL; |
102 char const *start; | |
103 char const *end; | |
104 char const *rname_limit; | |
5131 | 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 | 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 | 119 |
120 if (name == NULL) | |
121 { | |
12010
e5fd78d17104
canonicalize: simplify errno handling
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
122 errno = EINVAL; |
5131 | 123 return NULL; |
124 } | |
125 | |
126 if (name[0] == '\0') | |
127 { | |
12010
e5fd78d17104
canonicalize: simplify errno handling
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
128 errno = ENOENT; |
5131 | 129 return NULL; |
130 } | |
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 | 137 { |
5907 | 138 rname = xgetcwd (); |
139 if (!rname) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12020
diff
changeset
|
140 return NULL; |
5907 | 141 dest = strchr (rname, '\0'); |
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 | 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 | 155 } |
156 else | |
157 { | |
5907 | 158 rname = xmalloc (PATH_MAX); |
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 | 174 } |
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 | 177 { |
5907 | 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 | 181 |
5907 | 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 | 185 |
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 342 |
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 | 346 return rname; |
5131 | 347 |
348 error: | |
349 free (extra_buf); | |
5907 | 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 | 353 errno = saved_errno; |
5131 | 354 return NULL; |
355 } |