diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2002-07-08 20:23:15 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2002-07-08 20:23:15 +0000 |
commit | 540d2586b028e26b0a325b13fd1d7266fb55fb3f (patch) | |
tree | 72e844e988e7b4d15826810e06f29457aeff5ede /lib | |
parent | e178384c643b5cedf2b78ca5bb2a81da886ccec0 (diff) |
Use qsort() instead of mergesort() since the latter can fail due
to malloc(). opendir() requires a stable sort so we rig the compare
routine to never return 0. From Lars J. Buitinck
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/gen/opendir.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c index dabafe3bfe1..d9dcb77306e 100644 --- a/lib/libc/gen/opendir.c +++ b/lib/libc/gen/opendir.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: opendir.c,v 1.6 1998/08/15 08:10:14 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: opendir.c,v 1.7 2002/07/08 20:23:14 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -46,6 +46,22 @@ static char rcsid[] = "$OpenBSD: opendir.c,v 1.6 1998/08/15 08:10:14 deraadt Exp #include <string.h> #include <unistd.h> +static int direntcmp(const void *, const void *); + +/* + * Comparison function for sorting dirent structures that never returns 0; + * this causes qsort() to emulate a stable sort. + */ +static int +direntcmp(const void *d1, const void *d2) +{ + int i; + + i = strcmp((*(struct dirent **)d1)->d_name, + (*(struct dirent **)d2)->d_name); + return (i != 0 ? i : (char *)d2 - (char *)d1); +} + /* * Open a directory. */ @@ -211,7 +227,7 @@ __opendir2(name, flags) /* * This sort must be stable. */ - mergesort(dpv, n, sizeof(*dpv), alphasort); + qsort(dpv, n, sizeof(*dpv), direntcmp); dpv[n] = NULL; xp = NULL; |