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
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc