xref: /csrg-svn/lib/libc/db/recno/rec_close.c (revision 60056)
150995Sbostic /*-
250995Sbostic  * Copyright (c) 1990 The Regents of the University of California.
350995Sbostic  * All rights reserved.
450995Sbostic  *
550995Sbostic  * %sccs.include.redist.c%
650995Sbostic  */
750995Sbostic 
850995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*60056Sbostic static char sccsid[] = "@(#)rec_close.c	5.11 (Berkeley) 05/16/93";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1257462Sbostic #include <sys/types.h>
1350995Sbostic #include <sys/uio.h>
1458748Sbostic #include <sys/mman.h>
1556754Sbostic 
1650995Sbostic #include <errno.h>
1757462Sbostic #include <limits.h>
1856754Sbostic #include <stdio.h>
1950995Sbostic #include <unistd.h>
2056754Sbostic 
2157933Sbostic #include <db.h>
2251087Sbostic #include "recno.h"
2350995Sbostic 
2450995Sbostic /*
2550995Sbostic  * __REC_CLOSE -- Close a recno tree.
2650995Sbostic  *
2750995Sbostic  * Parameters:
2850995Sbostic  *	dbp:	pointer to access method
2950995Sbostic  *
3050995Sbostic  * Returns:
3150995Sbostic  *	RET_ERROR, RET_SUCCESS
3250995Sbostic  */
3350995Sbostic int
3450995Sbostic __rec_close(dbp)
3550995Sbostic 	DB *dbp;
3650995Sbostic {
3754280Sbostic 	BTREE *t;
3854280Sbostic 	int rval;
3954280Sbostic 
40*60056Sbostic 	if (__rec_sync(dbp, 0) == RET_ERROR)
4150995Sbostic 		return (RET_ERROR);
4254280Sbostic 
4354280Sbostic 	/* Committed to closing. */
4454280Sbostic 	t = dbp->internal;
4554280Sbostic 
4658748Sbostic 	rval = RET_SUCCESS;
47*60056Sbostic 	if (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
4858748Sbostic 		rval = RET_ERROR;
4958748Sbostic 
50*60056Sbostic 	if (!ISSET(t, R_INMEM))
51*60056Sbostic 		if (ISSET(t, R_CLOSEFP)) {
5258812Sbostic 			if (fclose(t->bt_rfp))
5358812Sbostic 				rval = RET_ERROR;
5458812Sbostic 		} else
5558812Sbostic 			if (close(t->bt_rfd))
5658812Sbostic 				rval = RET_ERROR;
5758748Sbostic 
5854280Sbostic 	if (__bt_close(dbp) == RET_ERROR)
5958748Sbostic 		rval = RET_ERROR;
6054280Sbostic 
6158748Sbostic 	return (rval);
6250995Sbostic }
6350995Sbostic 
6450995Sbostic /*
6550995Sbostic  * __REC_SYNC -- sync the recno tree to disk.
6650995Sbostic  *
6750995Sbostic  * Parameters:
6850995Sbostic  *	dbp:	pointer to access method
6950995Sbostic  *
7050995Sbostic  * Returns:
7150995Sbostic  *	RET_SUCCESS, RET_ERROR.
7250995Sbostic  */
7350995Sbostic int
74*60056Sbostic __rec_sync(dbp, flags)
7550995Sbostic 	const DB *dbp;
76*60056Sbostic 	u_int flags;
7750995Sbostic {
7850995Sbostic 	struct iovec iov[2];
7950995Sbostic 	BTREE *t;
8050995Sbostic 	DBT data, key;
8151087Sbostic 	off_t off;
8255312Sbostic 	recno_t scursor, trec;
8350995Sbostic 	int status;
8450995Sbostic 
8550995Sbostic 	t = dbp->internal;
8650995Sbostic 
87*60056Sbostic 	if (flags == R_RECNOSYNC)
88*60056Sbostic 		return (__bt_sync(dbp, 0));
89*60056Sbostic 
90*60056Sbostic 	if (ISSET(t, R_RDONLY | R_INMEM) || !ISSET(t, R_MODIFIED))
9150995Sbostic 		return (RET_SUCCESS);
9250995Sbostic 
9356702Sbostic 	/* Read any remaining records into the tree. */
94*60056Sbostic 	if (!ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
9550995Sbostic 		return (RET_ERROR);
9650995Sbostic 
9750995Sbostic 	/* Rewind the file descriptor. */
9856702Sbostic 	if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
9950995Sbostic 		return (RET_ERROR);
10050995Sbostic 
10150995Sbostic 	iov[1].iov_base = "\n";
10250995Sbostic 	iov[1].iov_len = 1;
10350995Sbostic 	scursor = t->bt_rcursor;
10450995Sbostic 
10555312Sbostic 	key.size = sizeof(recno_t);
10655312Sbostic 	key.data = &trec;
10755312Sbostic 
10850995Sbostic 	status = (dbp->seq)(dbp, &key, &data, R_FIRST);
10950995Sbostic         while (status == RET_SUCCESS) {
11050995Sbostic 		iov[0].iov_base = data.data;
11150995Sbostic 		iov[0].iov_len = data.size;
11250995Sbostic 		if (writev(t->bt_rfd, iov, 2) != data.size + 1)
11350995Sbostic 			return (RET_ERROR);
11450995Sbostic                 status = (dbp->seq)(dbp, &key, &data, R_NEXT);
11550995Sbostic         }
11650995Sbostic 	t->bt_rcursor = scursor;
11751087Sbostic 	if (status == RET_ERROR)
11851087Sbostic 		return (RET_ERROR);
11958748Sbostic 	if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
12051087Sbostic 		return (RET_ERROR);
12151087Sbostic 	if (ftruncate(t->bt_rfd, off))
12251087Sbostic 		return (RET_ERROR);
123*60056Sbostic 	CLR(t, R_MODIFIED);
12451087Sbostic 	return (RET_SUCCESS);
12550995Sbostic }
126