Skip to content

Commit 898f505

Browse files
xdelatourth-otto
authored andcommitted
Sync realpath with glibc 2.32
1 parent cdc0965 commit 898f505

File tree

1 file changed

+38
-41
lines changed

1 file changed

+38
-41
lines changed

stdlib/canonicalize.c

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/* Return the canonical absolute name of a given file.
2-
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
2+
Copyright (C) 1996-2020 Free Software Foundation, Inc.
33
This file is part of the GNU C Library.
44
55
The GNU C Library is free software; you can redistribute it and/or
6-
modify it under the terms of the GNU Library General Public License as
7-
published by the Free Software Foundation; either version 2 of the
8-
License, or (at your option) any later version.
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
99
1010
The GNU C Library is distributed in the hope that it will be useful,
1111
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,27 +18,19 @@
1818

1919
/* Modified by Guido Flohr <guido@freemint.de> for MiNTLib. */
2020

21-
#include <errno.h>
22-
#include <limits.h>
2321
#include <stdlib.h>
2422
#include <string.h>
2523
#include <unistd.h>
24+
#include <limits.h>
2625
#include <sys/param.h>
2726
#include <sys/stat.h>
27+
#include <errno.h>
2828

2929
#ifdef __MINT__
3030
# define __lxstat(version, file, buf) __lstat(file, buf)
3131
# define _STAT_VER
3232
#endif
3333

34-
#if __GNUC_PREREQ(12,0)
35-
/*
36-
* we don't return a local addr;
37-
* rpath is either == resolved, or malloced
38-
*/
39-
#pragma GCC diagnostic ignored "-Wreturn-local-addr"
40-
#endif
41-
4234
/* Return the canonical absolute name of file NAME. A canonical name
4335
does not contain any `.', `..' components nor any repeated path
4436
separators ('/') or symlinks. All path components must exist. If
@@ -50,8 +42,10 @@
5042
that cannot be resolved. If the path can be resolved, RESOLVED
5143
holds the same value as the value returned. */
5244

53-
static char *
54-
canonicalize (const char *name, char *resolved)
45+
__typeof__(realpath) __realpath;
46+
47+
char *
48+
__realpath (const char *name, char *resolved)
5549
{
5650
char *rpath, *dest, *extra_buf = NULL;
5751
const char *start, *end, *rpath_limit;
@@ -84,13 +78,23 @@ canonicalize (const char *name, char *resolved)
8478
path_max = 1024;
8579
#endif
8680

87-
rpath = resolved ? alloca (path_max) : malloc (path_max);
81+
if (resolved == NULL)
82+
{
83+
rpath = malloc (path_max);
84+
if (rpath == NULL)
85+
return NULL;
86+
}
87+
else
88+
rpath = resolved;
8889
rpath_limit = rpath + path_max;
8990

9091
if (name[0] != '/' || name[0] == '\\')
9192
{
9293
if (!__getcwd (rpath, path_max))
94+
{
95+
rpath[0] = '\0';
9396
goto error;
97+
}
9498
dest = strchr (rpath, '\0');
9599
}
96100
else
@@ -132,21 +136,26 @@ canonicalize (const char *name, char *resolved)
132136
if (dest + (end - start) >= rpath_limit)
133137
{
134138
long dest_offset = dest - rpath;
139+
char *new_rpath;
135140

136141
if (resolved)
137142
{
138143
__set_errno (ENAMETOOLONG);
144+
if (dest > rpath +1)
145+
dest--;
146+
*dest = '\0';
139147
goto error;
140148
}
141149
new_size = rpath_limit - rpath;
142150
if (end - start + 1 > path_max)
143151
new_size += end - start + 1;
144152
else
145153
new_size += path_max;
146-
rpath = realloc (rpath, new_size);
154+
new_rpath = (char *)realloc (rpath, new_size);
155+
if (new_rpath == NULL)
156+
goto error;
157+
rpath = new_rpath;
147158
rpath_limit = rpath + new_size;
148-
if (rpath == NULL)
149-
return NULL;
150159

151160
dest = rpath + dest_offset;
152161
}
@@ -173,7 +182,7 @@ canonicalize (const char *name, char *resolved)
173182
goto error;
174183
}
175184

176-
n = __readlink (rpath, buf, path_max);
185+
n = __readlink (rpath, buf, path_max - 1);
177186
if (n < 0)
178187
goto error;
179188
buf[n] = '\0';
@@ -199,43 +208,31 @@ canonicalize (const char *name, char *resolved)
199208
if (dest > rpath + 1)
200209
while ((--dest)[-1] != '/' && dest[-1] != '\\');
201210
}
211+
else if (!S_ISDIR(st.st_mode) && *end != '\0')
212+
{
213+
__set_errno (ENOTDIR);
214+
goto error;
215+
}
202216
}
203217
}
204218
if (dest > rpath + 1 && (dest[-1] == '/' || dest[-1] == '\\'))
205219
--dest;
206220
*dest = '\0';
207221

208-
return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath;
222+
return rpath;
209223

210224
error:
211-
if (resolved)
212-
strcpy (resolved, rpath);
213-
else
225+
if (resolved == NULL)
214226
free (rpath);
215227
return NULL;
216228
}
217-
218-
219-
__typeof__(realpath) __realpath;
220-
221-
char *
222-
__realpath (const char *name, char *resolved)
223-
{
224-
if (resolved == NULL)
225-
{
226-
__set_errno (EINVAL);
227-
return NULL;
228-
}
229-
230-
return canonicalize (name, resolved);
231-
}
232229
weak_alias (__realpath, realpath)
233230

234231
__typeof__(canonicalize_file_name) __canonicalize_file_name;
235232

236233
char *
237234
__canonicalize_file_name (const char *name)
238235
{
239-
return canonicalize (name, NULL);
236+
return __realpath (name, NULL);
240237
}
241238
weak_alias (__canonicalize_file_name, canonicalize_file_name)

0 commit comments

Comments
 (0)