Quick and dirty malloc() support for realpath.
Mike Frysinger
vapier at gentoo.org
Wed Oct 28 08:01:52 UTC 2009
On Tuesday 27 October 2009 15:44:42 Rob Landley wrote:
> On Tuesday 27 October 2009 05:51:05 Bernhard Reutner-Fischer wrote:
> > On Tue, Oct 27, 2009 at 08:54:50AM +0100, Ricard Wanderlof wrote:
> > >On Mon, 26 Oct 2009, Rob Landley wrote:
> > >>... Also, in my experience _Bool is about as real-world useful as
> > >>the bit field notation with the colons, and is really there to keep
> > >>the language pedants and the c++ guys happy without actually
> > >>accomplishing much. I've never seen it actually produce better
> > >>code.
> > >
> > >It can produce more readable, less error-prone C code though. We use
> >
> > $ size libc/stdlib/realpath.o*
> > text data bss dec hex filename
> > 555 0 0 555 22b libc/stdlib/realpath.os.oorig
> > 735 0 0 735 2df libc/stdlib/realpath.os.rob
> > 586 0 0 586 24a libc/stdlib/realpath.os
> >
> > perhaps that would do as well and doesn't cost 180b (!) but about 31b..
>
> The problem is that leaks memory if realpath ever returns failure, such as
> the lines right after that patch:
our friend goto solves the leak. stick it in the middle of the file to
maximize short forward/backward jumps and we only get a small increase:
578 0 0 578 242 libc/stdlib/realpath.os.orig
609 0 0 609 261 libc/stdlib/realpath.os
diff --git a/libc/stdlib/realpath.c b/libc/stdlib/realpath.c
index 1a00c31..146d1d8 100644
--- a/libc/stdlib/realpath.c
+++ b/libc/stdlib/realpath.c
@@ -47,8 +47,7 @@ char got_path[];
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;
size_t path_len;
int readlinks = 0;
#ifdef S_IFLNK
@@ -72,12 +71,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);
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 +114,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 +124,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 +135,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 */
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.busybox.net/pipermail/uclibc/attachments/20091028/a8c6ec23/attachment.pgp>
More information about the uClibc
mailing list