[PATCH] realpath: SUSv4 compliant
Peter Kjellerstedt
peter.kjellerstedt at axis.com
Fri Nov 13 08:35:02 UTC 2009
> -----Original Message-----
> From: uclibc-bounces at uclibc.org [mailto:uclibc-bounces at uclibc.org] On Behalf Of Bernhard Reutner-Fischer
> Sent: den 12 november 2009 21:08
> To: uclibc at uclibc.org
> Subject: [PATCH] realpath: SUSv4 compliant
>
> Signed-off-by: Mike Frysinger <vapier at gentoo.org>
> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
> ---
> include/stdlib.h | 2 --
> libc/stdlib/realpath.c | 20 ++++++++------------
> 2 files changed, 8 insertions(+), 14 deletions(-)
>
> diff --git a/include/stdlib.h b/include/stdlib.h
> index e462c1c..3e9ceab 100644
> --- a/include/stdlib.h
> +++ b/include/stdlib.h
> @@ -659,7 +659,6 @@ extern char *canonicalize_file_name (__const char *__name)
> __THROW __nonnull ((1)) __wur;
> #endif
>
> -#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
> /* Return the canonical absolute name of file NAME. If RESOLVED is
> null, the result is malloc'd; otherwise, if the canonical name is
> PATH_MAX chars or more, returns null with `errno' set to
> @@ -668,7 +667,6 @@ extern char *canonicalize_file_name (__const char
> *__name)
> /* we choose to handle __resolved==NULL as crash :) */
> extern char *realpath (__const char *__restrict __name,
> char *__restrict __resolved) __THROW __wur
> __nonnull((2));
> -#endif
>
>
> /* Shorthand for type of comparison functions. */
> diff --git a/libc/stdlib/realpath.c b/libc/stdlib/realpath.c
> index 1a00c31..3c3a607 100644
> --- a/libc/stdlib/realpath.c
> +++ b/libc/stdlib/realpath.c
> @@ -36,19 +36,12 @@
>
> #define MAX_READLINKS 32
>
> -#ifdef __STDC__
> char *realpath(const char *path, char got_path[])
> -#else
> -char *realpath(path, got_path)
> -const char *path;
> -char got_path[];
> -#endif
> {
> char copy_path[PATH_MAX];
> /* use user supplied buffer directly - reduces stack usage */
> /* char got_path[PATH_MAX]; */
> - char *max_path;
> - char *new_path;
> + char *max_path, *new_path, *allocated_path;
Why aggregate multiple variables on one line?
I have always found that to be a bad idea(tm).
> size_t path_len;
> int readlinks = 0;
> #ifdef S_IFLNK
> @@ -72,12 +65,13 @@ char got_path[];
> /* Copy so that path is at the end of copy_path[] */
> strcpy(copy_path + (PATH_MAX-1) - path_len, path);
> path = copy_path + (PATH_MAX-1) - path_len;
> + allocated_path = got_path ? NULL : malloc(PATH_MAX);
I may be blind, but as far as I can tell you never use
allocated_path for anything (except freeing it)...
> max_path = got_path + PATH_MAX - 2; /* points to last non-NUL char */
> new_path = got_path;
> if (*path != '/') {
> /* If it's a relative pathname use getcwd for starters. */
> if (!getcwd(new_path, PATH_MAX - 1))
> - return NULL;
> + goto err;
> new_path += strlen(new_path);
> if (new_path[-1] != '/')
> *new_path++ = '/';
> @@ -114,6 +108,8 @@ char got_path[];
> while (*path != '\0' && *path != '/') {
> if (new_path > max_path) {
> __set_errno(ENAMETOOLONG);
> + err:
> + free(allocated_path);
> return NULL;
> }
> *new_path++ = *path++;
> @@ -122,7 +118,7 @@ char got_path[];
> /* Protect against infinite loops. */
> if (readlinks++ > MAX_READLINKS) {
> __set_errno(ELOOP);
> - return NULL;
> + goto err;
> }
> path_len = strlen(path);
> /* See if last (so far) pathname component is a symlink. */
> @@ -133,13 +129,13 @@ char got_path[];
> if (link_len < 0) {
> /* EINVAL means the file exists but isn't a symlink. */
> if (errno != EINVAL) {
> - return NULL;
> + goto err;
> }
> } else {
> /* Safe sex check. */
> if (path_len + link_len >= PATH_MAX - 2) {
> __set_errno(ENAMETOOLONG);
> - return NULL;
> + goto err;
> }
> /* Note: readlink doesn't add the null byte. */
> /* copy_path[link_len] = '\0'; - we don't need it too */
> --
> 1.6.3.3
>
> _______________________________________________
> uClibc mailing list
> uClibc at uclibc.org
> http://lists.busybox.net/mailman/listinfo/uclibc
//Peter
More information about the uClibc
mailing list