Use newlib's realpath

This commit is contained in:
GaryOderNichts 2020-12-25 16:25:18 +01:00
parent 162e16fd8e
commit 7b16db25f9

View File

@ -17,140 +17,71 @@ char *_getcwd (char *__buf, size_t __size)
if (!ret)
return NULL;
strcpy(__buf, buf + 3);
// remove a '/' at the end
if (__buf[strlen(__buf)-1] == '/') __buf[strlen(__buf)-1] = '\0';
// remove a '/' at the end
if (__buf[strlen(__buf)-1] == '/') __buf[strlen(__buf)-1] = '\0';
return __buf;
}
/* Return the canonical absolute name of a given file.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
char *realpath(const char *name, char *resolved)
/* realpath.c - Return the canonicalized absolute pathname
* Written 2000 by Werner Almesberger
*
* Canonical name: never ends with a slash
*/
static int resolve_path(char *path,char *result,char *pos)
{
char *rpath, *dest = NULL;
const char *start, *end, *rpath_limit;
long int path_max;
if (*path == '/') {
*result = '/';
pos = result+1;
path++;
}
*pos = 0;
if (!*path) return 0;
while (1) {
char *slash;
struct stat st;
/* As per Single Unix Specification V2 we must return an error if
either parameter is a null pointer. We extend this to allow
the RESOLVED parameter to be NULL in case the we are expected to
allocate the room for the return value. */
if (!name)
return NULL;
slash = *path ? strchr(path,'/') : NULL;
if (slash) *slash = 0;
if (!path[0] || (path[0] == '.' &&
(!path[1] || (path[1] == '.' && !path[2])))) {
pos--;
if (pos != result && path[0] && path[1])
while (*--pos != '/');
}
else {
strcpy(pos,path);
pos = strchr(result,0);
}
if (slash) {
*pos++ = '/';
path = slash+1;
}
*pos = 0;
if (!slash) break;
}
return 0;
}
/* As per Single Unix Specification V2 we must return an error if
the name argument points to an empty string. */
if (name[0] == '\0')
return NULL;
path_max = PATH_MAX;
char *realpath(const char *__restrict path,char *__restrict resolved_path)
{
char cwd[PATH_MAX];
char *path_copy;
int res;
if (!resolved)
{
rpath = malloc(path_max);
if (!rpath)
return NULL;
}
else
rpath = resolved;
rpath_limit = rpath + path_max;
if (name[0] != '/')
{
if (!_getcwd(rpath, path_max))
{
rpath[0] = '\0';
goto error;
}
dest = memchr(rpath, '\0', path_max);
}
else
{
rpath[0] = '/';
dest = rpath + 1;
}
for (start = end = name; *start; start = end)
{
/* Skip sequence of multiple path-separators. */
while (*start == '/')
++start;
/* Find end of path component. */
for (end = start; *end && *end != '/'; ++end)
/* Nothing. */;
if (end - start == 0)
break;
else if (end - start == 1 && start[0] == '.')
/* nothing */;
else if (end - start == 2 && start[0] == '.' && start[1] == '.')
{
/* Back up to previous component, ignore if at root already. */
if (dest > rpath + 1)
while ((--dest)[-1] != '/')
;
}
else
{
size_t new_size;
if (dest[-1] != '/')
*dest++ = '/';
if (dest + (end - start) >= rpath_limit)
{
ptrdiff_t dest_offset = dest - rpath;
char *new_rpath;
if (resolved)
{
if (dest > rpath + 1)
dest--;
*dest = '\0';
goto error;
}
new_size = rpath_limit - rpath;
if (end - start + 1 > path_max)
new_size += end - start + 1;
else
new_size += path_max;
new_rpath = (char *)realloc(rpath, new_size);
if (!new_rpath)
goto error;
rpath = new_rpath;
rpath_limit = rpath + new_size;
dest = rpath + dest_offset;
}
dest = memcpy(dest, start, end - start);
*dest = '\0';
}
}
if (dest > rpath + 1 && dest[-1] == '/')
--dest;
*dest = '\0';
return rpath;
error:
if (!resolved)
free(rpath);
return NULL;
if (!*path) {
errno = ENOENT; /* SUSv2 */
return NULL;
}
if (!_getcwd(cwd,sizeof(cwd))) return NULL;
strcpy(resolved_path,"/");
if (resolve_path(cwd,resolved_path,resolved_path)) return NULL;
strcat(resolved_path,"/");
path_copy = strdup(path);
if (!path_copy) return NULL;
res = resolve_path(path_copy,resolved_path,strchr(resolved_path,0));
free(path_copy);
if (res) return NULL;
return resolved_path;
}
#endif