diff --git a/src/lib/libc/stdlib/icdb.c b/src/lib/libc/stdlib/icdb.c index e135bf02..2ddd9db4 100644 --- a/src/lib/libc/stdlib/icdb.c +++ b/src/lib/libc/stdlib/icdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icdb.c,v 1.7 2016/09/04 14:51:39 nicm Exp $ */ +/* $OpenBSD: icdb.c,v 1.8 2016/09/04 16:56:02 nicm Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -14,14 +14,16 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include #include +#include +#include #include #include -#include #include #include #include -#include #include #include @@ -120,10 +122,10 @@ icdb_new(uint32_t version, uint32_t nentries, uint32_t entrysize, struct icdbinfo *info; int i; - if (entrysize == 0 || entrysize > 1048576) - return NULL; - if (nkeys > 8) + if (entrysize == 0 || entrysize > 1048576 || nkeys > 8) { + errno = EINVAL; return NULL; + } if (!(db = calloc(1, sizeof(*db)))) return NULL; @@ -156,7 +158,7 @@ icdb_open(const char *name, int flags, uint32_t version) struct stat sb; uint8_t *ptr = MAP_FAILED; uint32_t baseoff, indexsize, idxmask, idxlen; - int fd, i; + int fd, i, saved_errno; if ((fd = open(name, flags | O_CLOEXEC)) == -1) return NULL; @@ -169,10 +171,10 @@ icdb_open(const char *name, int flags, uint32_t version) if (ptr == MAP_FAILED) goto fail; info = (struct icdbinfo *)ptr; - if (info->magic != magic) - goto fail; - if (info->version != version) + if (info->magic != magic || info->version != version) { + errno = ENOENT; goto fail; + } if (!(db = calloc(1, sizeof(*db)))) goto fail; @@ -191,11 +193,13 @@ icdb_open(const char *name, int flags, uint32_t version) return db; fail: + saved_errno = errno; if (ptr != MAP_FAILED) munmap(ptr, sb.st_size); if (fd != -1) close(fd); free(db); + errno = saved_errno; return NULL; } DEF_WEAK(icdb_open); @@ -211,14 +215,15 @@ icdb_get(struct icdb *db, void *entry, uint32_t idx) DEF_WEAK(icdb_get); int -icdb_lookup(struct icdb *db, int keynum, const void *key, void *entry, uint32_t *idxp) +icdb_lookup(struct icdb *db, int keynum, const void *key, void *entry, + uint32_t *idxp) { struct icdbinfo *info = db->info; uint32_t offset; uint64_t hash; uint32_t indexsize, idxmask, idxlen; uint32_t *idxdata; - + indexsize = info->indexsize; idxmask = indexsize - 1; idxlen = indexsize * sizeof(uint32_t); @@ -227,8 +232,10 @@ icdb_lookup(struct icdb *db, int keynum, const void *key, void *entry, uint32_t hash = SipHash24(&info->siphashkey, key, info->keysize[keynum]); while ((offset = idxdata[hash & idxmask]) != -1) { - if (icdb_get(db, entry, offset) != 0) + if (icdb_get(db, entry, offset) != 0) { + errno = ENOENT; return -1; + } if (memcmp((uint8_t *)entry + info->keyoffset[keynum], key, info->keysize[keynum]) == 0) { if (idxp) @@ -262,16 +269,17 @@ icdb_update(struct icdb *db, const void *entry, int offset) uint32_t entrysize = info->entrysize; uint32_t baseoff; uint32_t indexsize, idxmask, idxlen; - + indexsize = info->indexsize; idxmask = indexsize - 1; idxlen = indexsize * sizeof(uint32_t); baseoff = sizeof(*info) + idxlen * info->nkeys; - memcpy((uint8_t *)db->entries + offset * entrysize, - entry, entrysize); - if (db->fd != -1) - msync(db->entries + offset * entrysize, entrysize, MS_SYNC); + memcpy((uint8_t *)db->entries + offset * entrysize, entry, entrysize); + if (db->fd != -1) { + msync((uint8_t *)db->entries + offset * entrysize, entrysize, + MS_SYNC); + } return 0; } DEF_WEAK(icdb_update); @@ -304,7 +312,7 @@ icdb_rehash(struct icdb *db) uint32_t entrysize = info->entrysize; uint32_t indexsize, idxmask, idxlen; int i, j; - + indexsize = info->indexsize = roundup(info->nentries); idxmask = indexsize - 1; idxlen = sizeof(uint32_t) * indexsize; @@ -341,10 +349,10 @@ icdb_save(struct icdb *db, int fd) uint32_t entrysize = info->entrysize; uint32_t indexsize, idxlen; int i; - + if (icdb_rehash(db) != 0) return -1; - + indexsize = info->indexsize; idxlen = sizeof(uint32_t) * indexsize;