#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_close.c,v 1.11 2009/03/28 05:45:29 delphij Exp $");
#include "namespace.h"
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include "un-namespace.h"
#include <db.h>
#include "recno.h"
int
__rec_close(DB *dbp)
{
BTREE *t;
int status;
t = dbp->internal;
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
if (__rec_sync(dbp, 0) == RET_ERROR)
return (RET_ERROR);
status = RET_SUCCESS;
if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
status = RET_ERROR;
if (!F_ISSET(t, R_INMEM)) {
if (F_ISSET(t, R_CLOSEFP)) {
if (fclose(t->bt_rfp))
status = RET_ERROR;
} else {
if (_close(t->bt_rfd))
status = RET_ERROR;
}
}
if (__bt_close(dbp) == RET_ERROR)
status = RET_ERROR;
return (status);
}
int
__rec_sync(const DB *dbp, u_int flags)
{
struct iovec iov[2];
BTREE *t;
DBT data, key;
off_t off;
recno_t scursor, trec;
int status;
t = dbp->internal;
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
if (flags == R_RECNOSYNC)
return (__bt_sync(dbp, 0));
if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
return (RET_SUCCESS);
if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
return (RET_ERROR);
if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
return (RET_ERROR);
scursor = t->bt_cursor.rcursor;
key.size = sizeof(recno_t);
key.data = &trec;
if (F_ISSET(t, R_FIXLEN)) {
status = (dbp->seq)(dbp, &key, &data, R_FIRST);
while (status == RET_SUCCESS) {
if (_write(t->bt_rfd, data.data, data.size) !=
(ssize_t)data.size)
return (RET_ERROR);
status = (dbp->seq)(dbp, &key, &data, R_NEXT);
}
} else {
iov[1].iov_base = &t->bt_bval;
iov[1].iov_len = 1;
status = (dbp->seq)(dbp, &key, &data, R_FIRST);
while (status == RET_SUCCESS) {
iov[0].iov_base = data.data;
iov[0].iov_len = data.size;
if (_writev(t->bt_rfd, iov, 2) != (ssize_t)(data.size + 1))
return (RET_ERROR);
status = (dbp->seq)(dbp, &key, &data, R_NEXT);
}
}
t->bt_cursor.rcursor = scursor;
if (status == RET_ERROR)
return (RET_ERROR);
if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
return (RET_ERROR);
if (ftruncate(t->bt_rfd, off))
return (RET_ERROR);
F_CLR(t, R_MODIFIED);
return (RET_SUCCESS);
}