diff --git a/src/skel/wiiu/realpath.c b/src/skel/wiiu/realpath.c index 46563c46..5fa4c97d 100644 --- a/src/skel/wiiu/realpath.c +++ b/src/skel/wiiu/realpath.c @@ -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 - . */ -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 \ No newline at end of file