[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