summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-07-08 20:23:15 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-07-08 20:23:15 +0000
commit540d2586b028e26b0a325b13fd1d7266fb55fb3f (patch)
tree72e844e988e7b4d15826810e06f29457aeff5ede /lib/libc
parente178384c643b5cedf2b78ca5bb2a81da886ccec0 (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/libc')
-rw-r--r--lib/libc/gen/opendir.c20
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;