xref: /csrg-svn/lib/libc/db/recno/rec_close.c (revision 51087)
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*51087Sbostic static char sccsid[] = "@(#)rec_close.c	5.2 (Berkeley) 09/11/91";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1250995Sbostic #include <sys/param.h>
1350995Sbostic #include <sys/uio.h>
1450995Sbostic #include <errno.h>
1550995Sbostic #include <db.h>
1650995Sbostic #include <unistd.h>
1750995Sbostic #include <stdio.h>
18*51087Sbostic #include "recno.h"
1950995Sbostic 
2050995Sbostic /*
2150995Sbostic  * __REC_CLOSE -- Close a recno tree.
2250995Sbostic  *
2350995Sbostic  * Parameters:
2450995Sbostic  *	dbp:	pointer to access method
2550995Sbostic  *
2650995Sbostic  * Returns:
2750995Sbostic  *	RET_ERROR, RET_SUCCESS
2850995Sbostic  */
2950995Sbostic int
3050995Sbostic __rec_close(dbp)
3150995Sbostic 	DB *dbp;
3250995Sbostic {
3350995Sbostic 	if (__rec_sync(dbp) == RET_ERROR)
3450995Sbostic 		return (RET_ERROR);
3550995Sbostic 	return (__bt_close(dbp));
3650995Sbostic }
3750995Sbostic 
3850995Sbostic /*
3950995Sbostic  * __REC_SYNC -- sync the recno tree to disk.
4050995Sbostic  *
4150995Sbostic  * Parameters:
4250995Sbostic  *	dbp:	pointer to access method
4350995Sbostic  *
4450995Sbostic  * Returns:
4550995Sbostic  *	RET_SUCCESS, RET_ERROR.
4650995Sbostic  *
4750995Sbostic  * XXX
4850995Sbostic  * Currently don't handle a key marked for deletion when the tree is synced.
4950995Sbostic  * Should copy the page and write it out instead of the real page.
5050995Sbostic  */
5150995Sbostic int
5250995Sbostic __rec_sync(dbp)
5350995Sbostic 	const DB *dbp;
5450995Sbostic {
5550995Sbostic 	struct iovec iov[2];
5650995Sbostic 	BTREE *t;
5750995Sbostic 	DBT data, key;
58*51087Sbostic 	off_t off;
5950995Sbostic 	recno_t scursor;
6050995Sbostic 	int status;
6150995Sbostic 
6250995Sbostic 	t = dbp->internal;
6350995Sbostic 
6450995Sbostic 	if (ISSET(t, BTF_INMEM) || NOTSET(t, BTF_MODIFIED))
6550995Sbostic 		return (RET_SUCCESS);
6650995Sbostic 
6750995Sbostic 	if (ISSET(t, BTF_RDONLY)) {
6850995Sbostic 		errno = EPERM;
6950995Sbostic 		return (RET_ERROR);
7050995Sbostic 	}
7150995Sbostic 
7250995Sbostic 	/* Suck any remaining records into the tree. */
7350995Sbostic 	if (t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
7450995Sbostic 		return (RET_ERROR);
7550995Sbostic 
7650995Sbostic 	/* Rewind the file descriptor. */
7750995Sbostic 	if (lseek(t->bt_rfd, 0L, SEEK_SET) != 0L)
7850995Sbostic 		return (RET_ERROR);
7950995Sbostic 
8050995Sbostic 	iov[1].iov_base = "\n";
8150995Sbostic 	iov[1].iov_len = 1;
8250995Sbostic 	scursor = t->bt_rcursor;
8350995Sbostic 
8450995Sbostic 	status = (dbp->seq)(dbp, &key, &data, R_FIRST);
8550995Sbostic         while (status == RET_SUCCESS) {
8650995Sbostic 		iov[0].iov_base = data.data;
8750995Sbostic 		iov[0].iov_len = data.size;
8850995Sbostic 		if (writev(t->bt_rfd, iov, 2) != data.size + 1)
8950995Sbostic 			return (RET_ERROR);
9050995Sbostic                 status = (dbp->seq)(dbp, &key, &data, R_NEXT);
9150995Sbostic         }
9250995Sbostic 	t->bt_rcursor = scursor;
93*51087Sbostic 	if (status == RET_ERROR)
94*51087Sbostic 		return (RET_ERROR);
95*51087Sbostic 	if ((off = lseek(t->bt_rfd, 0L, SEEK_CUR)) == -1)
96*51087Sbostic 		return (RET_ERROR);
97*51087Sbostic 	if (ftruncate(t->bt_rfd, off))
98*51087Sbostic 		return (RET_ERROR);
99*51087Sbostic 	UNSET(t, BTF_MODIFIED);
100*51087Sbostic 	return (RET_SUCCESS);
10150995Sbostic }
102