xref: /csrg-svn/lib/libc/db/recno/rec_close.c (revision 50995)
1*50995Sbostic /*-
2*50995Sbostic  * Copyright (c) 1990 The Regents of the University of California.
3*50995Sbostic  * All rights reserved.
4*50995Sbostic  *
5*50995Sbostic  * %sccs.include.redist.c%
6*50995Sbostic  */
7*50995Sbostic 
8*50995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*50995Sbostic static char sccsid[] = "@(#)rec_close.c	5.1 (Berkeley) 09/04/91";
10*50995Sbostic #endif /* LIBC_SCCS and not lint */
11*50995Sbostic 
12*50995Sbostic #include <sys/param.h>
13*50995Sbostic #include <sys/uio.h>
14*50995Sbostic #include <errno.h>
15*50995Sbostic #include <db.h>
16*50995Sbostic #include <unistd.h>
17*50995Sbostic #include <stdio.h>
18*50995Sbostic #include "../btree/btree.h"
19*50995Sbostic 
20*50995Sbostic /*
21*50995Sbostic  * __REC_CLOSE -- Close a recno tree.
22*50995Sbostic  *
23*50995Sbostic  * Parameters:
24*50995Sbostic  *	dbp:	pointer to access method
25*50995Sbostic  *
26*50995Sbostic  * Returns:
27*50995Sbostic  *	RET_ERROR, RET_SUCCESS
28*50995Sbostic  */
29*50995Sbostic int
30*50995Sbostic __rec_close(dbp)
31*50995Sbostic 	DB *dbp;
32*50995Sbostic {
33*50995Sbostic 	if (__rec_sync(dbp) == RET_ERROR)
34*50995Sbostic 		return (RET_ERROR);
35*50995Sbostic 	return (__bt_close(dbp));
36*50995Sbostic }
37*50995Sbostic 
38*50995Sbostic /*
39*50995Sbostic  * __REC_SYNC -- sync the recno tree to disk.
40*50995Sbostic  *
41*50995Sbostic  * Parameters:
42*50995Sbostic  *	dbp:	pointer to access method
43*50995Sbostic  *
44*50995Sbostic  * Returns:
45*50995Sbostic  *	RET_SUCCESS, RET_ERROR.
46*50995Sbostic  *
47*50995Sbostic  * XXX
48*50995Sbostic  * Currently don't handle a key marked for deletion when the tree is synced.
49*50995Sbostic  * Should copy the page and write it out instead of the real page.
50*50995Sbostic  */
51*50995Sbostic int
52*50995Sbostic __rec_sync(dbp)
53*50995Sbostic 	const DB *dbp;
54*50995Sbostic {
55*50995Sbostic 	struct iovec iov[2];
56*50995Sbostic 	BTREE *t;
57*50995Sbostic 	DBT data, key;
58*50995Sbostic 	recno_t scursor;
59*50995Sbostic 	int status;
60*50995Sbostic 
61*50995Sbostic 	t = dbp->internal;
62*50995Sbostic 
63*50995Sbostic 	if (ISSET(t, BTF_INMEM) || NOTSET(t, BTF_MODIFIED))
64*50995Sbostic 		return (RET_SUCCESS);
65*50995Sbostic 
66*50995Sbostic 	if (ISSET(t, BTF_RDONLY)) {
67*50995Sbostic 		errno = EPERM;
68*50995Sbostic 		return (RET_ERROR);
69*50995Sbostic 	}
70*50995Sbostic 
71*50995Sbostic 	/* Suck any remaining records into the tree. */
72*50995Sbostic 	if (t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
73*50995Sbostic 		return (RET_ERROR);
74*50995Sbostic 
75*50995Sbostic 	/* Rewind the file descriptor. */
76*50995Sbostic 	if (lseek(t->bt_rfd, 0L, SEEK_SET) != 0L)
77*50995Sbostic 		return (RET_ERROR);
78*50995Sbostic 
79*50995Sbostic 	iov[1].iov_base = "\n";
80*50995Sbostic 	iov[1].iov_len = 1;
81*50995Sbostic 	scursor = t->bt_rcursor;
82*50995Sbostic 
83*50995Sbostic 	status = (dbp->seq)(dbp, &key, &data, R_FIRST);
84*50995Sbostic         while (status == RET_SUCCESS) {
85*50995Sbostic 		iov[0].iov_base = data.data;
86*50995Sbostic 		iov[0].iov_len = data.size;
87*50995Sbostic 		if (writev(t->bt_rfd, iov, 2) != data.size + 1)
88*50995Sbostic 			return (RET_ERROR);
89*50995Sbostic                 status = (dbp->seq)(dbp, &key, &data, R_NEXT);
90*50995Sbostic         }
91*50995Sbostic 	t->bt_rcursor = scursor;
92*50995Sbostic 	if (status != RET_ERROR) {
93*50995Sbostic 		UNSET(t, BTF_MODIFIED);
94*50995Sbostic 		return (RET_SUCCESS);
95*50995Sbostic 	}
96*50995Sbostic 	return (RET_ERROR);
97*50995Sbostic }
98