xref: /original-bsd/lib/libc/db/recno/rec_close.c (revision f737e041)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  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	8.3 (Berkeley) 02/21/94";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/types.h>
13 #include <sys/uio.h>
14 #include <sys/mman.h>
15 
16 #include <errno.h>
17 #include <limits.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 
21 #include <db.h>
22 #include "recno.h"
23 
24 /*
25  * __REC_CLOSE -- Close a recno tree.
26  *
27  * Parameters:
28  *	dbp:	pointer to access method
29  *
30  * Returns:
31  *	RET_ERROR, RET_SUCCESS
32  */
33 int
34 __rec_close(dbp)
35 	DB *dbp;
36 {
37 	BTREE *t;
38 	int status;
39 
40 	t = dbp->internal;
41 
42 	/* Toss any page pinned across calls. */
43 	if (t->bt_pinned != NULL) {
44 		mpool_put(t->bt_mp, t->bt_pinned, 0);
45 		t->bt_pinned = NULL;
46 	}
47 
48 	if (__rec_sync(dbp, 0) == RET_ERROR)
49 		return (RET_ERROR);
50 
51 	/* Committed to closing. */
52 	status = RET_SUCCESS;
53 	if (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
54 		status = RET_ERROR;
55 
56 	if (!ISSET(t, R_INMEM))
57 		if (ISSET(t, R_CLOSEFP)) {
58 			if (fclose(t->bt_rfp))
59 				status = RET_ERROR;
60 		} else
61 			if (close(t->bt_rfd))
62 				status = RET_ERROR;
63 
64 	if (__bt_close(dbp) == RET_ERROR)
65 		status = RET_ERROR;
66 
67 	return (status);
68 }
69 
70 /*
71  * __REC_SYNC -- sync the recno tree to disk.
72  *
73  * Parameters:
74  *	dbp:	pointer to access method
75  *
76  * Returns:
77  *	RET_SUCCESS, RET_ERROR.
78  */
79 int
80 __rec_sync(dbp, flags)
81 	const DB *dbp;
82 	u_int flags;
83 {
84 	struct iovec iov[2];
85 	BTREE *t;
86 	DBT data, key;
87 	off_t off;
88 	recno_t scursor, trec;
89 	int status;
90 
91 	t = dbp->internal;
92 
93 	/* Toss any page pinned across calls. */
94 	if (t->bt_pinned != NULL) {
95 		mpool_put(t->bt_mp, t->bt_pinned, 0);
96 		t->bt_pinned = NULL;
97 	}
98 
99 	if (flags == R_RECNOSYNC)
100 		return (__bt_sync(dbp, 0));
101 
102 	if (ISSET(t, R_RDONLY | R_INMEM) || !ISSET(t, R_MODIFIED))
103 		return (RET_SUCCESS);
104 
105 	/* Read any remaining records into the tree. */
106 	if (!ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
107 		return (RET_ERROR);
108 
109 	/* Rewind the file descriptor. */
110 	if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
111 		return (RET_ERROR);
112 
113 	iov[1].iov_base = "\n";
114 	iov[1].iov_len = 1;
115 	scursor = t->bt_rcursor;
116 
117 	key.size = sizeof(recno_t);
118 	key.data = &trec;
119 
120 	status = (dbp->seq)(dbp, &key, &data, R_FIRST);
121         while (status == RET_SUCCESS) {
122 		iov[0].iov_base = data.data;
123 		iov[0].iov_len = data.size;
124 		if (writev(t->bt_rfd, iov, 2) != data.size + 1)
125 			return (RET_ERROR);
126                 status = (dbp->seq)(dbp, &key, &data, R_NEXT);
127         }
128 	t->bt_rcursor = scursor;
129 	if (status == RET_ERROR)
130 		return (RET_ERROR);
131 	if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
132 		return (RET_ERROR);
133 	if (ftruncate(t->bt_rfd, off))
134 		return (RET_ERROR);
135 	CLR(t, R_MODIFIED);
136 	return (RET_SUCCESS);
137 }
138