xref: /csrg-svn/lib/libc/db/recno/rec_close.c (revision 56754)
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*56754Sbostic static char sccsid[] = "@(#)rec_close.c	5.6 (Berkeley) 11/13/92";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1250995Sbostic #include <sys/param.h>
1350995Sbostic #include <sys/uio.h>
14*56754Sbostic 
15*56754Sbostic #include <db.h>
1650995Sbostic #include <errno.h>
17*56754Sbostic #include <stdio.h>
1850995Sbostic #include <unistd.h>
19*56754Sbostic 
2051087Sbostic #include "recno.h"
2150995Sbostic 
2250995Sbostic /*
2350995Sbostic  * __REC_CLOSE -- Close a recno tree.
2450995Sbostic  *
2550995Sbostic  * Parameters:
2650995Sbostic  *	dbp:	pointer to access method
2750995Sbostic  *
2850995Sbostic  * Returns:
2950995Sbostic  *	RET_ERROR, RET_SUCCESS
3050995Sbostic  */
3150995Sbostic int
3250995Sbostic __rec_close(dbp)
3350995Sbostic 	DB *dbp;
3450995Sbostic {
3554280Sbostic 	BTREE *t;
3654280Sbostic 	int rval;
3754280Sbostic 
3850995Sbostic 	if (__rec_sync(dbp) == RET_ERROR)
3950995Sbostic 		return (RET_ERROR);
4054280Sbostic 
4154280Sbostic 	/* Committed to closing. */
4254280Sbostic 	t = dbp->internal;
43*56754Sbostic 	rval = ISSET(t, BTF_RINMEM) ? 0 :
44*56754Sbostic 	    t->bt_rfp == NULL ? close(t->bt_rfd) : fclose(t->bt_rfp);
4554280Sbostic 
4654280Sbostic 	if (__bt_close(dbp) == RET_ERROR)
4754280Sbostic 		return (RET_ERROR);
4854280Sbostic 
4954280Sbostic 	return (rval ? RET_ERROR : RET_SUCCESS);
5050995Sbostic }
5150995Sbostic 
5250995Sbostic /*
5350995Sbostic  * __REC_SYNC -- sync the recno tree to disk.
5450995Sbostic  *
5550995Sbostic  * Parameters:
5650995Sbostic  *	dbp:	pointer to access method
5750995Sbostic  *
5850995Sbostic  * Returns:
5950995Sbostic  *	RET_SUCCESS, RET_ERROR.
6050995Sbostic  */
6150995Sbostic int
6250995Sbostic __rec_sync(dbp)
6350995Sbostic 	const DB *dbp;
6450995Sbostic {
6550995Sbostic 	struct iovec iov[2];
6650995Sbostic 	BTREE *t;
6750995Sbostic 	DBT data, key;
6851087Sbostic 	off_t off;
6955312Sbostic 	recno_t scursor, trec;
7050995Sbostic 	int status;
7150995Sbostic 
7250995Sbostic 	t = dbp->internal;
7350995Sbostic 
74*56754Sbostic 	if (ISSET(t, BTF_RDONLY | BTF_RINMEM) || !ISSET(t, BTF_MODIFIED))
7550995Sbostic 		return (RET_SUCCESS);
7650995Sbostic 
7756702Sbostic 	/* Read any remaining records into the tree. */
7850995Sbostic 	if (t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
7950995Sbostic 		return (RET_ERROR);
8050995Sbostic 
8150995Sbostic 	/* Rewind the file descriptor. */
8256702Sbostic 	if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
8350995Sbostic 		return (RET_ERROR);
8450995Sbostic 
8550995Sbostic 	iov[1].iov_base = "\n";
8650995Sbostic 	iov[1].iov_len = 1;
8750995Sbostic 	scursor = t->bt_rcursor;
8850995Sbostic 
8955312Sbostic 	key.size = sizeof(recno_t);
9055312Sbostic 	key.data = &trec;
9155312Sbostic 
9250995Sbostic 	status = (dbp->seq)(dbp, &key, &data, R_FIRST);
9350995Sbostic         while (status == RET_SUCCESS) {
9450995Sbostic 		iov[0].iov_base = data.data;
9550995Sbostic 		iov[0].iov_len = data.size;
9650995Sbostic 		if (writev(t->bt_rfd, iov, 2) != data.size + 1)
9750995Sbostic 			return (RET_ERROR);
9850995Sbostic                 status = (dbp->seq)(dbp, &key, &data, R_NEXT);
9950995Sbostic         }
10050995Sbostic 	t->bt_rcursor = scursor;
10151087Sbostic 	if (status == RET_ERROR)
10251087Sbostic 		return (RET_ERROR);
10356702Sbostic 	if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) != 0)
10451087Sbostic 		return (RET_ERROR);
10551087Sbostic 	if (ftruncate(t->bt_rfd, off))
10651087Sbostic 		return (RET_ERROR);
107*56754Sbostic 	CLR(t, BTF_MODIFIED);
10851087Sbostic 	return (RET_SUCCESS);
10950995Sbostic }
110