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