summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/lsearch.c45
1 files changed, 13 insertions, 32 deletions
diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c
index 93e200e1bd..95ebf49b81 100644
--- a/src/lib/libc/stdlib/lsearch.c
+++ b/src/lib/libc/stdlib/lsearch.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: lsearch.c,v 1.6 2021/12/07 04:01:45 cheloha Exp $ */ 1/* $OpenBSD: lsearch.c,v 1.7 2021/12/08 22:06:28 cheloha Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
@@ -37,53 +37,34 @@
37#include <search.h> 37#include <search.h>
38 38
39typedef int (*cmp_fn_t)(const void *, const void *); 39typedef int (*cmp_fn_t)(const void *, const void *);
40static void *linear_base(const void *, const void *, size_t *, size_t,
41 cmp_fn_t, int);
42 40
43void * 41void *
44lsearch(const void *key, void *base, size_t *nelp, size_t width, 42lsearch(const void *key, void *base, size_t *nelp, size_t width,
45 cmp_fn_t compar) 43 cmp_fn_t compar)
46{ 44{
45 void *element = lfind(key, base, nelp, width, compar);
47 46
48 return(linear_base(key, base, nelp, width, compar, 1)); 47 /*
48 * Use memmove(3) to ensure the key is copied cleanly into the
49 * array, even if the key overlaps with the end of the array.
50 */
51 if (element == NULL) {
52 element = memmove((char *)base + *nelp * width, key, width);
53 *nelp += 1;
54 }
55 return element;
49} 56}
50 57
51void * 58void *
52lfind(const void *key, const void *base, size_t *nelp, size_t width, 59lfind(const void *key, const void *base, size_t *nelp, size_t width,
53 cmp_fn_t compar) 60 cmp_fn_t compar)
54{ 61{
55 return(linear_base(key, base, nelp, width, compar, 0));
56}
57
58static void *
59linear_base(const void *key, const void *base, size_t *nelp, size_t width,
60 cmp_fn_t compar, int add_flag)
61{
62 const char *element, *end; 62 const char *element, *end;
63 63
64 end = (const char *)base + *nelp * width; 64 end = (const char *)base + *nelp * width;
65 for (element = base; element < end; element += width) 65 for (element = base; element < end; element += width)
66 if (!compar(key, element)) /* key found */ 66 if (!compar(key, element)) /* key found */
67 return((void *)element); 67 return((void *)element);
68 68 return NULL;
69 if (!add_flag) /* key not found */
70 return(NULL);
71
72 /*
73 * The UNIX System User's Manual, 1986 edition claims that
74 * a NULL pointer is returned by lsearch with errno set
75 * appropriately, if there is not enough room in the table
76 * to add a new item. This can't be done as none of these
77 * routines have any method of determining the size of the
78 * table. This comment isn't in the 1986-87 System V
79 * manual.
80 */
81 ++*nelp;
82
83 /*
84 * Use memmove(3) to ensure the key is copied cleanly into the
85 * array, even if the key overlaps with the end of the array.
86 */
87 memmove((void *)end, key, width);
88 return((void *)end);
89} 69}
70DEF_WEAK(lfind);